This patch fixes (hopefully the) one remaining place where gimple SRA
was still creating a load into const aggregates. It occurs when there
is a replacement for a load but that replacement is not type
compatible - typically because it is a single field structure.
I have used testcases from duplicates because the original test-case
no longer reproduces for me.
gcc/ChangeLog:
2025-05-13 Martin Jambor <mjambor@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 <mjambor@suse.cz>
* gcc.dg/ipa/pr120044-1.c: New test.
* gcc.dg/ipa/pr120044-2.c: Likewise.
* gcc.dg/tree-ssa/pr114864.c: Likewise.
--- /dev/null
+/* { 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);
+}
--- /dev/null
+/* { 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);
+}
--- /dev/null
+/* { 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;
+}
}
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,