This reverts r17-1586, keeping its testcase and adding the one
that regressed, fixing PR125730 in a different way, recognizing
the issue at hand there is the emitted POINTER_PLUS_EXPRs that
we should not have generated due to association done by
IVOPTs via using tree-affine and by create_mem_ref as part of
distributing the pieces.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

        PR tree-optimization/126008
        * tree-ssa-loop-ivopts.cc (alloc_iv): Revert last change.
        * tree-ssa-address.cc (add_to_parts): Use unsigned arithmetic
        to accumulate to base.

        * gcc.dg/torture/pr126008.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr126008.c | 20 ++++++++++++++++++++
 gcc/tree-ssa-address.cc                 |  9 +++++++--
 gcc/tree-ssa-loop-ivopts.cc             |  8 +++++---
 3 files changed, 32 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr126008.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr126008.c 
b/gcc/testsuite/gcc.dg/torture/pr126008.c
new file mode 100644
index 00000000000..4b95aa9332c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr126008.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+int h, q, r;
+int o[27];
+
+__attribute__((noipa))
+void z (int r) {
+  int q = -13363 + r; // 27
+  int p = -71005931 * q + ~51083117 + 1968243255; // == 0
+  while (p != 12)
+  {
+    o[p] = 1 + p;
+    p = 1 + p;
+  }
+}
+
+int main () {
+  z(13390);
+}
diff --git a/gcc/tree-ssa-address.cc b/gcc/tree-ssa-address.cc
index 818ae35a873..30baf81d789 100644
--- a/gcc/tree-ssa-address.cc
+++ b/gcc/tree-ssa-address.cc
@@ -546,10 +546,15 @@ add_to_parts (struct mem_address *parts, tree elt)
       return;
     }
 
-  /* Add ELT to base.  */
+  /* Add ELT to base.  As we have arbitrarily associated address parts
+     make sure to use unsigned arithmetic.  */
   type = TREE_TYPE (parts->base);
   if (POINTER_TYPE_P (type))
-    parts->base = fold_build_pointer_plus (parts->base, elt);
+    parts->base
+      = fold_convert (TREE_TYPE (parts->base),
+                     fold_build2 (PLUS_EXPR, sizetype,
+                                  fold_convert (sizetype, parts->base),
+                                  fold_convert (sizetype, elt)));
   else
     parts->base = fold_build2 (PLUS_EXPR, type, parts->base, elt);
 }
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index bbd3cfaab24..4ca55325188 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -1162,8 +1162,8 @@ alloc_iv (struct ivopts_data *data, tree base, tree step,
                                              sizeof (struct iv));
   gcc_assert (step != NULL_TREE);
 
-  /* Canonicalize the address expression in base.
-     That leads to more equalities being detected and results in:
+  /* Canonicalize the address expression in base if it were an unsigned
+      computation. That leads to more equalities being detected and results in:
 
        1) More accurate cost can be computed for address expressions;
        2) Duplicate candidates won't be created for bases in different
@@ -1171,8 +1171,10 @@ alloc_iv (struct ivopts_data *data, tree base, tree step,
        3) Duplicate candidates won't be created for IV expressions that differ
          only in their sign.  */
   aff_tree comb;
+  STRIP_NOPS (expr);
+  expr = fold_convert (unsigned_type_for (TREE_TYPE (expr)), expr);
   tree_to_aff_combination (expr, TREE_TYPE (expr), &comb);
-  base = aff_combination_to_tree (&comb);
+  base = fold_convert (TREE_TYPE (base), aff_combination_to_tree (&comb));
 
   iv->base = base;
   iv->base_object = determine_base_object (data, base);
-- 
2.51.0

Reply via email to