]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-optimization/120944 - bogus VN with volatile copies
authorRichard Biener <rguenther@suse.de>
Fri, 4 Jul 2025 07:08:19 +0000 (09:08 +0200)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 9 Jul 2025 06:29:34 +0000 (08:29 +0200)
The following avoids translating expressions through volatile
copies.

PR tree-optimization/120944
* tree-ssa-sccvn.cc (vn_reference_lookup_3): Gate optimizations
invalid when volatile is involved.

* gcc.dg/torture/pr120944.c: New testcase.

(cherry picked from commit 6ed1e2ae1a742d859c2dd74c9e7cebdd3618e8b1)

gcc/testsuite/gcc.dg/torture/pr120944.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.cc

diff --git a/gcc/testsuite/gcc.dg/torture/pr120944.c b/gcc/testsuite/gcc.dg/torture/pr120944.c
new file mode 100644 (file)
index 0000000..92f3c77
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+/* { dg-additional-options "-fdump-tree-optimized" } */
+
+#include <stdlib.h>
+
+typedef union {
+  int u32;
+  struct
+  {
+     int A:1;
+     int B:2;
+     int C:3;
+  };
+} u_t;
+
+typedef union {
+   volatile int u[3];
+   volatile struct {
+        u_t a;
+        int b;
+        int c;
+   };
+} DATA;
+
+void foo (volatile DATA *d)
+{
+     d->a.u32 = ~0;
+     u_t u = d->a;
+     int v = u.A;
+     if (v)
+        abort();
+}
+
+/* { dg-final { scan-tree-dump-times "if \\\(" 1 "optimized" } } */
index f3bc6dbebe13e7ec933913f18ea97b013ad6f23a..7f2500e5d591df13e6fbc8e81d39fc02fe34cfb4 100644 (file)
@@ -2809,7 +2809,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
          we find a VN result with exactly the same value as the
         possible clobber.  In this case we can ignore the clobber
         and return the found value.  */
-      if (is_gimple_reg_type (TREE_TYPE (lhs))
+      if (!gimple_has_volatile_ops (def_stmt)
+         && is_gimple_reg_type (TREE_TYPE (lhs))
          && types_compatible_p (TREE_TYPE (lhs), vr->type)
          && (ref->ref || data->orig_ref.ref)
          && !data->mask
@@ -3093,7 +3094,8 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
   else if (is_gimple_reg_type (vr->type)
           && gimple_assign_single_p (def_stmt)
           && gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
-          && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0)
+          && CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0
+          && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt)))
     {
       tree base2;
       poly_int64 offset2, size2, maxsize2;
@@ -3149,6 +3151,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
           && !reverse_storage_order_for_component_p (vr->operands)
           && !contains_storage_order_barrier_p (vr->operands)
           && gimple_assign_single_p (def_stmt)
+          && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
           && CHAR_BIT == 8
           && BITS_PER_UNIT == 8
           && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
@@ -3307,6 +3310,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
           && !reverse_storage_order_for_component_p (vr->operands)
           && !contains_storage_order_barrier_p (vr->operands)
           && gimple_assign_single_p (def_stmt)
+          && !TREE_THIS_VOLATILE (gimple_assign_lhs (def_stmt))
           && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
     {
       tree lhs = gimple_assign_lhs (def_stmt);
@@ -3518,6 +3522,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
      the copy kills ref.  */
   else if (data->vn_walk_kind == VN_WALKREWRITE
           && gimple_assign_single_p (def_stmt)
+          && !gimple_has_volatile_ops (def_stmt)
           && (DECL_P (gimple_assign_rhs1 (def_stmt))
               || TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
               || handled_component_p (gimple_assign_rhs1 (def_stmt))))