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 | |
6 | __m128i load(__m128i *v) { |
7 | #if TSAN_VECTORIZE |
8 | return _mm_load_si128(v); |
9 | #else |
10 | return *v; |
11 | #endif |
12 | } |
13 | |
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 | |
24 | int main() { |
25 | barrier_init(barrier: &barrier, count: 2); |
26 | pthread_t th; |
27 | pthread_create(newthread: &th, NULL, start_routine: Thread, NULL); |
28 | barrier_wait(barrier: &barrier); |
29 | |
30 | print_address("addr0:" , 2, &data[0], &data[0]); |
31 | auto v0 = load(v: &data[1]); |
32 | store(v: &data[0], a: 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(v: &data[12], a: v0); |
53 | ((volatile unsigned long long *)(&data[14]))[1] = 42; |
54 | ((volatile char *)(&data[16]))[15] = 42; |
55 | barrier_wait(barrier: &barrier); |
56 | pthread_join(th: th, NULL); |
57 | return 0; |
58 | } |
59 | |
60 | void *Thread(void *arg) { |
61 | // Use only even indexes so that compiler does not insert memcpy. |
62 | auto v0 = load(v: &data[0]); |
63 | auto v1 = load(v: &data[2]); |
64 | auto v2 = load(v: &data[4]); |
65 | store(v: &data[6], a: v0); |
66 | store(v: &data[8], a: v1); |
67 | store(v: &data[10], a: v2); |
68 | barrier_wait(barrier: &barrier); |
69 | barrier_wait(barrier: &barrier); |
70 | |
71 | print_address("addr3:" , 2, &data[12], &data[12]); |
72 | store(v: &data[12], a: 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(v: &data[14], a: 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(v: &data[16], a: 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 | |