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
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
]
......
......@@ -143,4 +143,4 @@ test('T10870', when(wordsize(32), skip), compile_and_run, [''])
test('PopCnt', omit_ways(['ghci']), multi_compile_and_run,
['PopCnt', [('PopCnt_cmm.cmm', '')], ''])
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