Hi, this patch fixes (hopefully the) one remaining place where gimple SRA was still creating a load into a const aggregates. It occurs when there was a replacement for a load but that replacement is not type compatible - typically because it was a single field structure.
I have used testcases from duplicates because the original test-case no longer reproduces for me. It is kind of embarrassing how long it took me to get to this given the issue is actually very simple. Based on my hazy recollection from earlier encounters with SRA and TREE_READONLY, I had expected it to be quite bit more convoluted. Anyway, it passes bootstrap and testing on x86_64-linux, bootstrap on Aarch64, testsuite is still running there. OK for master and all active release branches if it passes? Thanks, Martin gcc/ChangeLog: 2025-05-13 Martin Jambor <mjam...@suse.cz> PR tree-optimization/111873 * tree-sra.cc (sra_modify_expr): When processing a load which has a type-incompatible replacement, do not store the contents of the replacement into the original aggregate when that aggregate is const. gcc/testsuite/ChangeLog: 2025-05-13 Martin Jambor <mjam...@suse.cz> * gcc.dg/ipa/pr120044-1.c: New test. * gcc.dg/ipa/pr120044-2.c: Likewise. * gcc.dg/tree-ssa/pr114864.c: Likewise. --- gcc/testsuite/gcc.dg/ipa/pr120044-1.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/ipa/pr120044-2.c | 17 +++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr114864.c | 15 +++++++++++++++ gcc/tree-sra.cc | 4 +++- 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/pr120044-1.c create mode 100644 gcc/testsuite/gcc.dg/ipa/pr120044-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr114864.c diff --git a/gcc/testsuite/gcc.dg/ipa/pr120044-1.c b/gcc/testsuite/gcc.dg/ipa/pr120044-1.c new file mode 100644 index 00000000000..f9fee3e85af --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr120044-1.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-tree-fre -fno-tree-pre -fno-code-hoisting -fno-inline" } */ + +struct a { + int b; +} const c; +void d(char p, struct a e) { + while (e.b) + ; +} +static unsigned short f(const struct a g) { + d(g.b, g); + return g.b; +} +int main() { + return f(c); +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr120044-2.c b/gcc/testsuite/gcc.dg/ipa/pr120044-2.c new file mode 100644 index 00000000000..5130791f544 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr120044-2.c @@ -0,0 +1,17 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-early-inlining -fno-tree-fre -fno-tree-pre -fno-code-hoisting -fno-ipa-cp" } */ + +struct a { + int b; +} const c; +void d(char p, struct a e) { + while (e.b) + ; +} +static unsigned short f(const struct a g) { + d(g.b, g); + return g.b; +} +int main() { + return f(c); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr114864.c b/gcc/testsuite/gcc.dg/tree-ssa/pr114864.c new file mode 100644 index 00000000000..cd9b94c094f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr114864.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-options "-O1 -fno-tree-dce -fno-tree-fre" } */ + +struct a { + int b; +} const c; +void d(const struct a f) {} +void e(const struct a f) { + f.b == 0 ? 1 : f.b; + d(f); +} +int main() { + e(c); + return 0; +} diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc index 302b73e83b8..4b6daf77284 100644 --- a/gcc/tree-sra.cc +++ b/gcc/tree-sra.cc @@ -4205,8 +4205,10 @@ sra_modify_expr (tree *expr, bool write, gimple_stmt_iterator *stmt_gsi, } else { - gassign *stmt; + if (TREE_READONLY (access->base)) + return false; + gassign *stmt; if (access->grp_partial_lhs) repl = force_gimple_operand_gsi (stmt_gsi, repl, true, NULL_TREE, true, -- 2.49.0