aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2024-09-20 12:32:13 +0200
committerEric Botcazou <ebotcazou@adacore.com>2024-09-20 12:38:26 +0200
commit16d2d177ac11b4d968d0ec7df9602b3f4059583d (patch)
treefca68d760d45564c20aa37b164b8bf1203ad9495
parentbf4a5efa80ef8438deb0a99c9a02b1f550aaf814 (diff)
downloadgcc-16d2d177ac11b4d968d0ec7df9602b3f4059583d.zip
gcc-16d2d177ac11b4d968d0ec7df9602b3f4059583d.tar.gz
gcc-16d2d177ac11b4d968d0ec7df9602b3f4059583d.tar.bz2
Fix small thinko in IPA mod/ref pass
When a memory copy operation is analyzed by analyze_ssa_name, if both the load and store are made through the same SSA name, the store is overlooked. gcc/ * ipa-modref.cc (modref_eaf_analysis::analyze_ssa_name): Always process both the load and the store of a memory copy operation. gcc/testsuite/ * gcc.dg/ipa/modref-4.c: New test.
-rw-r--r--gcc/ipa-modref.cc3
-rw-r--r--gcc/testsuite/gcc.dg/ipa/modref-4.c34
2 files changed, 36 insertions, 1 deletions
diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
index 9275030..400a885 100644
--- a/gcc/ipa-modref.cc
+++ b/gcc/ipa-modref.cc
@@ -2610,8 +2610,9 @@ modref_eaf_analysis::analyze_ssa_name (tree name, bool deferred)
is used arbitrarily. */
if (memory_access_to (gimple_assign_rhs1 (assign), name))
m_lattice[index].merge (deref_flags (0, false));
+
/* Handle *name = *exp. */
- else if (memory_access_to (gimple_assign_lhs (assign), name))
+ if (memory_access_to (gimple_assign_lhs (assign), name))
m_lattice[index].merge_direct_store ();
}
/* Handle lhs = *name. */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-4.c b/gcc/testsuite/gcc.dg/ipa/modref-4.c
new file mode 100644
index 0000000..71ed1ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/modref-4.c
@@ -0,0 +1,34 @@
+/* { dg-options "-O" } */
+/* { dg-do run } */
+
+static __attribute__((noipa)) int foo (void)
+{
+ return 1;
+}
+
+int main (void)
+{
+ struct S { int a; int b; };
+ struct T { struct S s; };
+
+ struct T t = { { 0, 0 } };
+ struct T u;
+
+ __attribute__((noinline)) void bar (void)
+ {
+ if (foo ())
+ {
+ u = t;
+ /* OK with u.s.a = 0; */
+ }
+ }
+
+ u.s.a = 1;
+
+ bar ();
+
+ if (u.s.a != 0)
+ __builtin_abort ();
+
+ return 0;
+}