Commit 86836a2e authored by Simon Marlow's avatar Simon Marlow
Browse files

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
parent 876b00ba
...@@ -2603,7 +2603,8 @@ genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock ...@@ -2603,7 +2603,8 @@ genSwitch :: DynFlags -> CmmExpr -> SwitchTargets -> NatM InstrBlock
genSwitch dflags expr targets genSwitch dflags expr targets
| gopt Opt_PIC dflags | gopt Opt_PIC dflags
= do = 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 lbl <- getNewLabelNat
dflags <- getDynFlags dflags <- getDynFlags
let is32bit = target32Bit (targetPlatform dflags) let is32bit = target32Bit (targetPlatform dflags)
...@@ -2624,6 +2625,7 @@ genSwitch dflags expr targets ...@@ -2624,6 +2625,7 @@ genSwitch dflags expr targets
let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) let op = OpAddr (AddrBaseIndex (EABaseReg tableReg)
(EAIndex reg (wORD_SIZE dflags)) (ImmInt 0)) (EAIndex reg (wORD_SIZE dflags)) (ImmInt 0))
offsetReg <- getNewRegNat (intFormat (wordWidth dflags))
return $ if is32bit || os == OSDarwin return $ if is32bit || os == OSDarwin
then e_code `appOL` t_code `appOL` toOL [ then e_code `appOL` t_code `appOL` toOL [
ADD (intFormat (wordWidth dflags)) op (OpReg tableReg), ADD (intFormat (wordWidth dflags)) op (OpReg tableReg),
...@@ -2636,8 +2638,9 @@ genSwitch dflags expr targets ...@@ -2636,8 +2638,9 @@ genSwitch dflags expr targets
-- hack should be removed in conjunction with the hack in -- hack should be removed in conjunction with the hack in
-- PprMach.hs/pprDataItem once binutils 2.17 is standard. -- PprMach.hs/pprDataItem once binutils 2.17 is standard.
e_code `appOL` t_code `appOL` toOL [ e_code `appOL` t_code `appOL` toOL [
MOVSxL II32 op (OpReg reg), MOVSxL II32 op (OpReg offsetReg),
ADD (intFormat (wordWidth dflags)) (OpReg reg) ADD (intFormat (wordWidth dflags))
(OpReg offsetReg)
(OpReg tableReg), (OpReg tableReg),
JMP_TBL (OpReg tableReg) ids rosection lbl JMP_TBL (OpReg tableReg) ids rosection lbl
] ]
......
...@@ -143,4 +143,4 @@ test('T10870', when(wordsize(32), skip), compile_and_run, ['']) ...@@ -143,4 +143,4 @@ test('T10870', when(wordsize(32), skip), compile_and_run, [''])
test('PopCnt', omit_ways(['ghci']), multi_compile_and_run, test('PopCnt', omit_ways(['ghci']), multi_compile_and_run,
['PopCnt', [('PopCnt_cmm.cmm', '')], '']) ['PopCnt', [('PopCnt_cmm.cmm', '')], ''])
test('T12059', normal, compile_and_run, ['']) test('T12059', normal, compile_and_run, [''])
test('T12433', expect_broken(12433), compile_and_run, ['']) test('T12433', normal, compile_and_run, [''])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment