summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-08-05 10:33:22 -0400
committerBen Gamari <ben@smart-cactus.org>2022-08-05 10:37:53 -0400
commitb4342e32823bb0bfc8e83b53055647d64e0431ab (patch)
treea5f074e050e777b8642171176fa2feb554442925
parent1d94a59fbadd56efec78680c89946eb425eef418 (diff)
downloadhaskell-wip/T12433.tar.gz
codeGen/X86: Don't clobber switch variable in switch generationwip/T12433
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