public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Andrew MacLeod <amacleod@redhat.com>
To: Jakub Jelinek <jakub@redhat.com>, Aldy Hernandez <aldyh@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [RFC PATCH] range-op-float: Fix up op1_op2_relation of comparisons
Date: Tue, 11 Apr 2023 16:58:19 -0400	[thread overview]
Message-ID: <7ad17002-8df2-c268-03f5-902ed57f3a97@redhat.com> (raw)
In-Reply-To: <ZDUYpbs+dY6ly8a1@tucnak>

[-- Attachment #1: Type: text/plain, Size: 2281 bytes --]


On 4/11/23 04:21, Jakub Jelinek wrote:
> Hi!
>
> This patch was what I've tried first before the currently committed
> PR109386 fix.  Still, I think it is the right thing until we have proper
> full set of VREL_* relations for NANs (though it would be really nice
> if op1_op2_relation could be passed either type of the comparison
> operands, or even better ranges of the two operands, such that
> we could choose if inversion of say VREL_LT is VREL_GE (if !MODE_HONOR_NANS
> (TYPE_MODE (type))) or rhs1/rhs2 ranges are guaranteed not to include
> NANs (!known_isnan && !maybe_isnan for both), or VREL_UNGE, etc.
> Anyway, the current state is that for the LE/LT/GE/GT comparisons
> we pretend the inverse is like for integral comparisons, which is
> true only if NANs can't appear in operands, while for UNLE/UNLT/UNGE/UNGT
> we don't override op1_op2_relation (so it always yields VREL_VARYING).
>
> Though, this patch regresses the
> FAIL: gcc.dg/tree-ssa/vrp-float-6.c scan-tree-dump-times evrp "Folding predicate x_.* <= y_.* to 1" 1
> test, so am not sure what to do with it.  The test has explicit
> !isnan tests around it, so e.g. having the ranges passed to op1_op2_relation
> would also fix it.


I see no reason op1_op2_relation can't have ranges provided to it for 
op1 and op2.  There was no need originally.  There are times when we 
don't have a range handy and we want the simple answer, but if the 
ranges are available, we could utilize them.

Attached is a patch which added op1 and op2 ranges to the routine.  GORI 
will utilize and pass on real ranges (which I think is the core part you 
want), but the consumers in fold_using_range at this point will simply 
pass in varying.  There are 2 consumers in fold_using_range.. one is a 
combiner for logicals, and the other is for export outgoing relations 
that are not on the branch condition.  The combiner could use real 
ranges, but until I fix dispatch up it is very awkward to get them.  The 
export one simply doesn't have them without going to an calculating 
them.. which would probably be expensive..

Regardless, you can at least try your enhancement using real ranges and 
see if this works for you.

This bootstraps and has no regressions, and is fine by me if you want to 
use it.,

Andrew


[-- Attachment #2: rel.patch --]
[-- Type: text/x-patch, Size: 14578 bytes --]

commit 3715234f2cba21f2b9ec6c609b6f058d1d8af500
Author: Andrew MacLeod <amacleod@redhat.com>
Date:   Tue Apr 11 12:25:49 2023 -0400

    Add op1 and op2 ranges to op1_op2_relation.
    
            * gimple-range-fold.cc (fold_using_range::relation_fold_and_or):
            Provide VARYING for op1 and op2 when calling op1_op2_relation.
            (fur_source::register_outgoing_edges): Ditto.
            * gimple-range-gori.cc (gori_compute::compute_operand1_range):
            Pass op1 and op2 ranges to op1_op2_relation.
            (gori_compute::compute_operand2_range): Ditto.
            * range-op-float.cc (*::op1_op2_relation): Adjust params.
            * range-op.cc (*::op1_op2_relation): Adjust params.
            * range-op.h (*::op1_op2_relation): Adjust params.

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index e81f6b3699e..3170b1e71a1 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -1051,9 +1051,11 @@ fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
     return;
 
   int_range<2> bool_one (boolean_true_node, boolean_true_node);
+  Value_Range op (TREE_TYPE (ssa1));
+  op.set_varying (TREE_TYPE (ssa1));
 
-  relation_kind relation1 = handler1.op1_op2_relation (bool_one);
-  relation_kind relation2 = handler2.op1_op2_relation (bool_one);
+  relation_kind relation1 = handler1.op1_op2_relation (bool_one, op, op);
+  relation_kind relation2 = handler2.op1_op2_relation (bool_one, op, op);
   if (relation1 == VREL_VARYING || relation2 == VREL_VARYING)
     return;
 
@@ -1125,15 +1127,17 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
   tree ssa2 = gimple_range_ssa_p (handler.operand2 ());
   if (ssa1 && ssa2)
     {
+      Value_Range op (TREE_TYPE (ssa1));
+      op.set_varying (TREE_TYPE (ssa1));
       if (e0)
 	{
-	  relation_kind relation = handler.op1_op2_relation (e0_range);
+	  relation_kind relation = handler.op1_op2_relation (e0_range, op, op);
 	  if (relation != VREL_VARYING)
 	    register_relation (e0, relation, ssa1, ssa2);
 	}
       if (e1)
 	{
-	  relation_kind relation = handler.op1_op2_relation (e1_range);
+	  relation_kind relation = handler.op1_op2_relation (e1_range, op, op);
 	  if (relation != VREL_VARYING)
 	    register_relation (e1, relation, ssa1, ssa2);
 	}
@@ -1160,17 +1164,19 @@ fur_source::register_outgoing_edges (gcond *s, irange &lhs_range, edge e0, edge
       Value_Range r (TREE_TYPE (name));
       if (ssa1 && ssa2)
 	{
+	  Value_Range op (TREE_TYPE (ssa1));
+	  op.set_varying (TREE_TYPE (ssa1));
 	  if (e0 && gori ()->outgoing_edge_range_p (r, e0, name, *m_query)
 	      && r.singleton_p ())
 	    {
-	      relation_kind relation = handler.op1_op2_relation (r);
+	      relation_kind relation = handler.op1_op2_relation (r, op, op);
 	      if (relation != VREL_VARYING)
 		register_relation (e0, relation, ssa1, ssa2);
 	    }
 	  if (e1 && gori ()->outgoing_edge_range_p (r, e1, name, *m_query)
 	      && r.singleton_p ())
 	    {
-	      relation_kind relation = handler.op1_op2_relation (r);
+	      relation_kind relation = handler.op1_op2_relation (r, op, op);
 	      if (relation != VREL_VARYING)
 		register_relation (e1, relation, ssa1, ssa2);
 	    }
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index d77e1f51ac2..a488c230f6c 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -1105,7 +1105,8 @@ gori_compute::compute_operand1_range (vrange &r,
       // This allows multiple relations to be processed in compound logicals.
       if (gimple_range_ssa_p (op1) && gimple_range_ssa_p (op2))
 	{
-	  relation_kind k = handler.op1_op2_relation (lhs);
+	  relation_kind k = handler.op1_op2_relation (lhs, op1_range,
+						      op2_range);
 	  if (k != VREL_VARYING)
 	    {
 	      op_op = k;
@@ -1210,7 +1211,7 @@ gori_compute::compute_operand2_range (vrange &r,
   // This allows multiple relations to be processed in compound logicals.
   if (gimple_range_ssa_p (op1) && gimple_range_ssa_p (op2))
     {
-      relation_kind k = handler.op1_op2_relation (lhs);
+      relation_kind k = handler.op1_op2_relation (lhs, op1_range, op2_range);
       if (k != VREL_VARYING)
 	{
 	  op_op = k;
diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index e0e91bad44d..72de8f2a856 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -233,13 +233,17 @@ range_operator_float::lhs_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
 }
 
 relation_kind
-range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const
+range_operator_float::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
+					const frange &op1 ATTRIBUTE_UNUSED,
+					const frange &op2 ATTRIBUTE_UNUSED) const
 {
   return VREL_VARYING;
 }
 
 relation_kind
-range_operator_float::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED) const
+range_operator_float::op1_op2_relation (const frange &lhs ATTRIBUTE_UNUSED,
+					const frange &op1 ATTRIBUTE_UNUSED,
+					const frange &op2 ATTRIBUTE_UNUSED) const
 {
   return VREL_VARYING;
 }
@@ -578,7 +582,8 @@ public:
   bool fold_range (irange &r, tree type,
 		   const frange &op1, const frange &op2,
 		   relation_trio = TRIO_VARYING) const final override;
-  relation_kind op1_op2_relation (const irange &lhs) const final override
+  relation_kind op1_op2_relation (const irange &lhs, const frange &,
+				  const frange &) const final override
   {
     return equal_op1_op2_relation (lhs);
   }
@@ -706,7 +711,8 @@ public:
   bool fold_range (irange &r, tree type,
 		   const frange &op1, const frange &op2,
 		   relation_trio rel = TRIO_VARYING) const final override;
-  relation_kind op1_op2_relation (const irange &lhs) const final override
+  relation_kind op1_op2_relation (const irange &lhs, const frange &,
+				  const frange &) const final override
   {
     return not_equal_op1_op2_relation (lhs);
   }
@@ -829,7 +835,8 @@ public:
   bool fold_range (irange &r, tree type,
 		   const frange &op1, const frange &op2,
 		   relation_trio = TRIO_VARYING) const final override;
-  relation_kind op1_op2_relation (const irange &lhs) const final override
+  relation_kind op1_op2_relation (const irange &lhs, const frange &,
+				  const frange &) const final override
   {
     return lt_op1_op2_relation (lhs);
   }
@@ -945,7 +952,8 @@ public:
   bool fold_range (irange &r, tree type,
 		   const frange &op1, const frange &op2,
 		   relation_trio rel = TRIO_VARYING) const final override;
-  relation_kind op1_op2_relation (const irange &lhs) const final override
+  relation_kind op1_op2_relation (const irange &lhs, const frange &,
+				  const frange &) const final override
   {
     return le_op1_op2_relation (lhs);
   }
@@ -1055,7 +1063,8 @@ public:
   bool fold_range (irange &r, tree type,
 		   const frange &op1, const frange &op2,
 		   relation_trio = TRIO_VARYING) const final override;
-  relation_kind op1_op2_relation (const irange &lhs) const final override
+  relation_kind op1_op2_relation (const irange &lhs, const frange &,
+				  const frange &) const final override
   {
     return gt_op1_op2_relation (lhs);
   }
@@ -1175,7 +1184,8 @@ public:
   bool fold_range (irange &r, tree type,
 		   const frange &op1, const frange &op2,
 		   relation_trio = TRIO_VARYING) const final override;
-  relation_kind op1_op2_relation (const irange &lhs) const final override
+  relation_kind op1_op2_relation (const irange &lhs, const frange &,
+				  const frange &) const final override
   {
     return ge_op1_op2_relation (lhs);
   }
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index f90e78dcfbc..876747110a9 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -368,11 +368,14 @@ range_operator::lhs_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
 }
 
 relation_kind
-range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED) const
+range_operator::op1_op2_relation (const irange &lhs ATTRIBUTE_UNUSED,
+				  const irange &op1 ATTRIBUTE_UNUSED,
+				  const irange &op2 ATTRIBUTE_UNUSED) const
 {
   return VREL_VARYING;
 }
 
+
 // Default is no relation affects the LHS.
 
 bool
@@ -565,7 +568,9 @@ public:
 			  const irange &lhs,
 			  const irange &val,
 			  relation_trio = TRIO_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs,
+					  const irange &,
+					  const irange &) const;
 } op_equal;
 
 // Check if the LHS range indicates a relation between OP1 and OP2.
@@ -587,7 +592,8 @@ equal_op1_op2_relation (const irange &lhs)
 }
 
 relation_kind
-operator_equal::op1_op2_relation (const irange &lhs) const
+operator_equal::op1_op2_relation (const irange &lhs, const irange &,
+				  const irange &) const
 {
   return equal_op1_op2_relation (lhs);
 }
@@ -685,7 +691,8 @@ public:
 			  const irange &lhs,
 			  const irange &op1,
 			  relation_trio = TRIO_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs, const irange &,
+					  const irange &) const;
 } op_not_equal;
 
 // Check if the LHS range indicates a relation between OP1 and OP2.
@@ -707,7 +714,8 @@ not_equal_op1_op2_relation (const irange &lhs)
 }
 
 relation_kind
-operator_not_equal::op1_op2_relation (const irange &lhs) const
+operator_not_equal::op1_op2_relation (const irange &lhs, const irange &,
+				      const irange &) const
 {
   return not_equal_op1_op2_relation (lhs);
 }
@@ -865,7 +873,8 @@ public:
 			  const irange &lhs,
 			  const irange &op1,
 			  relation_trio = TRIO_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs, const irange &,
+					  const irange &) const;
 } op_lt;
 
 // Check if the LHS range indicates a relation between OP1 and OP2.
@@ -887,7 +896,8 @@ lt_op1_op2_relation (const irange &lhs)
 }
 
 relation_kind
-operator_lt::op1_op2_relation (const irange &lhs) const
+operator_lt::op1_op2_relation (const irange &lhs, const irange &,
+			       const irange &) const
 {
   return lt_op1_op2_relation (lhs);
 }
@@ -985,7 +995,8 @@ public:
 			  const irange &lhs,
 			  const irange &op1,
 			  relation_trio = TRIO_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs, const irange &,
+					  const irange &) const;
 } op_le;
 
 // Check if the LHS range indicates a relation between OP1 and OP2.
@@ -1007,7 +1018,8 @@ le_op1_op2_relation (const irange &lhs)
 }
 
 relation_kind
-operator_le::op1_op2_relation (const irange &lhs) const
+operator_le::op1_op2_relation (const irange &lhs, const irange &,
+			       const irange &) const
 {
   return le_op1_op2_relation (lhs);
 }
@@ -1102,7 +1114,8 @@ public:
 			  const irange &lhs,
 			  const irange &op1,
 			  relation_trio = TRIO_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs, const irange &,
+					  const irange &) const;
 } op_gt;
 
 // Check if the LHS range indicates a relation between OP1 and OP2.
@@ -1124,7 +1137,8 @@ gt_op1_op2_relation (const irange &lhs)
 }
 
 relation_kind
-operator_gt::op1_op2_relation (const irange &lhs) const
+operator_gt::op1_op2_relation (const irange &lhs, const irange &,
+			       const irange &) const
 {
   return gt_op1_op2_relation (lhs);
 }
@@ -1218,7 +1232,8 @@ public:
 			  const irange &lhs,
 			  const irange &op1,
 			  relation_trio = TRIO_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs, const irange &,
+					  const irange &) const;
 } op_ge;
 
 // Check if the LHS range indicates a relation between OP1 and OP2.
@@ -1240,7 +1255,8 @@ ge_op1_op2_relation (const irange &lhs)
 }
 
 relation_kind
-operator_ge::op1_op2_relation (const irange &lhs) const
+operator_ge::op1_op2_relation (const irange &lhs, const irange &,
+			       const irange &) const
 {
   return ge_op1_op2_relation (lhs);
 }
@@ -4845,14 +4861,21 @@ range_op_handler::lhs_op2_relation (const vrange &lhs,
 }
 
 relation_kind
-range_op_handler::op1_op2_relation (const vrange &lhs) const
+range_op_handler::op1_op2_relation (const vrange &lhs, const vrange &op1,
+				    const vrange &op2) const
 {
   gcc_checking_assert (m_valid);
   if (m_int)
-    return m_int->op1_op2_relation (as_a <irange> (lhs));
+    return m_int->op1_op2_relation (as_a <irange> (lhs),
+				    as_a <irange> (op1),
+				    as_a <irange> (op2));
   if (is_a <irange> (lhs))
-    return m_float->op1_op2_relation (as_a <irange> (lhs));
-  return m_float->op1_op2_relation (as_a <frange> (lhs));
+    return m_float->op1_op2_relation (as_a <irange> (lhs),
+				      as_a <frange> (op1),
+				      as_a <frange> (op2));
+  return m_float->op1_op2_relation (as_a <frange> (lhs),
+				    as_a <frange> (op1),
+				    as_a <frange> (op2));
 }
 
 // Cast the range in R to TYPE.
diff --git a/gcc/range-op.h b/gcc/range-op.h
index 03ef6b98542..310302b4ec9 100644
--- a/gcc/range-op.h
+++ b/gcc/range-op.h
@@ -89,7 +89,9 @@ public:
 					  const irange &op1,
 					  const irange &op2,
 					  relation_kind = VREL_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs,
+					  const irange &op1,
+					  const irange &op2) const;
 protected:
   // Perform an integral operation between 2 sub-ranges and return it.
   virtual void wi_fold (irange &r, tree type,
@@ -178,8 +180,12 @@ public:
 					  const frange &op1,
 					  const frange &op2,
 					  relation_kind = VREL_VARYING) const;
-  virtual relation_kind op1_op2_relation (const irange &lhs) const;
-  virtual relation_kind op1_op2_relation (const frange &lhs) const;
+  virtual relation_kind op1_op2_relation (const irange &lhs,
+					  const frange &op1,
+					  const frange &op2) const;
+  virtual relation_kind op1_op2_relation (const frange &lhs,
+					  const frange &op1,
+					  const frange &op2) const;
 };
 
 class range_op_handler
@@ -209,7 +215,8 @@ public:
 				  const vrange &op1,
 				  const vrange &op2,
 				  relation_kind = VREL_VARYING) const;
-  relation_kind op1_op2_relation (const vrange &lhs) const;
+  relation_kind op1_op2_relation (const vrange &lhs, const vrange &op1,
+				  const vrange &op2) const;
 protected:
   void set_op_handler (enum tree_code code, tree type);
   bool m_valid;

  parent reply	other threads:[~2023-04-11 20:58 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-11  8:21 Jakub Jelinek
2023-04-11  8:59 ` Aldy Hernandez
2023-04-11 20:58 ` Andrew MacLeod [this message]
2023-04-12 10:33   ` Jakub Jelinek
2023-04-12 14:21     ` Jakub Jelinek
2023-04-12 16:35       ` Bernhard Reutner-Fischer
2023-04-12 16:40         ` Jakub Jelinek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7ad17002-8df2-c268-03f5-902ed57f3a97@redhat.com \
    --to=amacleod@redhat.com \
    --cc=aldyh@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).