diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2022-10-14 09:29:23 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2022-10-17 09:13:55 -0400 |
commit | 04874fedae8074b252abbd70fea68bf3dd0a605b (patch) | |
tree | 6563185f47c4c65c0054693f051119ba399149b5 | |
parent | fca529517484bf19098ca9efa77e95534086abdc (diff) | |
download | gcc-04874fedae8074b252abbd70fea68bf3dd0a605b.zip gcc-04874fedae8074b252abbd70fea68bf3dd0a605b.tar.gz gcc-04874fedae8074b252abbd70fea68bf3dd0a605b.tar.bz2 |
Fix nan updating in range-ops.
Calling clean_nan on an undefined type traps, set_varying first. Other
tweaks for correctness.
* range-op-float.cc (foperator_not_equal::op1_range): Check for
VREL_EQ after singleton.
(foperator_unordered::op1_range): Set VARYING before calling
clear_nan().
(foperator_ordered::op1_range): Set rather than clear NAN if both
operands are the same.
-rw-r--r-- | gcc/range-op-float.cc | 23 |
1 files changed, 10 insertions, 13 deletions
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 23e0f5e..6cf2180 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -510,12 +510,9 @@ foperator_not_equal::op1_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - // The TRUE side of op1 != op1 implies op1 is NAN. - if (rel == VREL_EQ) - r.set_nan (type); // If the result is true, the only time we know anything is if // OP2 is a constant. - else if (op2.singleton_p ()) + if (op2.singleton_p ()) { // This is correct even if op1 is NAN, because the following // range would be ~[tmp, tmp] with the NAN property set to @@ -523,6 +520,9 @@ foperator_not_equal::op1_range (frange &r, tree type, REAL_VALUE_TYPE tmp = op2.lower_bound (); r.set (type, tmp, tmp, VR_ANTI_RANGE); } + // The TRUE side of op1 != op1 implies op1 is NAN. + else if (rel == VREL_EQ) + r.set_nan (type); else r.set_varying (type); break; @@ -1045,22 +1045,18 @@ foperator_unordered::op1_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (rel == VREL_EQ) - r.set_nan (type); // Since at least one operand must be NAN, if one of them is // not, the other must be. - else if (!op2.maybe_isnan ()) + if (rel == VREL_EQ || !op2.maybe_isnan ()) r.set_nan (type); else r.set_varying (type); break; case BRS_FALSE: - if (rel == VREL_EQ) - r.clear_nan (); // A false UNORDERED means both operands are !NAN, so it's // impossible for op2 to be a NAN. - else if (op2.known_isnan ()) + if (op2.known_isnan ()) r.set_undefined (); else { @@ -1132,10 +1128,11 @@ foperator_ordered::op1_range (frange &r, tree type, break; case BRS_FALSE: - r.set_varying (type); - // The FALSE side of op1 ORDERED op1 implies op1 is !NAN. + // The FALSE side of op1 ORDERED op1 implies op1 is NAN. if (rel == VREL_EQ) - r.clear_nan (); + r.set_nan (type); + else + r.set_varying (type); break; default: |