summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-11-09 10:44:07 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-12-02 18:13:30 -0500
commit9c65197e0aec9a4ee11e377dac52f459ac64067a (patch)
tree2fe7456cb0264192cff507e2e3382db1523b9374
parent7094f4faeb78a3ffda98c44700b4addba3f5b951 (diff)
downloadhaskell-9c65197e0aec9a4ee11e377dac52f459ac64067a.tar.gz
cmm/opt: Fold away shifts larger than shiftee width
This is necessary for lint-correctness since we no longer allow such shifts in Cmm.
-rw-r--r--compiler/GHC/Cmm/Opt.hs14
1 files changed, 12 insertions, 2 deletions
diff --git a/compiler/GHC/Cmm/Opt.hs b/compiler/GHC/Cmm/Opt.hs
index e9615c3a15..131267e352 100644
--- a/compiler/GHC/Cmm/Opt.hs
+++ b/compiler/GHC/Cmm/Opt.hs
@@ -72,6 +72,16 @@ cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)]
_ -> panic $ "cmmMachOpFoldM: unknown unary op: " ++ show op
+-- Eliminate shifts that are wider than the shiftee
+cmmMachOpFoldM _ op [_shiftee, CmmLit (CmmInt shift _)]
+ | Just width <- isShift op
+ , shift >= fromIntegral (widthInBits width)
+ = Just $! CmmLit (CmmInt 0 width)
+ where
+ isShift (MO_Shl w) = Just w
+ isShift (MO_U_Shr w) = Just w
+ isShift (MO_S_Shr w) = Just w
+ isShift _ = Nothing
-- Eliminate conversion NOPs
cmmMachOpFoldM _ (MO_SS_Conv rep1 rep2) [x] | rep1 == rep2 = Just x
@@ -137,9 +147,9 @@ cmmMachOpFoldM platform mop [CmmLit (CmmInt x xrep), CmmLit (CmmInt y _)]
MO_Or r -> Just $! CmmLit (CmmInt (x .|. y) r)
MO_Xor r -> Just $! CmmLit (CmmInt (x `xor` y) r)
- MO_Shl r -> Just $! CmmLit (CmmInt (x `shiftL` fromIntegral y) r)
+ MO_Shl r -> Just $! CmmLit (CmmInt (x `shiftL` fromIntegral y) r)
MO_U_Shr r -> Just $! CmmLit (CmmInt (x_u `shiftR` fromIntegral y) r)
- MO_S_Shr r -> Just $! CmmLit (CmmInt (x `shiftR` fromIntegral y) r)
+ MO_S_Shr r -> Just $! CmmLit (CmmInt (x `shiftR` fromIntegral y) r)
_ -> Nothing