diff mbox series

[COMMITTED] tree-optimization/101189 - Only register relations on live edges

Message ID cfd480d7-dcc8-496b-a84a-15a8979cf26b@redhat.com
State New
Headers show
Series [COMMITTED] tree-optimization/101189 - Only register relations on live edges | expand

Commit Message

Andrew MacLeod June 24, 2021, 8:03 p.m. UTC
As mentioned in the PR analysis, we shouldn't register a relation on an 
outgoing conditional edge if range analysis proves that edge can never 
be taken. Its just asking for trouble :-)

Bootstrapped on x86_64-pc-linux-gnu.  Pushed.

Andrew
diff mbox series

Patch

From a0accaa99844b0c40661202635859f8c0be76cdd Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Thu, 24 Jun 2021 13:35:21 -0400
Subject: [PATCH 1/2] Only register relations on live edges

Register a relation on a conditional edge only if the LHS supports
this edge being taken.

	gcc/
	PR tree-optimization/101189
	* gimple-range-fold.cc (fold_using_range::range_of_range_op): Pass
	LHS range of condition to postfold routine.
	(fold_using_range::postfold_gcond_edges): Only process the TRUE or
	FALSE edge if the LHS range supports it being taken.
	* gimple-range-fold.h (postfold_gcond_edges): Add range parameter.

	gcc/testsuite/
	* gcc.dg/tree-ssa/pr101189.c: New.
---
 gcc/gimple-range-fold.cc                 | 29 +++++++++++++++++++-----
 gcc/gimple-range-fold.h                  |  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/pr101189.c | 17 ++++++++++++++
 3 files changed, 41 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr101189.c

diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 583348e6e36..1fa4ace32b9 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -617,7 +617,7 @@  fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
 		}
 	    }
 	  else if (is_a<gcond *> (s))
-	    postfold_gcond_edges (as_a<gcond *> (s), src);
+	    postfold_gcond_edges (as_a<gcond *> (s), r, src);
 	}
       else
 	r.set_varying (type);
@@ -1247,9 +1247,11 @@  fold_using_range::relation_fold_and_or (irange& lhs_range, gimple *s,
 // Register any outgoing edge relations from a conditional branch.
 
 void
-fold_using_range::postfold_gcond_edges (gcond *s, fur_source &src)
+fold_using_range::postfold_gcond_edges (gcond *s, irange& lhs_range,
+					fur_source &src)
 {
   int_range_max r;
+  int_range<2> e0_range, e1_range;
   tree name;
   range_operator *handler;
   basic_block bb = gimple_bb (s);
@@ -1257,10 +1259,27 @@  fold_using_range::postfold_gcond_edges (gcond *s, fur_source &src)
   edge e0 = EDGE_SUCC (bb, 0);
   if (!single_pred_p (e0->dest))
     e0 = NULL;
+  else
+    {
+      // If this edge is never taken, ignore it.
+      gcond_edge_range (e0_range, e0);
+      e0_range.intersect (lhs_range);
+      if (e0_range.undefined_p ())
+	e0 = NULL;
+    }
+
 
   edge e1 = EDGE_SUCC (bb, 1);
   if (!single_pred_p (e1->dest))
     e1 = NULL;
+  else
+    {
+      // If this edge is never taken, ignore it.
+      gcond_edge_range (e1_range, e1);
+      e1_range.intersect (lhs_range);
+      if (e1_range.undefined_p ())
+	e1 = NULL;
+    }
 
   // At least one edge needs to be single pred.
   if (!e0 && !e1)
@@ -1276,15 +1295,13 @@  fold_using_range::postfold_gcond_edges (gcond *s, fur_source &src)
       gcc_checking_assert (handler);
       if (e0)
 	{
-	  gcond_edge_range (r, e0);
-	  relation_kind relation = handler->op1_op2_relation (r);
+	  relation_kind relation = handler->op1_op2_relation (e0_range);
 	  if (relation != VREL_NONE)
 	    src.register_relation (e0, relation, ssa1, ssa2);
 	}
       if (e1)
 	{
-	  gcond_edge_range (r, e1);
-	  relation_kind relation = handler->op1_op2_relation (r);
+	  relation_kind relation = handler->op1_op2_relation (e1_range);
 	  if (relation != VREL_NONE)
 	    src.register_relation (e1, relation, ssa1, ssa2);
 	}
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index aeb923145ca..dc1b28f9acc 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -158,6 +158,6 @@  protected:
   void range_of_ssa_name_with_loop_info (irange &, tree, class loop *, gphi *,
 					 fur_source &src);
   void relation_fold_and_or (irange& lhs_range, gimple *s, fur_source &src);
-  void postfold_gcond_edges (gcond *s, fur_source &src);
+  void postfold_gcond_edges (gcond *s, irange &lhs_range, fur_source &src);
 };
 #endif // GCC_GIMPLE_RANGE_FOLD_H
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c b/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c
new file mode 100644
index 00000000000..5730708a0b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr101189.c
@@ -0,0 +1,17 @@ 
+/* PR tree-optimization/101189  */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+static int a, b;
+int main() {
+  int d = 0, e, f = 5;
+  if (a)
+    f = 0;
+  for (; f < 4; f++)
+    ;
+  e = f ^ -f;
+  e && d;
+  if (!e)
+    e || b;
+  return 0;
+}
-- 
2.17.2