Commit b426de37 authored by Ben Gamari's avatar Ben Gamari 🐢 Committed by Marge Bot

llvmGen: Ensure that entry labels don't have predecessors

The LLVM IR forbids the entry label of a procedure from having any
predecessors. In the case of a simple looping function the LLVM code
generator broke this invariant, as noted in #17589. Fix this by
moving the function prologue to its own basic block, as suggested by
@kavon in #11649.

Fixes #11649 and #17589.
parent f14bb50b
...@@ -66,20 +66,24 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" ...@@ -66,20 +66,24 @@ genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!"
-- | Generate code for a list of blocks that make up a complete -- | Generate code for a list of blocks that make up a complete
-- procedure. The first block in the list is expected to be the entry -- procedure. The first block in the list is expected to be the entry
-- point and will get the prologue. -- point.
basicBlocksCodeGen :: LiveGlobalRegs -> [CmmBlock] basicBlocksCodeGen :: LiveGlobalRegs -> [CmmBlock]
-> LlvmM ([LlvmBasicBlock], [LlvmCmmDecl]) -> LlvmM ([LlvmBasicBlock], [LlvmCmmDecl])
basicBlocksCodeGen _ [] = panic "no entry block!" basicBlocksCodeGen _ [] = panic "no entry block!"
basicBlocksCodeGen live (entryBlock:cmmBlocks) basicBlocksCodeGen live cmmBlocks
= do (prologue, prologueTops) <- funPrologue live (entryBlock:cmmBlocks) = do -- Emit the prologue
-- N.B. this must be its own block to ensure that the entry block of the
-- procedure has no predecessors, as required by the LLVM IR. See #17589
-- and #11649.
bid <- newBlockId
(prologue, prologueTops) <- funPrologue live cmmBlocks
let entryBlock = BasicBlock bid (fromOL prologue)
-- Generate code -- Generate code
(BasicBlock bid entry, entryTops) <- basicBlockCodeGen entryBlock
(blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks (blocks, topss) <- fmap unzip $ mapM basicBlockCodeGen cmmBlocks
-- Compose -- Compose
let entryBlock = BasicBlock bid (fromOL prologue ++ entry) return (entryBlock : blocks, prologueTops ++ concat topss)
return (entryBlock : blocks, prologueTops ++ entryTops ++ concat topss)
-- | Generate code for one block -- | Generate code for one block
...@@ -1834,7 +1838,10 @@ funPrologue live cmmBlocks = do ...@@ -1834,7 +1838,10 @@ funPrologue live cmmBlocks = do
markStackReg r markStackReg r
return $ toOL [alloc, Store rval reg] return $ toOL [alloc, Store rval reg]
return (concatOL stmtss, []) return (concatOL stmtss `snocOL` jumpToEntry, [])
where
entryBlk : _ = cmmBlocks
jumpToEntry = Branch $ blockIdToLlvm (entryLabel entryBlk)
-- | Function epilogue. Load STG variables to use as argument for call. -- | Function epilogue. Load STG variables to use as argument for call.
-- STG Liveness optimisation done here. -- STG Liveness optimisation done here.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment