Hi!

The following testcase ICEs, because ve->reg is a SUBREG and thus should not
be shared, but we initialize sum to ve->reg, then add to it some REGs (which
can be shared always), and finally assign the addition etc. result into
ve->reg.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2017-04-24  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/80500
        * loop-unroll.c (combine_var_copies_in_loop_exit): Call copy_rtx on
        sum's initial value.

        * gcc.dg/pr80500.c: New test.

--- gcc/loop-unroll.c.jj        2017-04-04 07:32:57.000000000 +0200
+++ gcc/loop-unroll.c   2017-04-24 09:22:35.816571901 +0200
@@ -1913,6 +1913,7 @@ combine_var_copies_in_loop_exit (struct
   if (ve->var_expansions.length () == 0)
     return;
 
+  sum = copy_rtx (sum);
   start_sequence ();
   switch (ve->op)
     {
--- gcc/testsuite/gcc.dg/pr80500.c.jj   2017-04-24 09:29:39.382031846 +0200
+++ gcc/testsuite/gcc.dg/pr80500.c      2017-04-24 09:29:15.000000000 +0200
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/80500 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -funroll-loops -ftree-loop-if-convert 
-fvariable-expansion-in-unroller" } */
+
+signed char v;
+
+void
+foo (int x)
+{
+  while (x != 0)
+    {
+      v = (x >= 0) + 1;
+      ++x;
+    }
+}

        Jakub

Reply via email to