diff options
author | Simon Marlow <marlowsd@gmail.com> | 2016-09-15 10:11:34 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2016-09-15 13:23:36 +0100 |
commit | 86836a2ecc089b917866a2cb65b716fd5f04cc56 (patch) | |
tree | d4afa1e6e7b35046a9cc8b08cf563089541f683c /compiler | |
parent | 876b00ba25a615423f48b0cf9d443a9fd5dbd6f4 (diff) | |
download | haskell-86836a2ecc089b917866a2cb65b716fd5f04cc56.tar.gz |
Fix codegen bug in PIC version of genSwitch (#12433)
Summary:
* getNonClobberedReg instead of getSomeReg, because the reg needs to
survive across t_code
* Use a new reg for the table offset calculation instead of clobbering
the reg returned by expr (this was the bug affecting #12433)
Test Plan: New unit test; validate
Reviewers: rwbarton, bgamari, austin, erikd
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2529
GHC Trac Issues: #12433
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index cd45d92418..4401f38236 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -2603,7 +2603,8 @@ genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock genSwitch dflags expr targets | gopt Opt_PIC dflags = do - (reg,e_code) <- getSomeReg (cmmOffset dflags expr offset) + (reg,e_code) <- getNonClobberedReg (cmmOffset dflags expr offset) + -- getNonClobberedReg because it needs to survive across t_code lbl <- getNewLabelNat dflags <- getDynFlags let is32bit = target32Bit (targetPlatform dflags) @@ -2624,6 +2625,7 @@ genSwitch dflags expr targets let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) (EAIndex reg (wORD_SIZE dflags)) (ImmInt 0)) + offsetReg <- getNewRegNat (intFormat (wordWidth dflags)) return $ if is32bit || os == OSDarwin then e_code `appOL` t_code `appOL` toOL [ ADD (intFormat (wordWidth dflags)) op (OpReg tableReg), @@ -2636,8 +2638,9 @@ genSwitch dflags expr targets -- hack should be removed in conjunction with the hack in -- PprMach.hs/pprDataItem once binutils 2.17 is standard. e_code `appOL` t_code `appOL` toOL [ - MOVSxL II32 op (OpReg reg), - ADD (intFormat (wordWidth dflags)) (OpReg reg) + MOVSxL II32 op (OpReg offsetReg), + ADD (intFormat (wordWidth dflags)) + (OpReg offsetReg) (OpReg tableReg), JMP_TBL (OpReg tableReg) ids rosection lbl ] |