From patchwork Fri Mar 23 15:46:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C11-atomic] new test: limit precomputing values across acquire barriers Date: Fri, 23 Mar 2012 05:46:44 -0000 From: Aldy Hernandez X-Patchwork-Id: 148456 Message-Id: <4F6C9AE4.3070103@redhat.com> To: Andrew MacLeod , Torvald Riegel , gcc-patches 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 +#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; +}