]> 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>
Wed, 14 May 2025 10:08:28 +0000 (12:08 +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.

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 302b73e83b8ffe8a372a4e0562f3f87dcb4c094c..4b6daf772841cc7a0e160162709980d9cfee4944 100644 (file)
@@ -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,