Sylvain Henry pushed to branch wip/andreask/cfg-fix at Glasgow Haskell Compiler / GHC Commits: b0a084a0 by Andreas Klebinger at 2026-11-03T13:37:18+01:00 x86 ncg: Track the current block in NatM to keep the CFG in sync The x86 NCG maintains a CFG that is used for code layout. Whenever instruction selection introduces new basic blocks (for instance for word-to-float conversions, cmpxchg based atomic operations, ctz on i386 or 64-bit shifts on i386) it must update this CFG, and the code that follows must use the new block as its origin. Before this patch the current block was threaded explicitly through some statement-level functions only. Block-introducing primops that were dispatched as "simple" (word2Float#, #27915) and the 64-bit shifts in iselExpr64 did not update the CFG at all. This resulted in an out-of-sync CFG, bad code layout and the "Can't find weight for edge that should have one" panic once the register allocator inserted fixup blocks (#27694, #27915). We now keep the current block in the NatM state and provide a few combinators (continueInNewBlock, addCondBlock, addDiamondFlow, addColdSelfLoop, increaseEdgeWeight) that update the CFG and the current block at the same time. See Note [Updating the CFG during CodeGen] in GHC.CmmToAsm.Monad. The cfg sanity check (-dasm-lint) now also checks that the branches in the generated code and the edges in the CFG match both ways (call edges excepted), which catches this class of bug early. It immediately found another desync: when the register allocator needs more stack than preallocated, allocMoreStack moves the body of every entry block into a new block and retargets the local jumps to it, but the CFG only recorded the new block as the immediate successor of the entry block. The new addPreentryBlock also redirects the jump edges (and keeps the call edges, since returns still go through the entry block). The x86 code generator now keeps the CFG in sync on i386 too, so backendMaintainsCfg is enabled for it: i386 gets CFG based code layout, dead code elimination and the -dasm-lint check. Fixes #27694, #27915 Co-authored-by: Sylvain Henry <sylvain@haskus.fr> Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> - - - - - 14 changed files: - + changelog.d/27694 - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - + testsuite/tests/codeGen/should_compile/T27694.hs - testsuite/tests/codeGen/should_compile/all.T - + testsuite/tests/codeGen/should_run/T27915.hs - + testsuite/tests/codeGen/should_run/T27915.stdout-ws-32 - + testsuite/tests/codeGen/should_run/T27915.stdout-ws-64 - testsuite/tests/codeGen/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0a084a0cdcff6d41d03215596b7054b... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b0a084a0cdcff6d41d03215596b7054b... You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help