xref: /llvm-project/compiler-rt/test/tsan/vector_race.cpp (revision 5cac2b956bcf42495a2253443502fb73dbb43c3d)
1 // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s
2 #include "test.h"
3 
4 __m128i data[20];
5 
load(__m128i * v)6 __m128i load(__m128i *v) {
7 #if TSAN_VECTORIZE
8   return _mm_load_si128(v);
9 #else
10   return *v;
11 #endif
12 }
13 
store(__m128i * v,__m128i a)14 void store(__m128i *v, __m128i a) {
15 #if TSAN_VECTORIZE
16   _mm_store_si128(v, a);
17 #else
18   *v = a;
19 #endif
20 }
21 
22 void *Thread(void *arg);
23 
main()24 int main() {
25   barrier_init(&barrier, 2);
26   pthread_t th;
27   pthread_create(&th, NULL, Thread, NULL);
28   barrier_wait(&barrier);
29 
30   print_address("addr0:", 2, &data[0], &data[0]);
31   auto v0 = load(&data[1]);
32   store(&data[0], v0);
33   // CHECK: addr0:[[ADDR0_0:0x[0-9,a-f]+]] [[ADDR0_1:0x[0-9,a-f]+]]
34   // CHECK: WARNING: ThreadSanitizer: data race
35   // CHECK:   Write of size 8 at [[ADDR0_0]] by main thread:
36   // CHECK:   Previous read of size 8 at [[ADDR0_1]] by thread T1:
37 
38   print_address("addr1:", 2, (char *)&data[2] + 8, (char *)&data[2] + 8);
39   ((volatile unsigned long long *)(&data[2]))[1] = 42;
40   // CHECK: addr1:[[ADDR1_0:0x[0-9,a-f]+]] [[ADDR1_1:0x[0-9,a-f]+]]
41   // CHECK: WARNING: ThreadSanitizer: data race
42   // CHECK:   Write of size 8 at [[ADDR1_0]] by main thread:
43   // CHECK:   Previous read of size 8 at [[ADDR1_1]] by thread T1:
44 
45   print_address("addr2:", 2, (char *)&data[4] + 15, (char *)&data[4] + 8);
46   ((volatile char *)(&data[4]))[15] = 42;
47   // CHECK: addr2:[[ADDR2_0:0x[0-9,a-f]+]] [[ADDR2_1:0x[0-9,a-f]+]]
48   // CHECK: WARNING: ThreadSanitizer: data race
49   // CHECK:   Write of size 1 at [[ADDR2_0]] by main thread:
50   // CHECK:   Previous read of size 8 at [[ADDR2_1]] by thread T1:
51 
52   store(&data[12], v0);
53   ((volatile unsigned long long *)(&data[14]))[1] = 42;
54   ((volatile char *)(&data[16]))[15] = 42;
55   barrier_wait(&barrier);
56   pthread_join(th, NULL);
57   return 0;
58 }
59 
Thread(void * arg)60 void *Thread(void *arg) {
61   // Use only even indexes so that compiler does not insert memcpy.
62   auto v0 = load(&data[0]);
63   auto v1 = load(&data[2]);
64   auto v2 = load(&data[4]);
65   store(&data[6], v0);
66   store(&data[8], v1);
67   store(&data[10], v2);
68   barrier_wait(&barrier);
69   barrier_wait(&barrier);
70 
71   print_address("addr3:", 2, &data[12], &data[12]);
72   store(&data[12], v0);
73   // CHECK: addr3:[[ADDR3_0:0x[0-9,a-f]+]] [[ADDR3_1:0x[0-9,a-f]+]]
74   // CHECK: WARNING: ThreadSanitizer: data race
75   // CHECK:   Write of size 8 at [[ADDR3_0]] by thread T1:
76   // CHECK:   Previous write of size 8 at [[ADDR3_1]] by main thread:
77 
78   print_address("addr4:", 2, (char *)&data[14] + 8, (char *)&data[14] + 8);
79   store(&data[14], v0);
80   // CHECK: addr4:[[ADDR4_0:0x[0-9,a-f]+]] [[ADDR4_1:0x[0-9,a-f]+]]
81   // CHECK: WARNING: ThreadSanitizer: data race
82   // CHECK:   Write of size 8 at [[ADDR4_0]] by thread T1:
83   // CHECK:   Previous write of size 8 at [[ADDR4_1]] by main thread:
84 
85   print_address("addr5:", 2, (char *)&data[16] + 8, (char *)&data[16] + 15);
86   store(&data[16], v0);
87   // CHECK: addr5:[[ADDR5_0:0x[0-9,a-f]+]] [[ADDR5_1:0x[0-9,a-f]+]]
88   // CHECK: WARNING: ThreadSanitizer: data race
89   // CHECK:   Write of size 8 at [[ADDR5_0]] by thread T1:
90   // CHECK:   Previous write of size 1 at [[ADDR5_1]] by main thread:
91   return NULL;
92 }
93