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)
--- /dev/null
+/* { 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;
+}
}
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