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