Hi,
This patch fixes PR80345. It is backport of PR68021 to GCC 5 branch with one
assert statement removed. It also includes test case provided in the PR.
Bootstrap and test on x86_64. Is it OK?
Thanks,
bin
2017-04-07 Bin Cheng <bin.ch...@arm.com>
Backport from mainline
2016-02-10 Bin Cheng <bin.ch...@arm.com>
PR tree-optimization/68021
* tree-ssa-loop-ivopts.c (get_computation_aff): Set ratio to 1 if
when computing the value of biv cand by itself.
gcc/testsuite/ChangeLog
2017-04-07 Bin Cheng <bin.ch...@arm.com>
PR tree-optimization/80345
* gcc.c-torture/compile/pr80345.c
Backport from mainline
2016-02-10 Bin Cheng <bin.ch...@arm.com>
PR tree-optimization/68021
* gcc.dg/tree-ssa/pr68021.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr80345.c
b/gcc/testsuite/gcc.c-torture/compile/pr80345.c
new file mode 100644
index 0000000..3a9f3d7
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr80345.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/80345 */
+
+typedef long mp_limb_signed_t;
+void fn1(mp_limb_signed_t p1) {
+ int *a = (int *)1;
+ mp_limb_signed_t i, j;
+ i = 0;
+ for (; i < p1; i++) {
+ j = 0;
+ for (; j <= i; j++)
+ *a++ = 0;
+ j = i + 1;
+ for (; j < p1; j++)
+ a++;
+ }
+}
+void fn2() { fn1((mp_limb_signed_t)fn2); }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr68021.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr68021.c
new file mode 100644
index 0000000..f60b1ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr68021.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+char a;
+void fn1 (char *p1, int p2, int p3)
+{
+ int i, x;
+ for (i = 0; i < 10; i++)
+ {
+ for (x = 0; x < p3; x++)
+ {
+ *p1 = a;
+ p1--;
+ }
+ p1 += p2;
+ }
+}
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 6c96430..1d64261 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -3118,7 +3118,18 @@ get_computation_aff (struct loop *loop,
var = fold_convert (uutype, var);
}
- if (!constant_multiple_of (ustep, cstep, &rat))
+ /* Ratio is 1 when computing the value of biv cand by itself.
+ We can't rely on constant_multiple_of in this case because the
+ use is created after the original biv is selected. The call
+ could fail because of inconsistent fold behavior. See PR68021
+ for more information. */
+ if (cand->pos == IP_ORIGINAL && cand->incremented_at == use->stmt)
+ {
+ gcc_assert (is_gimple_assign (use->stmt));
+ gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after);
+ rat = 1;
+ }
+ else if (!constant_multiple_of (ustep, cstep, &rat))
return false;
/* In case both UBASE and CBASE are shortened to UUTYPE from some common