diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2021-06-24 13:35:21 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2021-06-24 16:01:55 -0400 |
commit | a0accaa99844b0c40661202635859f8c0be76cdd (patch) | |
tree | c6d9dade1c227a5ce29b876acea3ade86809d564 | |
parent | ce0b409f562cd09c67cc2dce74143a0f0647cde5 (diff) | |
download | gcc-a0accaa99844b0c40661202635859f8c0be76cdd.zip gcc-a0accaa99844b0c40661202635859f8c0be76cdd.tar.gz gcc-a0accaa99844b0c40661202635859f8c0be76cdd.tar.bz2 |
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.
-rw-r--r-- | gcc/gimple-range-fold.cc | 29 | ||||
-rw-r--r-- | gcc/gimple-range-fold.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr101189.c | 17 |
3 files changed, 41 insertions, 7 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 583348e..1fa4ace 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 aeb9231..dc1b28f 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 0000000..5730708 --- /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; +} |