summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-08-12 11:33:46 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-08-16 09:02:02 -0400
commitcd6f5bfd0cc2bcf74de1d9edb43fe4b338b4c4e3 (patch)
tree4379fc2246dd5a94119cca50349e9a72c7616649
parentffc9116e6223c0a90a51c05ff4b471b7f5af1b55 (diff)
downloadhaskell-cd6f5bfd0cc2bcf74de1d9edb43fe4b338b4c4e3.tar.gz
CmmToLlvm: Don't aliasify builtin LLVM variables
Our aliasification logic would previously turn builtin LLVM variables into aliases, which apparently confuses LLVM. This manifested in initializers failing to be emitted, resulting in many profiling failures with the LLVM backend. Fixes #22019.
-rw-r--r--compiler/GHC/CmmToLlvm/Base.hs20
1 files changed, 16 insertions, 4 deletions
diff --git a/compiler/GHC/CmmToLlvm/Base.hs b/compiler/GHC/CmmToLlvm/Base.hs
index 33592092de..390ba4c55a 100644
--- a/compiler/GHC/CmmToLlvm/Base.hs
+++ b/compiler/GHC/CmmToLlvm/Base.hs
@@ -58,7 +58,7 @@ import GHC.Utils.Logger
import Data.Maybe (fromJust)
import Control.Monad (ap)
-import Data.List (sortBy, groupBy)
+import Data.List (sortBy, groupBy, isPrefixOf)
import Data.Ord (comparing)
-- ----------------------------------------------------------------------------
@@ -504,6 +504,12 @@ generateExternDecls = do
modifyEnv $ \env -> env { envAliases = emptyUniqSet }
return (concat defss, [])
+-- | Is a variable one of the special @$llvm@ globals?
+isBuiltinLlvmVar :: LlvmVar -> Bool
+isBuiltinLlvmVar (LMGlobalVar lbl _ _ _ _ _) =
+ "$llvm" `isPrefixOf` unpackFS lbl
+isBuiltinLlvmVar _ = False
+
-- | Here we take a global variable definition, rename it with a
-- @$def@ suffix, and generate the appropriate alias.
aliasify :: LMGlobal -> LlvmM [LMGlobal]
@@ -511,8 +517,9 @@ aliasify :: LMGlobal -> LlvmM [LMGlobal]
-- Here we obtain the indirectee's precise type and introduce
-- fresh aliases to both the precise typed label (lbl$def) and the i8*
-- typed (regular) label of it with the matching new names.
-aliasify (LMGlobal (LMGlobalVar lbl ty@LMAlias{} link sect align Alias)
- (Just orig)) = do
+aliasify (LMGlobal var@(LMGlobalVar lbl ty@LMAlias{} link sect align Alias)
+ (Just orig))
+ | not $ isBuiltinLlvmVar var = do
let defLbl = llvmDefLabel lbl
LMStaticPointer (LMGlobalVar origLbl _ oLnk Nothing Nothing Alias) = orig
defOrigLbl = llvmDefLabel origLbl
@@ -525,7 +532,8 @@ aliasify (LMGlobal (LMGlobalVar lbl ty@LMAlias{} link sect align Alias)
pure [ LMGlobal (LMGlobalVar defLbl ty link sect align Alias) (Just defOrig)
, LMGlobal (LMGlobalVar lbl i8Ptr link sect align Alias) (Just orig')
]
-aliasify (LMGlobal var val) = do
+aliasify (LMGlobal var val)
+ | not $ isBuiltinLlvmVar var = do
let LMGlobalVar lbl ty link sect align const = var
defLbl = llvmDefLabel lbl
@@ -543,6 +551,7 @@ aliasify (LMGlobal var val) = do
return [ LMGlobal defVar val
, LMGlobal aliasVar (Just aliasVal)
]
+aliasify global = pure [global]
-- Note [Llvm Forward References]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -601,3 +610,6 @@ aliasify (LMGlobal var val) = do
-- away with casting the alias to the desired type in @getSymbolPtr@
-- and instead just emit a reference to the definition symbol directly.
-- This is the @Just@ case in @getSymbolPtr@.
+--
+-- Note that we must take care not to turn LLVM's builtin variables into
+-- aliases (e.g. $llvm.global_ctors) since this confuses LLVM.