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
14void store(__m128i *v, __m128i a) {
15#if TSAN_VECTORIZE
16 _mm_store_si128(v, a);
17#else
18 *v = a;
19#endif
20}
21
22void *Thread(void *arg);
23
24int 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
60void *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

source code of compiler-rt/test/tsan/vector_race.cpp