summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-11-07 00:31:04 -0400
committerBen Gamari <ben@well-typed.com>2022-03-07 23:27:02 +0000
commit1a0f8042165fde72dbbb474da10eeb72083126d2 (patch)
tree7ba0d7e3b713af379ba29e3150441d0f94b9fa74
parent18513122148d9120ee823096149da949f2c20f0f (diff)
downloadhaskell-1a0f8042165fde72dbbb474da10eeb72083126d2.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`.
-rw-r--r--compiler/cmm/CmmOpt.hs4
1 files changed, 2 insertions, 2 deletions
diff --git a/compiler/cmm/CmmOpt.hs b/compiler/cmm/CmmOpt.hs
index 5b542a390e..d6fdd5a23f 100644
--- a/compiler/cmm/CmmOpt.hs
+++ b/compiler/cmm/CmmOpt.hs
@@ -134,8 +134,8 @@ cmmMachOpFoldM dflags 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)