From 04874fedae8074b252abbd70fea68bf3dd0a605b Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Fri, 14 Oct 2022 09:29:23 -0400 Subject: [PATCH 2/4] 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. --- gcc/range-op-float.cc | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 23e0f5ef4e2..6cf2180ce59 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: -- 2.37.3