diff --git a/gcc/testsuite/gcc.dg/torture/pr100053.c b/gcc/testsuite/gcc.dg/torture/pr100053.c new file mode 100644 index 0000000000000000000000000000000000000000..3d1767513f3a26dac47fa5e5254d943107ff6387 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100053.c @@ -0,0 +1,25 @@ +/* { dg-do run } */ + +int __attribute__((returns_twice,noipa)) x() { return 0; } +void __attribute__((noipa)) ar() {} +void __attribute__((noipa)) as() { __builtin_abort (); } +int a1, a2, a3; +void __attribute__((noipa)) v(int init) +{ + if (!init) { + as(); + if (a1) + goto aq; + x (); + } + ar(); +aq: + if (!init) + as(); +} + +int main() +{ + v(1); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c new file mode 100644 index 0000000000000000000000000000000000000000..7f66b7ee3f40609210cae6de29da3a279a4190ca --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-93.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1" } */ + +void bar (); +void foo (int pred, int *other) +{ + *other = 0; + if (*other) + goto cnt; + if (pred) + { + *other = 1; +cnt: + if (!pred) + bar (); + } +} + +/* The first VN pass should figure that if (!pred) is false because + if (*other) is and thus the predicate test is redundant. */ +/* { dg-final { scan-tree-dump-not "bar" "fre1" } } */ diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 16e75b518b01b0715ff6939d26834dc3230aba95..ca0974d72b826254b954eed512989ff8adfec1c2 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4171,7 +4171,7 @@ vn_nary_op_insert_pieces_predicated (unsigned int length, enum tree_code code, } static bool -dominated_by_p_w_unex (basic_block bb1, basic_block bb2); +dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool); static tree vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb) @@ -4180,9 +4180,12 @@ vn_nary_op_get_predicated_value (vn_nary_op_t vno, basic_block bb) return vno->u.result; for (vn_pval *val = vno->u.values; val; val = val->next) for (unsigned i = 0; i < val->n; ++i) - if (dominated_by_p_w_unex (bb, - BASIC_BLOCK_FOR_FN - (cfun, val->valid_dominated_by_p[i]))) + /* Do not handle backedge executability optimistically since + when figuring out whether to iterate we do not consider + changed predication. */ + if (dominated_by_p_w_unex + (bb, BASIC_BLOCK_FOR_FN (cfun, val->valid_dominated_by_p[i]), + false)) return val->result; return NULL_TREE; } @@ -4482,10 +4485,11 @@ vn_phi_insert (gimple *phi, tree result, bool backedges_varying_p) /* Return true if BB1 is dominated by BB2 taking into account edges - that are not executable. */ + that are not executable. When ALLOW_BACK is false consider not + executable backedges as executable. */ static bool -dominated_by_p_w_unex (basic_block bb1, basic_block bb2) +dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back) { edge_iterator ei; edge e; @@ -4502,7 +4506,8 @@ dominated_by_p_w_unex (basic_block bb1, basic_block bb2) { edge prede = NULL; FOR_EACH_EDGE (e, ei, bb1->preds) - if (e->flags & EDGE_EXECUTABLE) + if ((e->flags & EDGE_EXECUTABLE) + || (!allow_back && (e->flags & EDGE_DFS_BACK))) { if (prede) { @@ -6901,7 +6906,7 @@ rpo_elim::eliminate_avail (basic_block bb, tree op) may also be able to "pre-compute" (bits of) the next immediate (non-)dominator during the RPO walk when marking edges as executable. */ - if (dominated_by_p_w_unex (bb, abb)) + if (dominated_by_p_w_unex (bb, abb, true)) { tree leader = ssa_name (av->leader); /* Prevent eliminations that break loop-closed SSA. */