Partial PRE ends up miscompiling the testcase in PR109002, likely involving a corner case when inifinite loops are involved. The following avoids the miscompilation by addressing a long-standing oddity that manifests in odd partial partial redundancies eliminated that are full redundancies. The oddity is that while we properly PHI translate the PA_IN set from the successors when computing PA_OUT but we fail to do the same for ANTIC_IN which is supposed to be unioned. That results in expressions with wrong virtual operands being placed in the PA_OUT/IN sets and the pruning machinery to go wrong because it assumes the expressions in the sets have virtual operands that are valid in the respective blocks.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/109002 * tree-ssa-pre.cc (compute_partial_antic_aux): Properly PHI-translate ANTIC_IN. * gcc.dg/torture/pr109002.c: New testcase. --- gcc/testsuite/gcc.dg/torture/pr109002.c | 27 +++++++++++++++++++++++++ gcc/tree-ssa-pre.cc | 20 ++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr109002.c diff --git a/gcc/testsuite/gcc.dg/torture/pr109002.c b/gcc/testsuite/gcc.dg/torture/pr109002.c new file mode 100644 index 00000000000..5575a4b9edc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr109002.c @@ -0,0 +1,27 @@ +/* { dg-do run } */ +/* { dg-additional-options "-ftree-pre -ftree-partial-pre" } */ + +extern void exit (int); + +int g; +int h; + +void __attribute__((noipa)) bar () +{ + if (g) + exit (0); +} + +int main(void) +{ + for (int i = 0; ; i++) { + for (int j = 0; j < g; j++); + if (i & 1) { + if (h) + continue; + if (g) + bar (); + g = 1; + } + } +} diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index f77732d75c3..37cad36f2de 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2364,11 +2364,14 @@ compute_partial_antic_aux (basic_block block, unsigned int i; bitmap_iterator bi; - FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (e->dest), i, bi) - bitmap_value_insert_into_set (PA_OUT, - expression_for_id (i)); if (!gimple_seq_empty_p (phi_nodes (e->dest))) { + bitmap_set_t antic_in = bitmap_set_new (); + phi_translate_set (antic_in, ANTIC_IN (e->dest), e); + FOR_EACH_EXPR_ID_IN_SET (antic_in, i, bi) + bitmap_value_insert_into_set (PA_OUT, + expression_for_id (i)); + bitmap_set_free (antic_in); bitmap_set_t pa_in = bitmap_set_new (); phi_translate_set (pa_in, PA_IN (e->dest), e); FOR_EACH_EXPR_ID_IN_SET (pa_in, i, bi) @@ -2377,9 +2380,14 @@ compute_partial_antic_aux (basic_block block, bitmap_set_free (pa_in); } else - FOR_EACH_EXPR_ID_IN_SET (PA_IN (e->dest), i, bi) - bitmap_value_insert_into_set (PA_OUT, - expression_for_id (i)); + { + FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (e->dest), i, bi) + bitmap_value_insert_into_set (PA_OUT, + expression_for_id (i)); + FOR_EACH_EXPR_ID_IN_SET (PA_IN (e->dest), i, bi) + bitmap_value_insert_into_set (PA_OUT, + expression_for_id (i)); + } } } } -- 2.35.3