summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2021-04-30 11:28:21 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-04-30 23:23:26 -0400
commite61d2d47c4942c829ec98016be5aa5ae36982524 (patch)
tree956c9760157e117d723d65a72dba3f4a20ac699f
parent460afbe676715e4b8d75af79e9700ceebcf62eed (diff)
downloadhaskell-e61d2d47c4942c829ec98016be5aa5ae36982524.tar.gz
Make sized division primops ok-for-spec (#19026)
-rw-r--r--compiler/GHC/Builtin/PrimOps.hs46
-rw-r--r--compiler/GHC/Core/Utils.hs15
2 files changed, 47 insertions, 14 deletions
diff --git a/compiler/GHC/Builtin/PrimOps.hs b/compiler/GHC/Builtin/PrimOps.hs
index 58d0c9e76b..2f89ba448b 100644
--- a/compiler/GHC/Builtin/PrimOps.hs
+++ b/compiler/GHC/Builtin/PrimOps.hs
@@ -17,6 +17,7 @@ module GHC.Builtin.PrimOps (
primOpOutOfLine, primOpCodeSize,
primOpOkForSpeculation, primOpOkForSideEffects,
primOpIsCheap, primOpFixity, primOpDocs,
+ primOpIsDiv,
getPrimOpResultInfo, isComparisonPrimOp, PrimOpResultInfo(..),
@@ -525,6 +526,51 @@ primOpIsCheap op = primOpOkForSpeculation op
-- that (it's exprIsDupable that does) so the problem doesn't occur
-- even if primOpIsCheap sometimes says 'True'.
+
+-- | True of dyadic operators that can fail only if the second arg is zero!
+--
+-- This function probably belongs in an automagically generated file.. but it's
+-- such a special case I thought I'd leave it here for now.
+primOpIsDiv :: PrimOp -> Bool
+primOpIsDiv op = case op of
+
+ -- TODO: quotRemWord2, Int64, Word64
+ IntQuotOp -> True
+ Int8QuotOp -> True
+ Int16QuotOp -> True
+ Int32QuotOp -> True
+
+ IntRemOp -> True
+ Int8RemOp -> True
+ Int16RemOp -> True
+ Int32RemOp -> True
+
+ IntQuotRemOp -> True
+ Int8QuotRemOp -> True
+ Int16QuotRemOp -> True
+ Int32QuotRemOp -> True
+
+ WordQuotOp -> True
+ Word8QuotOp -> True
+ Word16QuotOp -> True
+ Word32QuotOp -> True
+
+ WordRemOp -> True
+ Word8RemOp -> True
+ Word16RemOp -> True
+ Word32RemOp -> True
+
+ WordQuotRemOp -> True
+ Word8QuotRemOp -> True
+ Word16QuotRemOp -> True
+ Word32QuotRemOp -> True
+
+ FloatDivOp -> True
+ DoubleDivOp -> True
+ _ -> False
+
+
+
{-
************************************************************************
* *
diff --git a/compiler/GHC/Core/Utils.hs b/compiler/GHC/Core/Utils.hs
index cee7d4f68b..01b35f4b1f 100644
--- a/compiler/GHC/Core/Utils.hs
+++ b/compiler/GHC/Core/Utils.hs
@@ -1633,7 +1633,7 @@ app_ok primop_ok fun args
-- to take the arguments into account
PrimOpId op
- | isDivOp op
+ | primOpIsDiv op
, [arg1, Lit lit] <- args
-> not (isZeroLit lit) && expr_ok primop_ok arg1
-- Special case for dividing operations that fail
@@ -1686,19 +1686,6 @@ altsAreExhaustive (Alt con1 _ _ : alts)
-- we behave conservatively here -- I don't think it's important
-- enough to deserve special treatment
--- | True of dyadic operators that can fail only if the second arg is zero!
-isDivOp :: PrimOp -> Bool
--- This function probably belongs in GHC.Builtin.PrimOps, or even in
--- an automagically generated file.. but it's such a
--- special case I thought I'd leave it here for now.
-isDivOp IntQuotOp = True
-isDivOp IntRemOp = True
-isDivOp WordQuotOp = True
-isDivOp WordRemOp = True
-isDivOp FloatDivOp = True
-isDivOp DoubleDivOp = True
-isDivOp _ = False
-
{- Note [exprOkForSpeculation: case expressions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
exprOkForSpeculation accepts very special case expressions.