https://gcc.gnu.org/g:ee30e2586a3142e63daaf301a561984f1d22d38d

commit r15-7665-gee30e2586a3142e63daaf301a561984f1d22d38d
Author: Richard Biener <rguent...@suse.de>
Date:   Fri Feb 21 09:58:04 2025 +0100

    tree-optimization/118954 - avoid UB on ref created by predcom
    
    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.
    
            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.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr118954.c | 22 ++++++++++++++++++++++
 gcc/tree-predcom.cc                     |  3 ++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr118954.c 
b/gcc/testsuite/gcc.dg/torture/pr118954.c
new file mode 100644
index 000000000000..6b95e0b8c46f
--- /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 ade8fbf0b5c3..d45aa3857b9f 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);

Reply via email to