diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2020-11-02 14:42:07 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-11-03 17:42:26 -0500 |
commit | 37f0434d65fa0891a961504c8882893fad7609c6 (patch) | |
tree | fed6238e9b47fac3869b4443a362b0e217e468a9 /compiler/GHC/Core.hs | |
parent | 3486ebe6f960cc55d52c1e645ee15fdeb277d0ab (diff) | |
download | haskell-37f0434d65fa0891a961504c8882893fad7609c6.tar.gz |
Constant-folding: don't pass through GHC's Int/Word (fix #11704)
Constant-folding rules for integerToWord/integerToInt were performing
the following coercions at compilation time:
integerToWord: target's Integer -> ghc's Word -> target's Word
integerToInt : target's Integer -> ghc's Int -> target's Int
1) It was wrong for cross-compilers when GHC's word size is smaller than
the target one. This patch avoids passing through GHC's word-sized
types:
integerToWord: target's Integer -> ghc's Integer -> target's Word
integerToInt : target's Integer -> ghc's Integer -> target's Int
2) Additionally we didn't wrap the target word/int literal to make it
fit into the target's range! This broke the invariant of literals
only containing values in range.
The existing code is wrong only with a 64-bit cross-compiling GHC,
targeting a 32-bit platform, and performing constant folding on a
literal that doesn't fit in a 32-bit word. If GHC was built with
DEBUG, the assertion in GHC.Types.Literal.mkLitWord would fail.
Otherwise the bad transformation would go unnoticed.
Diffstat (limited to 'compiler/GHC/Core.hs')
-rw-r--r-- | compiler/GHC/Core.hs | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/compiler/GHC/Core.hs b/compiler/GHC/Core.hs index a6c1c282ab..57976e836a 100644 --- a/compiler/GHC/Core.hs +++ b/compiler/GHC/Core.hs @@ -27,8 +27,8 @@ module GHC.Core ( mkLet, mkLets, mkLetNonRec, mkLetRec, mkLams, mkApps, mkTyApps, mkCoApps, mkVarApps, mkTyArg, - mkIntLit, mkIntLitInt, - mkWordLit, mkWordLitWord, + mkIntLit, mkIntLitWrap, + mkWordLit, mkWordLitWrap, mkWord64LitWord64, mkInt64LitInt64, mkCharLit, mkStringLit, mkFloatLit, mkFloatLitFloat, @@ -1977,23 +1977,25 @@ mkTyArg ty -- | Create a machine integer literal expression of type @Int#@ from an @Integer@. -- If you want an expression of type @Int@ use 'GHC.Core.Make.mkIntExpr' -mkIntLit :: Platform -> Integer -> Expr b --- | Create a machine integer literal expression of type @Int#@ from an @Int@. --- If you want an expression of type @Int@ use 'GHC.Core.Make.mkIntExpr' -mkIntLitInt :: Platform -> Int -> Expr b +mkIntLit :: Platform -> Integer -> Expr b +mkIntLit platform n = Lit (mkLitInt platform n) -mkIntLit platform n = Lit (mkLitInt platform n) -mkIntLitInt platform n = Lit (mkLitInt platform (toInteger n)) +-- | Create a machine integer literal expression of type @Int#@ from an +-- @Integer@, wrapping if necessary. +-- If you want an expression of type @Int@ use 'GHC.Core.Make.mkIntExpr' +mkIntLitWrap :: Platform -> Integer -> Expr b +mkIntLitWrap platform n = Lit (mkLitIntWrap platform n) -- | Create a machine word literal expression of type @Word#@ from an @Integer@. -- If you want an expression of type @Word@ use 'GHC.Core.Make.mkWordExpr' -mkWordLit :: Platform -> Integer -> Expr b --- | Create a machine word literal expression of type @Word#@ from a @Word@. --- If you want an expression of type @Word@ use 'GHC.Core.Make.mkWordExpr' -mkWordLitWord :: Platform -> Word -> Expr b +mkWordLit :: Platform -> Integer -> Expr b +mkWordLit platform w = Lit (mkLitWord platform w) -mkWordLit platform w = Lit (mkLitWord platform w) -mkWordLitWord platform w = Lit (mkLitWord platform (toInteger w)) +-- | Create a machine word literal expression of type @Word#@ from an +-- @Integer@, wrapping if necessary. +-- If you want an expression of type @Word@ use 'GHC.Core.Make.mkWordExpr' +mkWordLitWrap :: Platform -> Integer -> Expr b +mkWordLitWrap platform w = Lit (mkLitWordWrap platform w) mkWord64LitWord64 :: Word64 -> Expr b mkWord64LitWord64 w = Lit (mkLitWord64 (toInteger w)) |