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
