Un-revert the reversion. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard. 2017-10-30 Richard Biener <rguent...@suse.de> PR tree-optimization/82762 Revert 2017-10-23 Richard Biener <rguent...@suse.de> PR tree-optimization/82129 Revert 2017-08-01 Richard Biener <rguent...@suse.de> PR tree-optimization/81181 * tree-ssa-pre.c (compute_antic_aux): Defer clean() to ... (compute_antic): ... end of iteration here. Index: gcc/tree-ssa-pre.c =================================================================== --- gcc/tree-ssa-pre.c (revision 254211) +++ gcc/tree-ssa-pre.c (working copy) @@ -2029,7 +2039,8 @@ static sbitmap has_abnormal_preds; ANTIC_OUT[BLOCK] = phi_translate (ANTIC_IN[succ(BLOCK)]) ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] - TMP_GEN[BLOCK]) -*/ + + Note that clean() is deferred until after the iteration. */ static bool compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) @@ -2165,7 +2176,8 @@ compute_antic_aux (basic_block block, bo bitmap_value_insert_into_set (ANTIC_IN (block), expression_for_id (bii)); - clean (ANTIC_IN (block)); + /* clean (ANTIC_IN (block)) is defered to after the iteration converged + because it can cause non-convergence, see for example PR81181. */ if (!bitmap_set_equal (old, ANTIC_IN (block))) changed = true; @@ -2397,6 +2409,12 @@ compute_antic (void) gcc_checking_assert (num_iterations < 500); } + /* We have to clean after the dataflow problem converged as cleaning + can cause non-convergence because it is based on expressions + rather than values. */ + FOR_EACH_BB_FN (block, cfun) + clean (ANTIC_IN (block)); + statistics_histogram_event (cfun, "compute_antic iterations", num_iterations); Index: gcc/testsuite/gcc.dg/torture/pr82762.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr82762.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr82762.c (working copy) @@ -0,0 +1,46 @@ +/* { dg-do compile } */ + +int printf (const char *, ...); + +int b, c, d, e, f, g, j, k; +char h, i; +volatile int l; + +int m (int n, int o) +{ + return o < 0 || o > 1 ? n : o; +} + +int p (int n, unsigned o) +{ + return n - o; +} + +int q () +{ + char r; + int a, s, t, u, v, w; +L: + if (t) + printf ("%d", d); + u = v; + while (j) + { + while (e) + for (w = 0; w != 54; w += 6) + { + l; + s = p (u < 1, i || c); + r = s < 0 || s > 1 ? 0 : 1 >> s; + v = r; + g = h; + } + if (h) + return f; + if (u) + for (a = 0; a != 54; a += 6) + f = m (2, -(k || b)); + } + d = t; + goto L; +}