]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-sra: Avoid total SRA if there are incompat. aggregate accesses (PR119085)
authorMartin Jambor <mjambor@suse.cz>
Wed, 23 Jul 2025 09:22:33 +0000 (11:22 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Tue, 29 Jul 2025 08:34:42 +0000 (10:34 +0200)
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  <mjambor@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  <mjambor@suse.cz>

PR tree-optimization/119085
* gcc.dg/tree-ssa/pr119085.c: New test.

(cherry picked from commit 171fcc80ede596442712e559c4fc787aa4636694)

gcc/testsuite/gcc.dg/tree-ssa/pr119085.c [new file with mode: 0644]
gcc/tree-sra.cc

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr119085.c b/gcc/testsuite/gcc.dg/tree-ssa/pr119085.c
new file mode 100644 (file)
index 0000000..e9811ce
--- /dev/null
@@ -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;
+}
index 307e8e29b8440e33faa53cdeb64b64e2b9fe9a17..aac5d733aa7b503706a5a9f6c6ef62ddb24bf7b4 100644 (file)
@@ -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