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

Reply via email to