This is the same thing as gcc.dg/pr52558-1.c, but in this case I had to
tweak the testcase a bit because optimization passes after LIM are smart
enough to remove the condition altogether, thus never triggering the
test. Interestingly, GCC can figure out what's going on when the
condition is "l < 1234", but not when it is "l != 4".
Luckily, the original PR (PR52558) was testing "l != 4", so now the test
looks exactly as the what the PR writer had.
Tested on x86-64 Linux by running with and without --param
allow-store-data-races=0, and by visual inspection of the assembly.
OK?
testsuite/
* gcc.dg/pr52558-2.c: Delete.
* gcc.dg/simulate-thread/speculative-store-3.c: New.
diff --git a/gcc/testsuite/gcc.dg/pr52558-2.c b/gcc/testsuite/gcc.dg/pr52558-2.c
deleted file mode 100644
index 6d5f51c..0000000
--- a/gcc/testsuite/gcc.dg/pr52558-2.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "--param allow-store-data-races=0 -O2 -fdump-tree-lim1" } */
-
-/* Test that g_2 is not written to unless !g_1. */
-
-int g_1 = 1;
-int g_2 = 0;
-
-int func_1(void)
-{
- int l;
- for (l = 0; l < 1234; l++)
- {
- if (g_1)
- return l;
- else
- g_2 = 0;
- }
- return 999;
-}
-
-/* { dg-final { scan-tree-dump-times "MEM.*g_2_lsm_flag" 1 "lim1" } } */
-/* { dg-final { cleanup-tree-dump "lim1" } } */
diff --git a/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c
b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c
new file mode 100644
index 0000000..203c026
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/simulate-thread/speculative-store-3.c
@@ -0,0 +1,71 @@
+/* { dg-do link } */
+/* { dg-options "--param allow-store-data-races=0 -O2" } */
+/* { dg-final { simulate-thread } } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "simulate-thread.h"
+
+/* Test distilled from PR52558. */
+
+int g_1 = 1;
+int g_2 = 0, insns = 0;
+int f;
+
+/* Test that g_2 is not written to unless !g_1. */
+
+__attribute__((noinline))
+int funky()
+{
+ int l;
+ for (l = 0; l != 4; l++)
+ {
+ if (g_1)
+ {
+ /* g_1 is globally true so we should always execute here,
+ thus never writing to g_2 under any circumstance in this
+ code path. */
+ return l;
+ }
+ for (g_2 = 0; g_2 >= 26; ++g_2)
+ ;
+ }
+ return 999;
+}
+
+int simulate_thread_final_verify ()
+{
+ /* If g_2 != insns, someone must have cached `g_2' and stored a
+ racy value into it. */
+ if (g_2 != insns)
+ {
+ printf("FAIL: g_2 was incorrectly cached\n");
+ return 1;
+ }
+ return 0;
+}
+
+void simulate_thread_other_threads ()
+{
+ ++insns;
+ ++g_2;
+}
+
+int simulate_thread_step_verify ()
+{
+ return 0;
+}
+
+__attribute__((noinline))
+void simulate_thread_main()
+{
+ f = funky();
+}
+
+int main()
+{
+ simulate_thread_main ();
+ simulate_thread_done ();
+ return 0;
+}