https://gcc.gnu.org/g:02c58bc4b0885f5b6f50033da35768ebe6c4a030

commit r16-1012-g02c58bc4b0885f5b6f50033da35768ebe6c4a030
Author: Richard Biener <rguent...@suse.de>
Date:   Fri May 30 13:47:55 2025 +0200

    tree-optimization/120341 - stores into STRING_CSTs can trap
    
    The following fixes conditional store elimination and store motion
    so they consider stores to STRING_CSTs as trapping.
    
            PR tree-optimization/120341
            * tree-ssa-loop-im.cc (can_sm_ref_p): STRING_CSTs are readonly.
            * tree-ssa-phiopt.cc (cond_store_replacement): Likewise.
    
            * gcc.dg/torture/pr120341-1.c: New testcase.
            * gcc.dg/torture/pr120341-2.c: Likewise.

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr120341-1.c | 11 +++++++++++
 gcc/testsuite/gcc.dg/torture/pr120341-2.c | 13 +++++++++++++
 gcc/tree-ssa-loop-im.cc                   |  3 ++-
 gcc/tree-ssa-phiopt.cc                    |  5 +++--
 4 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr120341-1.c 
b/gcc/testsuite/gcc.dg/torture/pr120341-1.c
new file mode 100644
index 000000000000..e23185b62b07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120341-1.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fallow-store-data-races" } */
+
+char a, *b;
+int main()
+{
+  b = "0";
+  if (a)
+    b[0]++;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr120341-2.c 
b/gcc/testsuite/gcc.dg/torture/pr120341-2.c
new file mode 100644
index 000000000000..7bcc96f63ddc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr120341-2.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fallow-store-data-races" } */
+
+char a, *b;
+int main()
+{
+  while (a)
+    {
+      b = "0";
+      b[0]++;
+    }
+  return 0;
+}
diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
index 50d2ee9b99d6..aee419aa5b1e 100644
--- a/gcc/tree-ssa-loop-im.cc
+++ b/gcc/tree-ssa-loop-im.cc
@@ -3307,7 +3307,8 @@ can_sm_ref_p (class loop *loop, im_mem_ref *ref)
      explicitly.  */
   base = get_base_address (ref->mem.ref);
   if ((tree_could_trap_p (ref->mem.ref)
-       || (DECL_P (base) && TREE_READONLY (base)))
+       || (DECL_P (base) && TREE_READONLY (base))
+       || TREE_CODE (base) == STRING_CST)
       /* ???  We can at least use false here, allowing loads?  We
         are forcing conditional stores if the ref is not always
         stored to later anyway.  So this would only guard
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 8c5908e5bff9..bf493e129878 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -3525,8 +3525,9 @@ cond_store_replacement (basic_block middle_bb, 
basic_block join_bb,
          /* tree_could_trap_p is a predicate for rvalues, so check
             for readonly memory explicitly.  */
          || ((base = get_base_address (lhs))
-             && DECL_P (base)
-             && TREE_READONLY (base)))
+             && ((DECL_P (base)
+                  && TREE_READONLY (base))
+                 || TREE_CODE (base) == STRING_CST)))
        return false;
     }

Reply via email to