https://gcc.gnu.org/g:9d039eff453f777c58642ff16178c1ce2a4be6ab

commit r16-614-g9d039eff453f777c58642ff16178c1ce2a4be6ab
Author: Martin Jambor <mjam...@suse.cz>
Date:   Wed May 14 12:08:24 2025 +0200

    tree-sra: Do not create stores into const aggregates (PR111873)
    
    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  <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.

Diff:
---
 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(-)

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 000000000000..f9fee3e85afb
--- /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 000000000000..5130791f5444
--- /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 000000000000..cd9b94c094fc
--- /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 302b73e83b8f..4b6daf772841 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,

Reply via email to