From: Martin Jambor Date: Wed, 23 Jul 2025 09:22:33 +0000 (+0200) Subject: tree-sra: Avoid total SRA if there are incompat. aggregate accesses (PR119085) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=171fcc80ede596442712e559c4fc787aa4636694;p=thirdparty%2Fgcc.git 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 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 PR tree-optimization/119085 * gcc.dg/tree-ssa/pr119085.c: New test. --- 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 00000000000..e9811ce12b5 --- /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 240af676ea3..032f2770484 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