]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-sra: Do not create stores into const aggregates (PR111873)
authorMartin Jambor <mjambor@suse.cz>
Wed, 14 May 2025 10:08:24 +0000 (12:08 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Tue, 10 Jun 2025 15:43:46 +0000 (17:43 +0200)
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.

(cherry picked from commit 9d039eff453f777c58642ff16178c1ce2a4be6ab)

gcc/testsuite/gcc.dg/ipa/pr120044-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/pr120044-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/pr114864.c [new file with mode: 0644]
gcc/tree-sra.cc

diff --git a/gcc/testsuite/gcc.dg/ipa/pr120044-1.c b/gcc/testsuite/gcc.dg/ipa/pr120044-1.c
new file mode 100644 (file)
index 0000000..f9fee3e
--- /dev/null
@@ -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 (file)
index 0000000..5130791
--- /dev/null
@@ -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 (file)
index 0000000..cd9b94c
--- /dev/null
@@ -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;
+}
index 91af2aef8b4c37ed79e94aa13ee15388475aa253..4a7836bc257b90fa89db801fc43a576bca774685 100644 (file)
@@ -3871,8 +3871,10 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
            }
          else
            {
-             gassign *stmt;
+             if (TREE_READONLY (access->base))
+               return false;
 
+             gassign *stmt;
              if (access->grp_partial_lhs)
                repl = force_gimple_operand_gsi (gsi, repl, true, NULL_TREE,
                                                 true, GSI_SAME_STMT);