https://gcc.gnu.org/g:2f21edc2a760862eab9e542aa7e4fc7886dbd41f

commit r13-9892-g2f21edc2a760862eab9e542aa7e4fc7886dbd41f
Author: Martin Jambor <[email protected]>
Date:   Wed Jul 23 11:22:33 2025 +0200

    tree-sra: Avoid total SRA if there are incompat. aggregate accesses  
(PR119085)
    
    We currently use the types encountered in the function body and not in
    type declaration to perform total scalarization.  Bug PR 119085
    uncovered that we miss a check that when the same data is accessed
    with aggregate types that those are actually compatible.  Without it,
    we can base total scalarization on a type that does not "cover" all
    live data in a different part of the function.  This patch adds the
    check.
    
    gcc/ChangeLog:
    
    2025-07-21  Martin Jambor  <[email protected]>
    
            PR tree-optimization/119085
            * tree-sra.cc (sort_and_splice_var_accesses): Prevent total
            scalarization if two incompatible aggregates access the same place.
    
    gcc/testsuite/ChangeLog:
    
    2025-07-21  Martin Jambor  <[email protected]>
    
            PR tree-optimization/119085
            * gcc.dg/tree-ssa/pr119085.c: New test.
    
    (cherry picked from commit dabac057141c26a69325a410c81de0ff2157c6c9)

Diff:
---
 gcc/testsuite/gcc.dg/tree-ssa/pr119085.c | 37 ++++++++++++++++++++++++++++++++
 gcc/tree-sra.cc                          |  6 ++++++
 2 files changed, 43 insertions(+)

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr119085.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr119085.c
new file mode 100644
index 000000000000..e9811ce12b58
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr119085.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+struct with_hole {
+  int x;
+  long y;
+};
+struct without_hole {
+  int x;
+  int y;
+};
+union u {
+  struct with_hole with_hole;
+  struct without_hole without_hole;
+};
+
+void __attribute__((noinline))
+test (union u *up, union u u)
+{
+  union u u2;
+  volatile int f = 0;
+  u2 = u;
+  if (f)
+    u2.with_hole = u.with_hole;
+  *up = u2;
+}
+
+int main(void)
+{
+  union u u;
+  union u u2;
+  u2.without_hole.y = -1;
+  test (&u, u2);
+  if (u.without_hole.y != -1)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index 6533e340c3e7..85f89954c263 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -2302,6 +2302,12 @@ sort_and_splice_var_accesses (tree var)
                }
              unscalarizable_region = true;
            }
+         /* If there the same place is accessed with two incompatible
+            aggregate types, trying to base total scalarization on either of
+            them can be wrong.  */
+         if (!first_scalar && !types_compatible_p (access->type, ac2->type))
+           bitmap_set_bit (cannot_scalarize_away_bitmap,
+                           DECL_UID (access->base));
 
          if (grp_same_access_path
              && (!ac2->grp_same_access_path

Reply via email to