diff options
author | John Ericson <John.Ericson@Obsidian.Systems> | 2021-06-10 23:14:35 +0000 |
---|---|---|
committer | John Ericson <John.Ericson@Obsidian.Systems> | 2021-07-21 22:51:41 +0000 |
commit | e8f7734d8a052f99b03e1123466dc9f47b48c311 (patch) | |
tree | fda662d428a825c69d24b204a9777d4f70235acd /compiler/GHC/CmmToAsm/SPARC | |
parent | 10124b16538091806953d732e24ca485a0664895 (diff) | |
download | haskell-e8f7734d8a052f99b03e1123466dc9f47b48c311.tar.gz |
Fix #19931
The issue was the renderer for x86 addressing modes assumes native size
registers, but we were passing in a possibly-smaller index in
conjunction with a native-sized base pointer.
The easist thing to do is just extend the register first.
I also changed the other NGC backends implementing jump tables
accordingly. On one hand, I think PowerPC and Sparc don't have the small
sub-registers anyways so there is less to worry about. On the other
hand, to the extent that's true the zero extension can become a no-op.
I should give credit where it's due: @hsyl20 really did all the work for
me in
https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4717#note_355874,
but I was daft and missed the "Oops" and so ended up spending a silly
amount of time putting it all back together myself.
The unregisterised backend change is a bit different, because here we
are translating the actual case not a jump table, and the fix is to
handle right-sized literals not addressing modes. But it makes sense to
include here too because it's the same change in the subsequent commit
that exposes both bugs.
Diffstat (limited to 'compiler/GHC/CmmToAsm/SPARC')
-rw-r--r-- | compiler/GHC/CmmToAsm/SPARC/CodeGen.hs | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs b/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs index 56f764560c..aeaaf1c9d3 100644 --- a/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/SPARC/CodeGen.hs @@ -313,7 +313,7 @@ genSwitch config expr targets = error "MachCodeGen: sparc genSwitch PIC not finished\n" | otherwise - = do (e_reg, e_code) <- getSomeReg (cmmOffset (ncgPlatform config) expr offset) + = do (e_reg, e_code) <- getSomeReg indexExpr base_reg <- getNewRegNat II32 offset_reg <- getNewRegNat II32 @@ -334,7 +334,15 @@ genSwitch config expr targets , LD II32 (AddrRegReg base_reg offset_reg) dst , JMP_TBL (AddrRegImm dst (ImmInt 0)) ids label , NOP ] - where (offset, ids) = switchTargetsToTable targets + where + indexExpr = cmmOffset platform exprWidened offset + -- We widen to a native-width register to santize the high bits + exprWidened = CmmMachOp + (MO_UU_Conv (cmmExprWidth platform expr) + (platformWordWidth platform)) + [expr] + (offset, ids) = switchTargetsToTable targets + platform = ncgPlatform config generateJumpTableForInstr :: Platform -> Instr -> Maybe (NatCmmDecl RawCmmStatics Instr) |