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
>From a0accaa99844b0c40661202635859f8c0be76cdd Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@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