Merging r259696:
[oota-llvm.git] / test / Instrumentation / MemorySanitizer / atomics.ll
1 ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s
2 ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s
3 ; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s
4
5 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-linux-gnu"
7
8 ; atomicrmw xchg: store clean shadow, return clean shadow
9
10 define i32 @AtomicRmwXchg(i32* %p, i32 %x) sanitize_memory {
11 entry:
12   %0 = atomicrmw xchg i32* %p, i32 %x seq_cst
13   ret i32 %0
14 }
15
16 ; CHECK-LABEL: @AtomicRmwXchg
17 ; CHECK: store i32 0,
18 ; CHECK: atomicrmw xchg {{.*}} seq_cst
19 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
20 ; CHECK: ret i32
21
22
23 ; atomicrmw max: exactly the same as above
24
25 define i32 @AtomicRmwMax(i32* %p, i32 %x) sanitize_memory {
26 entry:
27   %0 = atomicrmw max i32* %p, i32 %x seq_cst
28   ret i32 %0
29 }
30
31 ; CHECK-LABEL: @AtomicRmwMax
32 ; CHECK: store i32 0,
33 ; CHECK: atomicrmw max {{.*}} seq_cst
34 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
35 ; CHECK: ret i32
36
37
38 ; cmpxchg: the same as above, but also check %a shadow
39
40 define i32 @Cmpxchg(i32* %p, i32 %a, i32 %b) sanitize_memory {
41 entry:
42   %pair = cmpxchg i32* %p, i32 %a, i32 %b seq_cst seq_cst
43   %0 = extractvalue { i32, i1 } %pair, 0
44   ret i32 %0
45 }
46
47 ; CHECK-LABEL: @Cmpxchg
48 ; CHECK: store { i32, i1 } zeroinitializer,
49 ; CHECK: icmp
50 ; CHECK: br
51 ; CHECK: @__msan_warning
52 ; CHECK: cmpxchg {{.*}} seq_cst seq_cst
53 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
54 ; CHECK: ret i32
55
56
57 ; relaxed cmpxchg: bump up to "release monotonic"
58
59 define i32 @CmpxchgMonotonic(i32* %p, i32 %a, i32 %b) sanitize_memory {
60 entry:
61   %pair = cmpxchg i32* %p, i32 %a, i32 %b monotonic monotonic
62   %0 = extractvalue { i32, i1 } %pair, 0
63   ret i32 %0
64 }
65
66 ; CHECK-LABEL: @CmpxchgMonotonic
67 ; CHECK: store { i32, i1 } zeroinitializer,
68 ; CHECK: icmp
69 ; CHECK: br
70 ; CHECK: @__msan_warning
71 ; CHECK: cmpxchg {{.*}} release monotonic
72 ; CHECK: store i32 0, {{.*}} @__msan_retval_tls
73 ; CHECK: ret i32
74
75
76 ; atomic load: preserve alignment, load shadow value after app value
77
78 define i32 @AtomicLoad(i32* %p) sanitize_memory {
79 entry:
80   %0 = load atomic i32, i32* %p seq_cst, align 16
81   ret i32 %0
82 }
83
84 ; CHECK-LABEL: @AtomicLoad
85 ; CHECK: load atomic i32, i32* {{.*}} seq_cst, align 16
86 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
87 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
88 ; CHECK: ret i32
89
90
91 ; atomic load: preserve alignment, load shadow value after app value
92
93 define i32 @AtomicLoadAcquire(i32* %p) sanitize_memory {
94 entry:
95   %0 = load atomic i32, i32* %p acquire, align 16
96   ret i32 %0
97 }
98
99 ; CHECK-LABEL: @AtomicLoadAcquire
100 ; CHECK: load atomic i32, i32* {{.*}} acquire, align 16
101 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
102 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
103 ; CHECK: ret i32
104
105
106 ; atomic load monotonic: bump up to load acquire
107
108 define i32 @AtomicLoadMonotonic(i32* %p) sanitize_memory {
109 entry:
110   %0 = load atomic i32, i32* %p monotonic, align 16
111   ret i32 %0
112 }
113
114 ; CHECK-LABEL: @AtomicLoadMonotonic
115 ; CHECK: load atomic i32, i32* {{.*}} acquire, align 16
116 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
117 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
118 ; CHECK: ret i32
119
120
121 ; atomic load unordered: bump up to load acquire
122
123 define i32 @AtomicLoadUnordered(i32* %p) sanitize_memory {
124 entry:
125   %0 = load atomic i32, i32* %p unordered, align 16
126   ret i32 %0
127 }
128
129 ; CHECK-LABEL: @AtomicLoadUnordered
130 ; CHECK: load atomic i32, i32* {{.*}} acquire, align 16
131 ; CHECK: [[SHADOW:%[01-9a-z_]+]] = load i32, i32* {{.*}}, align 16
132 ; CHECK: store i32 {{.*}}[[SHADOW]], {{.*}} @__msan_retval_tls
133 ; CHECK: ret i32
134
135
136 ; atomic store: preserve alignment, store clean shadow value before app value
137
138 define void @AtomicStore(i32* %p, i32 %x) sanitize_memory {
139 entry:
140   store atomic i32 %x, i32* %p seq_cst, align 16
141   ret void
142 }
143
144 ; CHECK-LABEL: @AtomicStore
145 ; CHECK-NOT: @__msan_param_tls
146 ; CHECK: store i32 0, i32* {{.*}}, align 16
147 ; CHECK: store atomic i32 %x, i32* %p seq_cst, align 16
148 ; CHECK: ret void
149
150
151 ; atomic store: preserve alignment, store clean shadow value before app value
152
153 define void @AtomicStoreRelease(i32* %p, i32 %x) sanitize_memory {
154 entry:
155   store atomic i32 %x, i32* %p release, align 16
156   ret void
157 }
158
159 ; CHECK-LABEL: @AtomicStoreRelease
160 ; CHECK-NOT: @__msan_param_tls
161 ; CHECK: store i32 0, i32* {{.*}}, align 16
162 ; CHECK: store atomic i32 %x, i32* %p release, align 16
163 ; CHECK: ret void
164
165
166 ; atomic store monotonic: bumped up to store release
167
168 define void @AtomicStoreMonotonic(i32* %p, i32 %x) sanitize_memory {
169 entry:
170   store atomic i32 %x, i32* %p monotonic, align 16
171   ret void
172 }
173
174 ; CHECK-LABEL: @AtomicStoreMonotonic
175 ; CHECK-NOT: @__msan_param_tls
176 ; CHECK: store i32 0, i32* {{.*}}, align 16
177 ; CHECK: store atomic i32 %x, i32* %p release, align 16
178 ; CHECK: ret void
179
180
181 ; atomic store unordered: bumped up to store release
182
183 define void @AtomicStoreUnordered(i32* %p, i32 %x) sanitize_memory {
184 entry:
185   store atomic i32 %x, i32* %p unordered, align 16
186   ret void
187 }
188
189 ; CHECK-LABEL: @AtomicStoreUnordered
190 ; CHECK-NOT: @__msan_param_tls
191 ; CHECK: store i32 0, i32* {{.*}}, align 16
192 ; CHECK: store atomic i32 %x, i32* %p release, align 16
193 ; CHECK: ret void