diff options
author | Ben Gamari <ben@smart-cactus.org> | 2021-11-07 00:31:04 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-12-02 18:13:30 -0500 |
commit | 5b950a7f939a35538abf61ea8e86ddd07cc75237 (patch) | |
tree | b4f4a471e72cd129aac3a19d7f1793670d25cb7a | |
parent | 1724ac37633b2796e2410296e8a34bc8e1fa4934 (diff) | |
download | haskell-5b950a7f939a35538abf61ea8e86ddd07cc75237.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)
-rw-r--r-- | compiler/GHC/Cmm/Opt.hs | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/compiler/GHC/Cmm/Opt.hs b/compiler/GHC/Cmm/Opt.hs index 676c1270b5..e9615c3a15 100644 --- a/compiler/GHC/Cmm/Opt.hs +++ b/compiler/GHC/Cmm/Opt.hs @@ -130,8 +130,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) |