summaryrefslogtreecommitdiff
path: root/compiler/prelude/PrelRules.lhs
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2010-02-11 13:15:43 +0000
committerSimon Marlow <marlowsd@gmail.com>2010-02-11 13:15:43 +0000
commitca10c79f28cfc0c29d02d0f2c0ea111093bd2b37 (patch)
treee53454cdecb90216243b33fb9b17bc9093b754c0 /compiler/prelude/PrelRules.lhs
parentd259dd70d7f5b1981b522b5a9317fbf22840450b (diff)
downloadhaskell-ca10c79f28cfc0c29d02d0f2c0ea111093bd2b37.tar.gz
don't constant fold division that would result in negative zero (#3676)
Diffstat (limited to 'compiler/prelude/PrelRules.lhs')
-rw-r--r--compiler/prelude/PrelRules.lhs12
1 files changed, 10 insertions, 2 deletions
diff --git a/compiler/prelude/PrelRules.lhs b/compiler/prelude/PrelRules.lhs
index bc8c9b81bc..4ca4462e50 100644
--- a/compiler/prelude/PrelRules.lhs
+++ b/compiler/prelude/PrelRules.lhs
@@ -293,7 +293,9 @@ floatOp2 _ _ _ = Nothing
floatOp2Z :: (Rational -> Rational -> Rational) -> Literal -> Literal
-> Maybe (Expr CoreBndr)
floatOp2Z op (MachFloat f1) (MachFloat f2)
- | f2 /= 0 = Just (mkFloatVal (f1 `op` f2))
+ | (f1 /= 0 || f2 > 0) -- see Note [negative zero]
+ && f2 /= 0 -- avoid NaN and Infinity/-Infinity
+ = Just (mkFloatVal (f1 `op` f2))
floatOp2Z _ _ _ = Nothing
--------------------------
@@ -306,7 +308,13 @@ doubleOp2 _ _ _ = Nothing
doubleOp2Z :: (Rational -> Rational -> Rational) -> Literal -> Literal
-> Maybe (Expr CoreBndr)
doubleOp2Z op (MachDouble f1) (MachDouble f2)
- | f2 /= 0 = Just (mkDoubleVal (f1 `op` f2))
+ | (f1 /= 0 || f2 > 0) -- see Note [negative zero]
+ && f2 /= 0 -- avoid NaN and Infinity/-Infinity
+ = Just (mkDoubleVal (f1 `op` f2))
+ -- Note [negative zero] Avoid (0 / -d), otherwise 0/(-1) reduces to
+ -- zero, but we might want to preserve the negative zero here which
+ -- is representable in Float/Double but not in (normalised)
+ -- Rational. (#3676) Perhaps we should generate (0 :% (-1)) instead?
doubleOp2Z _ _ _ = Nothing