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

commit r15-10083-gb1b8d8ce3eea34959a63400680ce4bf783a1d337
Author: Martin Jambor <mjam...@suse.cz>
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  <mjam...@suse.cz>
    
            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  <mjam...@suse.cz>
    
            PR tree-optimization/119085
            * gcc.dg/tree-ssa/pr119085.c: New test.
    
    (cherry picked from commit 171fcc80ede596442712e559c4fc787aa4636694)

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 307e8e29b844..aac5d733aa7b 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -2504,6 +2504,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