From: Andrew MacLeod Date: Thu, 24 Jun 2021 17:35:21 +0000 (-0400) Subject: Only register relations on live edges X-Git-Tag: upstream/12.2.0~6900 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a0accaa99844b0c40661202635859f8c0be76cdd;p=platform%2Fupstream%2Fgcc.git 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. --- 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 (s)) - postfold_gcond_edges (as_a (s), src); + postfold_gcond_edges (as_a (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; +}