summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-11-07 00:31:04 -0400
committerBen Gamari <ben@smart-cactus.org>2022-03-02 09:00:44 -0500
commit4ddc62e55fa1eddaa98d54df54b3be1b1759a1e7 (patch)
tree8237bf179b250ac6b5b6d0cb9097642d0e164ee1
parent7896cd36e4036648aa59c2b942eea4653466350b (diff)
downloadhaskell-4ddc62e55fa1eddaa98d54df54b3be1b1759a1e7.tar.gz
cmm: narrow when folding signed quotients
Previously the constant-folding behavior for MO_S_Quot and MO_S_Rem failed to narrow its arguments, meaning that a program like: %zx64(%quot(%lobits8(0x00e1::bits16), 3::bits8)) would be miscompiled. Specifically, this program should reduce as %lobits8(0x00e1::bits16) == -31 %quot(%lobits8(0x00e1::bits16), 3::bits8) == -10 %zx64(%quot(%lobits8(0x00e1::bits16), 3::bits8)) == 246 However, with this bug the `%lobits8(0x00e1::bits16)` would instead be treated as `+31`, resulting in the incorrect result of `75`. (cherry picked from commit 94e197e3dbb9a48991eb90a03b51ea13d39ba4cc) (cherry picked from commit 5b950a7f939a35538abf61ea8e86ddd07cc75237)
-rw-r--r--compiler/GHC/Cmm/Opt.hs4
1 files changed, 2 insertions, 2 deletions
diff --git a/compiler/GHC/Cmm/Opt.hs b/compiler/GHC/Cmm/Opt.hs
index 6a2945c4f8..dc81a2c7aa 100644
--- a/compiler/GHC/Cmm/Opt.hs
+++ b/compiler/GHC/Cmm/Opt.hs
@@ -134,8 +134,8 @@ cmmMachOpFoldM platform mop [CmmLit (CmmInt x xrep), CmmLit (CmmInt y _)]
MO_Mul r -> Just $! CmmLit (CmmInt (x * y) r)
MO_U_Quot r | y /= 0 -> Just $! CmmLit (CmmInt (x_u `quot` y_u) r)
MO_U_Rem r | y /= 0 -> Just $! CmmLit (CmmInt (x_u `rem` y_u) r)
- MO_S_Quot r | y /= 0 -> Just $! CmmLit (CmmInt (x `quot` y) r)
- MO_S_Rem r | y /= 0 -> Just $! CmmLit (CmmInt (x `rem` y) r)
+ MO_S_Quot r | y /= 0 -> Just $! CmmLit (CmmInt (x_s `quot` y_s) r)
+ MO_S_Rem r | y /= 0 -> Just $! CmmLit (CmmInt (x_s `rem` y_s) r)
MO_And r -> Just $! CmmLit (CmmInt (x .&. y) r)
MO_Or r -> Just $! CmmLit (CmmInt (x .|. y) r)