summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-11-09 10:44:07 -0500
committerBen Gamari <ben@smart-cactus.org>2022-03-02 22:49:17 -0500
commit4a34401c017cdf8d1a2bb15aaf7527c24feb5212 (patch)
tree4d43b9c1ef109cc951766f07bcf379129b503039
parent96faf9546faf634e6108633bd2f03b13e21f1e34 (diff)
downloadhaskell-4a34401c017cdf8d1a2bb15aaf7527c24feb5212.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. (cherry picked from commit 9c65197e0aec9a4ee11e377dac52f459ac64067a)
-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 dc81a2c7aa..6979f786a0 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
@@ -141,9 +151,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