frange: Fix up foperator_{,not_}equal::fold_range for signed zeros [PR108540]
authorJakub Jelinek <jakub@redhat.com>
Thu, 26 Jan 2023 16:21:22 +0000 (17:21 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 26 Jan 2023 16:28:17 +0000 (17:28 +0100)
commit09176201ec6a21c25b1edb07f19f83be22a123f9
tree5095ca59b6ff2a1cf939627442f91a3bdd0cee36
parent0cdb609f43eb6131053fb88e32fdc5490f4ef293
frange: Fix up foperator_{,not_}equal::fold_range for signed zeros [PR108540]

The following testcases are miscompiled, because threader sees some
SSA_NAME would have -0.0 value and when computing range of SSA_NAME == 0.0
foperator_equal::fold_range sees one operand has [-0.0, -0.0] singleton
range, the other [0.0, 0.0], they aren't equal (frange operator== uses
real_identical etc. rather than real comparisons) and so it thinks they
compare unequal.  With signed zeros -0.0 == 0.0 is true though, so we
need to special case the both ranges singleton code.
Similarly, if we see op1 range being say [-42.0, -0.0] and op2 range
[0.0, 42.0], we'd check that the intersection of the two ranges is empty
(that is correct) and fold the result of == between such operands to
[0, 0] which is wrong, because -0.0 == 0.0, it needs to be [0, 1].
Similarly for foperator_not_equal::fold_range.

2023-01-26  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/108540
* range-op-float.cc (foperator_equal::fold_range): If both op1 and op2
are singletons, use range_true even if op1 != op2
when one range is [-0.0, -0.0] and another [0.0, 0.0].  Similarly,
even if intersection of the ranges is empty and one has
zero low bound and another zero high bound, use range_true_and_false
rather than range_false.
(foperator_not_equal::fold_range): If both op1 and op2
are singletons, use range_false even if op1 != op2
when one range is [-0.0, -0.0] and another [0.0, 0.0].  Similarly,
even if intersection of the ranges is empty and one has
zero low bound and another zero high bound, use range_true_and_false
rather than range_true.

* gcc.c-torture/execute/ieee/pr108540-1.c: New test.
* gcc.c-torture/execute/ieee/pr108540-2.c: New test.
gcc/range-op-float.cc
gcc/testsuite/gcc.c-torture/execute/ieee/pr108540-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/ieee/pr108540-2.c [new file with mode: 0644]