diff options
author | Ben Gamari <ben@smart-cactus.org> | 2021-11-07 00:31:04 -0400 |
---|---|---|
committer | Ben Gamari <ben@well-typed.com> | 2022-03-07 23:27:02 +0000 |
commit | 1a0f8042165fde72dbbb474da10eeb72083126d2 (patch) | |
tree | 7ba0d7e3b713af379ba29e3150441d0f94b9fa74 | |
parent | 18513122148d9120ee823096149da949f2c20f0f (diff) | |
download | haskell-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.hs | 4 |
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) |