[Git][ghc/ghc][master] Cmm: don't perform unsound optimizations on 32-bit compiler hosts
Marge Bot (@marge-bot)
gitlab at gitlab.haskell.org
Wed Aug 7 15:51:16 UTC 2024
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
7446a09a by Sylvain Henry at 2024-08-07T11:50:35-04:00
Cmm: don't perform unsound optimizations on 32-bit compiler hosts
- beef61351b240967b49169d27a9a19565cf3c4af enabled the use of
MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends
- 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG
backend
However we store some literal values as `Int` in the compiler. As a
result, some Cmm optimizations transformed target 64-bit literals into
compiler `Int`. If the compiler is 32-bit, this leads to computing with
wrong literals (see #24893 and #24700).
This patch disables these Cmm optimizations for 32-bit compilers. This
is unsatisfying (optimizations shouldn't be compiler-word-size
dependent) but it fixes the bug and it makes the patch easy to backport.
A proper fix would be much more invasive but it shall be implemented in
the future.
Co-authored-by: amesgen <amesgen at amesgen.de>
- - - - -
7 changed files:
- compiler/GHC/Cmm/Opt.hs
- + testsuite/tests/codeGen/should_run/T24700.hs
- + testsuite/tests/codeGen/should_run/T24700.stdin
- + testsuite/tests/codeGen/should_run/T24700.stdout
- + testsuite/tests/codeGen/should_run/T24893.hs
- + testsuite/tests/codeGen/should_run/T24893.stdout
- testsuite/tests/codeGen/should_run/all.T
Changes:
=====================================
compiler/GHC/Cmm/Opt.hs
=====================================
@@ -237,23 +237,33 @@ cmmMachOpFoldM _ MO_Add{} [ CmmMachOp op at MO_Add{} [pic, CmmLit lit]
= Just $! CmmMachOp op [pic, CmmLit $ cmmOffsetLit lit off ]
where off = fromIntegral (narrowS rep n)
--- Make a RegOff if we can
+-- Make a RegOff if we can. We don't perform this optimization if rep is greater
+-- than the host word size because we use an Int to store the offset. See
+-- #24893 and #24700. This should be fixed to ensure that optimizations don't
+-- depend on the compiler host platform.
cmmMachOpFoldM _ (MO_Add _) [CmmReg reg, CmmLit (CmmInt n rep)]
+ | validOffsetRep rep
= Just $! cmmRegOff reg (fromIntegral (narrowS rep n))
cmmMachOpFoldM _ (MO_Add _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
+ | validOffsetRep rep
= Just $! cmmRegOff reg (off + fromIntegral (narrowS rep n))
cmmMachOpFoldM _ (MO_Sub _) [CmmReg reg, CmmLit (CmmInt n rep)]
+ | validOffsetRep rep
= Just $! cmmRegOff reg (- fromIntegral (narrowS rep n))
cmmMachOpFoldM _ (MO_Sub _) [CmmRegOff reg off, CmmLit (CmmInt n rep)]
+ | validOffsetRep rep
= Just $! cmmRegOff reg (off - fromIntegral (narrowS rep n))
-- Fold label(+/-)offset into a CmmLit where possible
cmmMachOpFoldM _ (MO_Add _) [CmmLit lit, CmmLit (CmmInt i rep)]
+ | validOffsetRep rep
= Just $! CmmLit (cmmOffsetLit lit (fromIntegral (narrowU rep i)))
cmmMachOpFoldM _ (MO_Add _) [CmmLit (CmmInt i rep), CmmLit lit]
+ | validOffsetRep rep
= Just $! CmmLit (cmmOffsetLit lit (fromIntegral (narrowU rep i)))
cmmMachOpFoldM _ (MO_Sub _) [CmmLit lit, CmmLit (CmmInt i rep)]
+ | validOffsetRep rep
= Just $! CmmLit (cmmOffsetLit lit (fromIntegral (negate (narrowU rep i))))
@@ -409,6 +419,13 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n _))]
cmmMachOpFoldM _ _ _ = Nothing
+-- | Check that a literal width is compatible with the host word size used to
+-- store offsets. This should be fixed properly (using larger types to store
+-- literal offsets). See #24893
+validOffsetRep :: Width -> Bool
+validOffsetRep rep = widthInBits rep <= finiteBitSize (undefined :: Int)
+
+
{- Note [Comparison operators]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we have
=====================================
testsuite/tests/codeGen/should_run/T24700.hs
=====================================
@@ -0,0 +1,5 @@
+import Data.Int
+
+main = do
+ input <- getLine
+ print (read input - 3000000000 :: Int64)
=====================================
testsuite/tests/codeGen/should_run/T24700.stdin
=====================================
@@ -0,0 +1 @@
+0
=====================================
testsuite/tests/codeGen/should_run/T24700.stdout
=====================================
@@ -0,0 +1 @@
+-3000000000
=====================================
testsuite/tests/codeGen/should_run/T24893.hs
=====================================
@@ -0,0 +1,8 @@
+import Data.Word
+
+main :: IO ()
+main = print $ 0x8000000000000000 + zero
+
+zero :: Word64
+zero = 0
+{-# NOINLINE zero #-}
=====================================
testsuite/tests/codeGen/should_run/T24893.stdout
=====================================
@@ -0,0 +1 @@
+9223372036854775808
=====================================
testsuite/tests/codeGen/should_run/all.T
=====================================
@@ -248,3 +248,5 @@ test('T24664a', normal, compile_and_run, ['-O'])
test('T24664b', normal, compile_and_run, ['-O'])
test('CtzClz0', normal, compile_and_run, [''])
test('T23034', req_c, compile_and_run, ['-O2 T23034_c.c'])
+test('T24700', normal, compile_and_run, ['-O'])
+test('T24893', normal, compile_and_run, ['-O'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7446a09a2d5b04b95cd43c03659b5647853124ce
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7446a09a2d5b04b95cd43c03659b5647853124ce
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240807/d645ee07/attachment-0001.html>
More information about the ghc-commits
mailing list