When predicitive commoning moves an invariant ref it makes sure to
not build a MEM_REF with a base that is negatively offsetted from
an object. But in trying to preserve some transforms it does not
consider association of a constant offset with the address computation
in DR_BASE_ADDRESS leading to exactly this problem again. This is
arguably a problem in data-ref analysis producing such an out-of-bound
DR_BASE_ADDRESS, but this looks quite involved to fix, so the
following avoids the association in one more case. This fixes the
testcase while preserving the desired transform in
gcc.dg/tree-ssa/predcom-1.c.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.
Richard.
PR tree-optimization/118954
* tree-predcom.cc (ref_at_iteration): Make sure to not
associate the constant offset with DR_BASE_ADDRESS when
that is an offsetted pointer.
* gcc.dg/torture/pr118954.c: New testcase.
---
gcc/testsuite/gcc.dg/torture/pr118954.c | 22 ++++++++++++++++++++++
gcc/tree-predcom.cc | 3 ++-
2 files changed, 24 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.dg/torture/pr118954.c
diff --git a/gcc/testsuite/gcc.dg/torture/pr118954.c
b/gcc/testsuite/gcc.dg/torture/pr118954.c
new file mode 100644
index 00000000000..6b95e0b8c46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr118954.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fpredictive-commoning" } */
+
+int a, b, c, d;
+void e(int f)
+{
+ int g[] = {5, 8};
+ int *h = g;
+ while (c < f) {
+ d = 0;
+ for (; d < f; d++)
+ c = h[d];
+ }
+}
+int main()
+{
+ int i = (0 == a + 1) - 1;
+ e(i + 3);
+ if (b != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-predcom.cc b/gcc/tree-predcom.cc
index ade8fbf0b5c..d45aa3857b9 100644
--- a/gcc/tree-predcom.cc
+++ b/gcc/tree-predcom.cc
@@ -1807,7 +1807,8 @@ ref_at_iteration (data_reference_p dr, int iter,
then. But for some cases we can retain that to allow tree_could_trap_p
to return false - see gcc.dg/tree-ssa/predcom-1.c */
tree addr, alias_ptr;
- if (integer_zerop (off))
+ if (integer_zerop (off)
+ && TREE_CODE (DR_BASE_ADDRESS (dr)) != POINTER_PLUS_EXPR)
{
alias_ptr = fold_convert (reference_alias_ptr_type (ref), coff);
addr = DR_BASE_ADDRESS (dr);
--
2.43.0