On Thu, Mar 23, 2017 at 3:58 PM, Segher Boessenkool <seg...@kernel.crashing.org> wrote: > The algorithm fwprop uses never reconsiders a possible propagation, > although it could succeed if the def (in the def-use to propagate) > has changed. This causes fwprop to do infinite propagations, like > in the scenario in the PR, where we end up with effectively > B = A > A = B > D = A > where only propagations into the last statement are still tried, and > that loops (it becomes D = B, then back to D = A, etc.) > > Fixing this properly isn't easy; this patch instead limits the number > of propagations performed to the number of uses we originally had, > which is the maximum number of propagations that can be done if there > are no such infinite loops. > > Bootstrapped and regression checked on powerpc64-linux {-m64,-m32}; > is this okay for trunk?
https://gcc.gnu.org/ml/gcc-patches/2017-02/msg01485.html ? > > Segher > > > 2017-03-23 Segher Boessenkool <seg...@kernel.crashing.org> > > PR rtl-optimization/79405 > * fwprop.c (propagations_left): New variable. > (forward_propagate_into): Decrement it. > (fwprop_init): Initialize it. > (fw_prop): If the variable has reached zero, stop propagating. > (fwprop_addr): Ditto. > > gcc/testsuite/ > PR rtl-optimization/79405 > gcc.dg/pr79405.c: New testcase. > > --- > gcc/fwprop.c | 17 ++++++++++++++++ > gcc/testsuite/gcc.dg/pr79405.c | 45 > ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 62 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/pr79405.c > > diff --git a/gcc/fwprop.c b/gcc/fwprop.c > index 285fb1a..0ab25ef 100644 > --- a/gcc/fwprop.c > +++ b/gcc/fwprop.c > @@ -120,6 +120,13 @@ static vec<df_ref> use_def_ref; > static vec<df_ref> reg_defs; > static vec<df_ref> reg_defs_stack; > > +/* The maximum number of propagations that are still allowed. If we do > + more propagations than originally we had uses, we must have ended up > + in a propagation loop, as in PR79405. Until the algorithm fwprop > + uses can obviously not get into such loops we need a workaround like > + this. */ > +static int propagations_left; > + > /* The MD bitmaps are trimmed to include only live registers to cut > memory usage on testcases like insn-recog.c. Track live registers > in the basic block and do not perform forward propagation if the > @@ -1407,6 +1414,8 @@ forward_propagate_into (df_ref use) > if (forward_propagate_and_simplify (use, def_insn, def_set) > || forward_propagate_subreg (use, def_insn, def_set)) > { > + propagations_left--; > + > if (cfun->can_throw_non_call_exceptions > && find_reg_note (use_insn, REG_EH_REGION, NULL_RTX) > && purge_dead_edges (DF_REF_BB (use))) > @@ -1434,6 +1443,8 @@ fwprop_init (void) > active_defs = XNEWVEC (df_ref, max_reg_num ()); > if (flag_checking) > active_defs_check = sparseset_alloc (max_reg_num ()); > + > + propagations_left = DF_USES_TABLE_SIZE (); > } > > static void > @@ -1480,6 +1491,9 @@ fwprop (void) > > for (i = 0; i < DF_USES_TABLE_SIZE (); i++) > { > + if (!propagations_left) > + break; > + > df_ref use = DF_USES_GET (i); > if (use) > if (DF_REF_TYPE (use) == DF_REF_REG_USE > @@ -1540,6 +1554,9 @@ fwprop_addr (void) > end, and we'll go through them as well. */ > for (i = 0; i < DF_USES_TABLE_SIZE (); i++) > { > + if (!propagations_left) > + break; > + > df_ref use = DF_USES_GET (i); > if (use) > if (DF_REF_TYPE (use) != DF_REF_REG_USE > diff --git a/gcc/testsuite/gcc.dg/pr79405.c b/gcc/testsuite/gcc.dg/pr79405.c > new file mode 100644 > index 0000000..c17baff > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr79405.c > @@ -0,0 +1,45 @@ > +/* PR rtl-optimization/79405 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +char cz; > +long long int xx, u2; > + > +void > +qv (int js, int wl) > +{ > + if (js != 0) > + { > + short int sc; > + int *at = (int *)≻ > + long long int gx = 0; > + > + for (;;) > + { > + *at = 0; > + js /= sc; > + > + for (wl = 0; wl < 2; ++wl) > + { > + xx = gx; > + u2 %= xx > 0; > + cz /= u2; > + > + fa: > + if (cz != u2) > + { > + gx |= js; > + cz = gx / js; > + } > + } > + } > + > + yq: > + wl /= 0x80000000; > + u2 = wl; > + u2 |= (wl != 0) | (wl != 0 && gx != 0); > + js = u2; > + goto fa; > + } > + goto yq; > +} > -- > 1.9.3 >