https://gcc.gnu.org/g:96d53252aefcbc2fe419c4c3b4bcd3fc03d4d187

commit r15-581-g96d53252aefcbc2fe419c4c3b4bcd3fc03d4d187
Author: Jan Hubicka <j...@suse.cz>
Date:   Thu May 16 15:33:55 2024 +0200

    Fix points_to_local_or_readonly_memory_p wrt TARGET_MEM_REF
    
    TARGET_MEM_REF can be used to offset constant base into a memory object (to
    produce lea instruction).  This confuses 
points_to_local_or_readonly_memory_p
    which treats the constant address as a base of the access.
    
    Bootstrapped/regtsted x86_64-linux, comitted.
    Honza
    
    gcc/ChangeLog:
    
            PR ipa/113787
            * ipa-fnsummary.cc (points_to_local_or_readonly_memory_p): Do not
            look into TARGET_MEM_REFS with constant opreand 0.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.c-torture/execute/pr113787.c: New test.

Diff:
---
 gcc/ipa-fnsummary.cc                           |  4 ++-
 gcc/testsuite/gcc.c-torture/execute/pr113787.c | 38 ++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 07a853f78e39..2faf23892971 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -2648,7 +2648,9 @@ points_to_local_or_readonly_memory_p (tree t)
        return true;
       return !ptr_deref_may_alias_global_p (t, false);
     }
-  if (TREE_CODE (t) == ADDR_EXPR)
+  if (TREE_CODE (t) == ADDR_EXPR
+      && (TREE_CODE (TREE_OPERAND (t, 0)) != TARGET_MEM_REF
+         || TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)) != INTEGER_CST))
     return refs_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
   return false;
 }
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr113787.c 
b/gcc/testsuite/gcc.c-torture/execute/pr113787.c
new file mode 100644
index 000000000000..702b6c35fc68
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr113787.c
@@ -0,0 +1,38 @@
+void foo(int x, int y, int z, int d, int *buf)
+{
+  for(int i = z; i < y-z; ++i)
+    for(int j = 0; j < d; ++j)
+      /* buf[x(i+1) + j] = buf[x(i+1)-j-1] */
+      buf[i*x+(x-z+j)] = buf[i*x+(x-z-1-j)];
+}
+
+void bar(int x, int y, int z, int d, int *buf)
+{
+  for(int i = 0; i < d; ++i)
+    for(int j = z; j < x-z; ++j)
+      /* buf[j+(y+i)*x] = buf[j+(y-1-i)*x] */
+      buf[j+(y-z+i)*x] = buf[j+(y-z-1-i)*x];
+}
+
+__attribute__((noipa))
+void baz(int x, int y, int d, int *buf)
+{
+  foo(x, y, 0, d, buf);
+  bar(x, y, 0, d, buf);
+}
+
+int main(void)
+{
+  int a[] = { 1, 2, 3 };
+  baz (1, 2, 1, a);
+  /* foo does:
+     buf[1] = buf[0];
+     buf[2] = buf[1];
+
+     bar does:
+     buf[2] = buf[1]; (no-op)
+     so we should have { 1, 1, 1 }.  */
+  for (int i = 0; i < 3; i++)
+    if (a[i] != 1)
+      __builtin_abort ();
+}

Reply via email to