summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-08-05 10:33:22 -0400
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-08-05 22:00:29 -0400
commit037bc9c94a7977d0382b9d510b4ba6c08f87fbfb (patch)
tree053d88ef3267a7d513e4d5db6fc98d8c263ff12c
parent78d232f5ca7f02b8f743e6982e710a4bfb309c4f (diff)
downloadhaskell-037bc9c94a7977d0382b9d510b4ba6c08f87fbfb.tar.gz
codeGen/X86: Don't clobber switch variable in switch generation
Previously ce8745952f99174ad9d3bdc7697fd086b47cdfb5 assumed that it was safe to clobber the switch variable when generating code for a jump table since we were at the end of a block. However, this assumption is wrong; the register could be live in the jump target. Fixes #21968.
-rw-r--r--compiler/GHC/CmmToAsm/X86/CodeGen.hs5
1 files changed, 3 insertions, 2 deletions
diff --git a/compiler/GHC/CmmToAsm/X86/CodeGen.hs b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
index 3d2a83c984..de0a7c56e3 100644
--- a/compiler/GHC/CmmToAsm/X86/CodeGen.hs
+++ b/compiler/GHC/CmmToAsm/X86/CodeGen.hs
@@ -2922,11 +2922,12 @@ genSwitch expr targets = do
else do
-- See Note [%rip-relative addressing on x86-64].
tableReg <- getNewRegNat (intFormat (platformWordWidth platform))
+ targetReg <- getNewRegNat (intFormat (platformWordWidth platform))
let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) (EAIndex reg (platformWordSizeInBytes platform)) (ImmInt 0))
code = e_code `appOL` toOL
[ LEA (archWordFormat is32bit) (OpAddr (AddrBaseIndex EABaseRip EAIndexNone (ImmCLbl lbl))) (OpReg tableReg)
- , MOV (archWordFormat is32bit) op (OpReg reg)
- , JMP_TBL (OpReg reg) ids (Section ReadOnlyData lbl) lbl
+ , MOV (archWordFormat is32bit) op (OpReg targetReg)
+ , JMP_TBL (OpReg targetReg) ids (Section ReadOnlyData lbl) lbl
]
return code
where