[commit: ghc] ghc-8.0: Fix codegen bug in PIC version of genSwitch (#12433) (a0472f8)

git at git.haskell.org git at git.haskell.org
Thu Sep 15 17:50:42 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-8.0
Link       : http://ghc.haskell.org/trac/ghc/changeset/a0472f8dd29037412c61cbd42537863ad18b74f0/ghc

>---------------------------------------------------------------

commit a0472f8dd29037412c61cbd42537863ad18b74f0
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Thu Sep 15 10:11:34 2016 +0100

    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


>---------------------------------------------------------------

a0472f8dd29037412c61cbd42537863ad18b74f0
 compiler/nativeGen/X86/CodeGen.hs        | 9 ++++++---
 testsuite/tests/codeGen/should_run/all.T | 2 +-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index cd45d92..4401f38 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
                        ]
diff --git a/testsuite/tests/codeGen/should_run/all.T b/testsuite/tests/codeGen/should_run/all.T
index 36babf2..15ad68b 100644
--- a/testsuite/tests/codeGen/should_run/all.T
+++ b/testsuite/tests/codeGen/should_run/all.T
@@ -143,4 +143,4 @@ test('T10521b', normal, compile_and_run, [''])
 test('T10870', when(wordsize(32), skip), compile_and_run, [''])
 test('PopCnt', omit_ways(['ghci']), multi_compile_and_run,
                  ['PopCnt', [('PopCnt_cmm.cmm', '')], ''])
-test('T12433', expect_broken(12433), compile_and_run, [''])
+test('T12433', normal, compile_and_run, [''])



More information about the ghc-commits mailing list