aboutsummaryrefslogtreecommitdiff
path: root/gcc/range-op-float.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/range-op-float.cc')
-rw-r--r--gcc/range-op-float.cc40
1 files changed, 35 insertions, 5 deletions
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 74ac465..2db83ae 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -607,6 +607,10 @@ foperator_equal::fold_range (irange &r, tree type,
{
if (op1 == op2)
r = range_true (type);
+ // If one operand is -0.0 and other 0.0, they are still equal.
+ else if (real_iszero (&op1.lower_bound ())
+ && real_iszero (&op2.lower_bound ()))
+ r = range_true (type);
else
r = range_false (type);
}
@@ -617,7 +621,18 @@ foperator_equal::fold_range (irange &r, tree type,
frange tmp = op1;
tmp.intersect (op2);
if (tmp.undefined_p ())
- r = range_false (type);
+ {
+ // If one range is [whatever, -0.0] and another
+ // [0.0, whatever2], we don't know anything either,
+ // because -0.0 == 0.0.
+ if ((real_iszero (&op1.upper_bound ())
+ && real_iszero (&op2.lower_bound ()))
+ || (real_iszero (&op1.lower_bound ())
+ && real_iszero (&op2.upper_bound ())))
+ r = range_true_and_false (type);
+ else
+ r = range_false (type);
+ }
else
r = range_true_and_false (type);
}
@@ -708,10 +723,14 @@ foperator_not_equal::fold_range (irange &r, tree type,
// consist of a single value, and then compare them.
else if (op1.singleton_p () && op2.singleton_p ())
{
- if (op1 != op2)
- r = range_true (type);
- else
+ if (op1 == op2)
r = range_false (type);
+ // If one operand is -0.0 and other 0.0, they are still equal.
+ else if (real_iszero (&op1.lower_bound ())
+ && real_iszero (&op2.lower_bound ()))
+ r = range_false (type);
+ else
+ r = range_true (type);
}
else if (!maybe_isnan (op1, op2))
{
@@ -720,7 +739,18 @@ foperator_not_equal::fold_range (irange &r, tree type,
frange tmp = op1;
tmp.intersect (op2);
if (tmp.undefined_p ())
- r = range_true (type);
+ {
+ // If one range is [whatever, -0.0] and another
+ // [0.0, whatever2], we don't know anything either,
+ // because -0.0 == 0.0.
+ if ((real_iszero (&op1.upper_bound ())
+ && real_iszero (&op2.lower_bound ()))
+ || (real_iszero (&op1.lower_bound ())
+ && real_iszero (&op2.upper_bound ())))
+ r = range_true_and_false (type);
+ else
+ r = range_true (type);
+ }
else
r = range_true_and_false (type);
}