This is a similar test to the previous acquire test. Here we are
incorrectly caching 'x' and failing to reload it after the __ATOMIC_ACQUIRE.
+ i = x + y;
+
+ if (__atomic_load_n (&flag, __ATOMIC_ACQUIRE))
+ {
+ /* x here should not be reused from above. */
+ k = x;
+ }
Note that there is technically a data race on the load of x+y. See the
explanation on my previous testcase.
OK for branch?
Index: testsuite/gcc.dg/simulate-thread/atomic-hoist-2.c
===================================================================
--- testsuite/gcc.dg/simulate-thread/atomic-hoist-2.c (revision 0)
+++ testsuite/gcc.dg/simulate-thread/atomic-hoist-2.c (revision 0)
@@ -0,0 +1,60 @@
+/* { dg-do link } */
+/* { dg-require-effective-target sync_int_long } */
+/* { dg-final { simulate-thread } } */
+
+/* Test that a load is not precomputed before an acquire. */
+
+#include <stdio.h>
+#include "simulate-thread.h"
+
+int flag=0;
+int x = 0, y = 10, i = 0, k = -1;
+
+__attribute__((noinline))
+void simulate_thread_main()
+{
+ /* Test that the first load of x is not cached and reused in the second
+ load of x. */
+
+ /* Note: Technically this first load of x/y is a data race. See
+ note on atomic-hoist-1.c. */
+ i = x + y;
+
+ if (__atomic_load_n (&flag, __ATOMIC_ACQUIRE))
+ {
+ /* x here should not be reused from above. */
+ k = x;
+ }
+}
+
+void simulate_thread_other_threads ()
+{
+ /* Once i has been calculated in thread 1, change the value of x. */
+ if (i != 0)
+ {
+ x = -1;
+ flag = 1;
+ }
+}
+
+int simulate_thread_step_verify ()
+{
+ return 0;
+}
+
+int simulate_thread_final_verify ()
+{
+ if (k != -1)
+ {
+ printf("FAIL: k != -1\n");
+ return 1;
+ }
+ return 0;
+}
+
+main()
+{
+ simulate_thread_main ();
+ simulate_thread_done ();
+ return 0;
+}