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