[COMMITTED] Fix nan updating in range-ops.

Message ID 03ebe7bc-13bf-a37f-7f8d-d2146e2df918@redhat.com
State Repeat Merge
Headers
Series [COMMITTED] Fix nan updating in range-ops. |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Andrew MacLeod Oct. 17, 2022, 1:25 p.m. UTC
  There is a path in which clear_nan() is called on an UNDEFINED range, 
which is not allowed.  This patch simply makes sure VARYING is set 
before calling clear_nan().

In operator_not_equal, we should check if op1 == op1 AFTER the check for 
a singleton.

operator_ordered was also cealring the NAN on the false side, and should 
be setting it.

None of these paths were being executed to this point as GORI was not 
passing in the relation between op1 and op2, but the next patch changes 
that and would trigger these issues.

Bootstrapped on x86_64-pc-linux-gnu with no regressions.  Pushed.

Andrew
  

Patch

From 04874fedae8074b252abbd70fea68bf3dd0a605b Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
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