diff --git a/gcc/gimple-loop-jam.cc b/gcc/gimple-loop-jam.cc index 9a2eba02dd978a6e6310853d6ff64e8f0ed9c852..5e6c04a7d7f2e15a9d12a54b56bed9997e532103 100644 --- a/gcc/gimple-loop-jam.cc +++ b/gcc/gimple-loop-jam.cc @@ -279,13 +279,17 @@ unroll_jam_possible_p (class loop *outer, class loop *loop) body would be the after-iter value of the first body) if it's over an associative and commutative operation. We wouldn't be able to handle unknown cycles. */ + bool inner_vdef = false; for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi)) { affine_iv iv; tree op = gimple_phi_result (psi.phi ()); if (virtual_operand_p (op)) - continue; + { + inner_vdef = true; + continue; + } if (!simple_iv (loop, loop, op, &iv, true)) return false; /* The inductions must be regular, loop invariant step and initial @@ -301,6 +305,12 @@ unroll_jam_possible_p (class loop *outer, class loop *loop) copy, _not_ the next value of the second body. */ } + /* When there's no inner loop virtual PHI IV we cannot handle the update + required to the inner loop if that doesn't already have one. See + PR117113. */ + if (!inner_vdef && get_virtual_phi (outer->header)) + return false; + return true; } diff --git a/gcc/testsuite/gcc.dg/torture/pr117113.c b/gcc/testsuite/gcc.dg/torture/pr117113.c new file mode 100644 index 0000000000000000000000000000000000000000..e90ad034a4d3f5bfe05582c887051a4ff755907f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr117113.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fno-tree-dce -fno-inline" } */ + +int a, b, c; +volatile int d[1]; +void e() {} +void f(int g) {} +int main() { + int i; + for (; b; b--) { + for (i = 0; i < 3; i++) { + e(); + f(d[0]); + d[0]; + } + if (a) + c++; + } + return 0; +}