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

commit r17-5123-gc312eea008ebfefc946d51cd064adaaa0efe8fb0
Author: Richard Biener <[email protected]>
Date:   Tue Oct 13 15:28:09 2026 +0200

    tree-optimization/127858 - fix memory access canonicalization in LIM
    
    When we canonicalize a memory access we merge accesses with differing
    access paths to a plain MEM_REF, but when there is a previous access
    with an access path we fail to clear the ao_refs base and offset.
    
            PR tree-optimization/127858
            * tree-ssa-loop-im.cc (gather_mem_refs_stmt): When merging
            accesses with differing access path always reset base and
            offset to the canonical form by re-using the already canonical
            ao_ref.
    
            * gcc.dg/torture/pr127858.c: New testcase.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr127858.c | 44 +++++++++++++++++++++++++++++++++
 gcc/tree-ssa-loop-im.cc                 |  5 +---
 2 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr127858.c 
b/gcc/testsuite/gcc.dg/torture/pr127858.c
new file mode 100644
index 000000000000..a7982aafbf2d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr127858.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+
+struct node {
+    struct node *prev;
+    struct node *next;
+};
+
+struct owner {
+    int          id;
+    struct node  list;
+};
+
+int __attribute__((noipa))
+count_stale_reads(struct owner *owner, struct node *list_alias,
+                 struct node *new_values, int iterations)
+{
+  struct node **field = &owner->list.prev;
+  int stale = 0;
+  int i;
+
+  for (i = 0; i < iterations; i++)
+    {
+      struct node *before = owner->list.prev;
+      list_alias->prev = &new_values[i];
+      struct node *after = *field;
+      if (before == after)
+       stale++;
+    }
+
+  return stale;
+}
+
+int
+main()
+{
+  static struct owner  owner;          /* list.prev starts out NULL */
+  static struct node   new_values[4];
+  int                  stale;
+
+  stale = count_stale_reads (&owner, &owner.list, new_values, 4);
+  if (stale != 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 162b30ad2859..04f6e9282ee8 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -1742,10 +1742,7 @@ gather_mem_refs_stmt (class loop *loop, gimple *stmt)
                 a canonical ref which is a bare MEM_REF.  */
              if (TREE_CODE (*mem) == MEM_REF
                  || TREE_CODE (*mem) == TARGET_MEM_REF)
-               {
-                 (*slot)->mem.ref = *mem;
-                 (*slot)->mem.base_alias_set = ao_ref_base_alias_set (&aor);
-               }
+               (*slot)->mem = aor;
              else
                {
                  tree ref_alias_type = reference_alias_ptr_type (*mem);

Reply via email to