diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-08-05 10:33:22 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-08-05 22:00:29 -0400 |
commit | 037bc9c94a7977d0382b9d510b4ba6c08f87fbfb (patch) | |
tree | 053d88ef3267a7d513e4d5db6fc98d8c263ff12c | |
parent | 78d232f5ca7f02b8f743e6982e710a4bfb309c4f (diff) | |
download | haskell-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.hs | 5 |
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 |