re PR rtl-optimization/79405 (Infinite loop in fwprop)
authorSegher Boessenkool <segher@kernel.crashing.org>
Fri, 31 Mar 2017 22:49:53 +0000 (00:49 +0200)
committerJeff Law <law@gcc.gnu.org>
Fri, 31 Mar 2017 22:49:53 +0000 (16:49 -0600)
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.

From-SVN: r246627

gcc/ChangeLog
gcc/fwprop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr79405.c [new file with mode: 0644]

index 012d8f825f0209b074b395a6165facf856bd9f55..d4096c9a64a03f8bcc912699e33d4e49925e9d47 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-31  Segher Boessenkool  <segher@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.
+
 2017-03-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/79255
index 285fb1ab78a26aa7b440cbb85bab015038484431..0ab25efdb8565fa0110307060916cdc309ccbf11 100644 (file)
@@ -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
index d88e067d84051f913a951789b408abdde32805f1..7f236ac742e551b955a20887dec9b104a5e09d79 100644 (file)
@@ -1,3 +1,8 @@
+2017-03-31  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR rtl-optimization/79405
+       gcc.dg/pr79405.c: New testcase.
+
 2017-03-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR debug/79255
diff --git a/gcc/testsuite/gcc.dg/pr79405.c b/gcc/testsuite/gcc.dg/pr79405.c
new file mode 100644 (file)
index 0000000..c17baff
--- /dev/null
@@ -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 *)&sc;
+      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;
+}