Hi,
Loop header PHI defining IV(biv) may not be identified as biv because its
increment statement is in (irreducible) inner loop. Function
find_deriving_biv_for_expr doesn't take this into consideration and runs into
infinite recursion. The patch fixes this issue by skipping such loop header
PHI. Bootstrap and test on x86_64 and AArch64, is it OK?
BTW, we don't mark such IV as biv because of below code:
/* If the increment is in the subloop, ignore it. */
incr_bb = gimple_bb (SSA_NAME_DEF_STMT (var));
if (incr_bb->loop_father != data->current_loop
|| (incr_bb->flags & BB_IRREDUCIBLE_LOOP))
continue;
I thought twice and this check may be too strict. Given valid incr_iv returned
by simple_iv, we know it behaves just like usual increment IVs. In other
words, though the increment statement is executed multiple times in inner loop,
it computes the same result for every iteration. Anyway this is stage1 work.
Thanks,
bin
2016-11-30 Bin Cheng <bin.ch...@arm.com>
PR tree-optimization/78574
* tree-ssa-loop-ivopts.c (find_deriving_biv_for_expr): Skip loop
header PHI that doesn't define biv.
gcc/testsuite/ChangeLog
2016-11-30 Bin Cheng <bin.ch...@arm.com>
PR tree-optimization/78574
* gcc.c-torture/compile/pr78574.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr78574.c
b/gcc/testsuite/gcc.c-torture/compile/pr78574.c
new file mode 100644
index 0000000..8c91d1e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr78574.c
@@ -0,0 +1,27 @@
+/* PR tree-optimization/78574 */
+
+int a, d, f, g;
+int b[1];
+short h;
+int main() {
+ long j;
+ int k, i;
+ for (; j; j++) {
+ i = 0;
+ for (; i < 6; i++) {
+ int l = a, m = d || g;
+ L:
+ l ^ m | a;
+ }
+ b[j + 1] = 2;
+ ++k;
+ for (; g; g++) {
+ d ^= h;
+ if (f)
+ for (;;)
+ ;
+ }
+ }
+ if (k)
+ goto L;
+}
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 5c667a2..00b287a 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1853,6 +1853,11 @@ find_deriving_biv_for_expr (struct ivopts_data *data,
tree expr)
{
ssa_op_iter iter;
use_operand_p use_p;
+ basic_block phi_bb = gimple_bb (phi);
+
+ /* Skip loop header PHI that doesn't define biv. */
+ if (phi_bb->loop_father == data->current_loop)
+ return NULL;
if (virtual_operand_p (gimple_phi_result (phi)))
return NULL;