[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / Instrumentation / MemorySanitizer / msan_kernel_basic.ll
blob870e7768cc622c68c5347ed1b2fe265db9ede72a
1 ; KMSAN instrumentation tests
2 ; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s             \
3 ; RUN: -check-prefixes=CHECK
4 ; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck %s -check-prefixes=CHECK
6 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"
7 target triple = "x86_64-unknown-linux-gnu"
9 ; Check the instrumentation prologue.
10 define void @Empty() nounwind uwtable sanitize_memory {
11 entry:
12   ret void
15 ; CHECK-LABEL: @Empty
16 ; CHECK: entry:
17 ; CHECK: @__msan_get_context_state()
18 ; %param_shadow:
19 ; CHECK: getelementptr {{.*}} i32 0, i32 0
20 ; %retval_shadow:
21 ; CHECK: getelementptr {{.*}} i32 0, i32 1
22 ; %va_arg_shadow:
23 ; CHECK: getelementptr {{.*}} i32 0, i32 2
24 ; %va_arg_origin:
25 ; CHECK: getelementptr {{.*}} i32 0, i32 3
26 ; %va_arg_overflow_size:
27 ; CHECK: getelementptr {{.*}} i32 0, i32 4
28 ; %param_origin:
29 ; CHECK: getelementptr {{.*}} i32 0, i32 5
30 ; %retval_origin:
31 ; CHECK: getelementptr {{.*}} i32 0, i32 6
32 ; CHECK: entry.split:
34 ; Check instrumentation of stores
36 define void @Store1(i8* nocapture %p, i8 %x) nounwind uwtable sanitize_memory {
37 entry:
38   store i8 %x, i8* %p
39   ret void
42 ; CHECK-LABEL: @Store1
43 ; CHECK: entry:
44 ; CHECK: @__msan_get_context_state()
45 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
46 ; CHECK: entry.split:
47 ; CHECK: [[BASE2:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
48 ; CHECK: [[BASE:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
49 ; CHECK: [[SHADOW:%[a-z0-9_]+]] = inttoptr {{.*}} [[BASE]]
50 ; Load the shadow of %p and check it
51 ; CHECK: load i64, i64* [[SHADOW]]
52 ; CHECK: icmp
53 ; CHECK: br i1
54 ; CHECK: {{^[0-9]+}}:
55 ; CHECK: @__msan_metadata_ptr_for_store_1(i8* %p)
56 ; CHECK: store i8
57 ; If the new shadow is non-zero, jump to __msan_chain_origin()
58 ; CHECK: icmp
59 ; CHECK: br i1
60 ; CHECK: {{^[0-9]+}}:
61 ; CHECK: @__msan_chain_origin
62 ; Storing origin here:
63 ; CHECK: store i32
64 ; CHECK: br label
65 ; CHECK: {{^[0-9]+}}:
66 ; CHECK: store i8
67 ; CHECK: ret void
69 define void @Store2(i16* nocapture %p, i16 %x) nounwind uwtable sanitize_memory {
70 entry:
71   store i16 %x, i16* %p
72   ret void
75 ; CHECK-LABEL: @Store2
76 ; CHECK: entry:
77 ; CHECK: @__msan_get_context_state()
78 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
79 ; CHECK: entry.split:
80 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
81 ; Load the shadow of %p and check it
82 ; CHECK: load i64
83 ; CHECK: icmp
84 ; CHECK: br i1
85 ; CHECK: {{^[0-9]+}}:
86 ; CHECK: [[REG:%[0-9]+]] = bitcast i16* %p to i8*
87 ; CHECK: @__msan_metadata_ptr_for_store_2(i8* [[REG]])
88 ; CHECK: store i16
89 ; If the new shadow is non-zero, jump to __msan_chain_origin()
90 ; CHECK: icmp
91 ; CHECK: br i1
92 ; CHECK: {{^[0-9]+}}:
93 ; CHECK: @__msan_chain_origin
94 ; Storing origin here:
95 ; CHECK: store i32
96 ; CHECK: br label
97 ; CHECK: {{^[0-9]+}}:
98 ; CHECK: store i16
99 ; CHECK: ret void
102 define void @Store4(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory {
103 entry:
104   store i32 %x, i32* %p
105   ret void
108 ; CHECK-LABEL: @Store4
109 ; CHECK: entry:
110 ; CHECK: @__msan_get_context_state()
111 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
112 ; CHECK: entry.split:
113 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
114 ; Load the shadow of %p and check it
115 ; CHECK: load i32
116 ; CHECK: icmp
117 ; CHECK: br i1
118 ; CHECK: {{^[0-9]+}}:
119 ; CHECK: [[REG:%[0-9]+]] = bitcast i32* %p to i8*
120 ; CHECK: @__msan_metadata_ptr_for_store_4(i8* [[REG]])
121 ; CHECK: store i32
122 ; If the new shadow is non-zero, jump to __msan_chain_origin()
123 ; CHECK: icmp
124 ; CHECK: br i1
125 ; CHECK: {{^[0-9]+}}:
126 ; CHECK: @__msan_chain_origin
127 ; Storing origin here:
128 ; CHECK: store i32
129 ; CHECK: br label
130 ; CHECK: {{^[0-9]+}}:
131 ; CHECK: store i32
132 ; CHECK: ret void
134 define void @Store8(i64* nocapture %p, i64 %x) nounwind uwtable sanitize_memory {
135 entry:
136   store i64 %x, i64* %p
137   ret void
140 ; CHECK-LABEL: @Store8
141 ; CHECK: entry:
142 ; CHECK: @__msan_get_context_state()
143 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
144 ; CHECK: entry.split:
145 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
146 ; Load the shadow of %p and check it
147 ; CHECK: load i64
148 ; CHECK: icmp
149 ; CHECK: br i1
150 ; CHECK: {{^[0-9]+}}:
151 ; CHECK: [[REG:%[0-9]+]] = bitcast i64* %p to i8*
152 ; CHECK: @__msan_metadata_ptr_for_store_8(i8* [[REG]])
153 ; CHECK: store i64
154 ; If the new shadow is non-zero, jump to __msan_chain_origin()
155 ; CHECK: icmp
156 ; CHECK: br i1
157 ; CHECK: {{^[0-9]+}}:
158 ; CHECK: @__msan_chain_origin
159 ; Storing origin here:
160 ; CHECK: store i32
161 ; CHECK: br label
162 ; CHECK: {{^[0-9]+}}:
163 ; CHECK: store i64
164 ; CHECK: ret void
166 define void @Store16(i128* nocapture %p, i128 %x) nounwind uwtable sanitize_memory {
167 entry:
168   store i128 %x, i128* %p
169   ret void
172 ; CHECK-LABEL: @Store16
173 ; CHECK: entry:
174 ; CHECK: @__msan_get_context_state()
175 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
176 ; CHECK: entry.split:
177 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
178 ; Load the shadow of %p and check it
179 ; CHECK: load i64
180 ; CHECK: icmp
181 ; CHECK: br i1
182 ; CHECK: {{^[0-9]+}}:
183 ; CHECK: [[REG:%[0-9]+]] = bitcast i128* %p to i8*
184 ; CHECK: @__msan_metadata_ptr_for_store_n(i8* [[REG]], i64 16)
185 ; CHECK: store i128
186 ; If the new shadow is non-zero, jump to __msan_chain_origin()
187 ; CHECK: icmp
188 ; CHECK: br i1
189 ; CHECK: {{^[0-9]+}}:
190 ; CHECK: @__msan_chain_origin
191 ; Storing origin here:
192 ; CHECK: store i32
193 ; CHECK: br label
194 ; CHECK: {{^[0-9]+}}:
195 ; CHECK: store i128
196 ; CHECK: ret void
199 ; Check instrumentation of loads
201 define i8 @Load1(i8* nocapture %p) nounwind uwtable sanitize_memory {
202 entry:
203   %0 = load i8, i8* %p
204   ret i8 %0
207 ; CHECK-LABEL: @Load1
208 ; CHECK: entry:
209 ; CHECK: @__msan_get_context_state()
210 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
211 ; CHECK: entry.split:
212 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
213 ; Load the shadow of %p and check it
214 ; CHECK: load i64
215 ; CHECK: icmp
216 ; CHECK: br i1
217 ; CHECK: {{^[0-9]+}}:
218 ; Load the value from %p. This is done before accessing the shadow
219 ; to ease atomic handling.
220 ; CHECK: load i8
221 ; CHECK: @__msan_metadata_ptr_for_load_1(i8* %p)
222 ; Load the shadow and origin.
223 ; CHECK: load i8
224 ; CHECK: load i32
227 define i16 @Load2(i16* nocapture %p) nounwind uwtable sanitize_memory {
228 entry:
229   %0 = load i16, i16* %p
230   ret i16 %0
233 ; CHECK-LABEL: @Load2
234 ; CHECK: entry:
235 ; CHECK: @__msan_get_context_state()
236 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
237 ; CHECK: entry.split:
238 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
239 ; Load the shadow of %p and check it
240 ; CHECK: load i64
241 ; CHECK: icmp
242 ; CHECK: br i1
243 ; CHECK: {{^[0-9]+}}:
244 ; Load the value from %p. This is done before accessing the shadow
245 ; to ease atomic handling.
246 ; CHECK: load i16
247 ; CHECK: [[REG:%[0-9]+]] = bitcast i16* %p to i8*
248 ; CHECK: @__msan_metadata_ptr_for_load_2(i8* [[REG]])
249 ; Load the shadow and origin.
250 ; CHECK: load i16
251 ; CHECK: load i32
254 define i32 @Load4(i32* nocapture %p) nounwind uwtable sanitize_memory {
255 entry:
256   %0 = load i32, i32* %p
257   ret i32 %0
260 ; CHECK-LABEL: @Load4
261 ; CHECK: entry:
262 ; CHECK: @__msan_get_context_state()
263 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
264 ; CHECK: entry.split:
265 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
266 ; Load the shadow of %p and check it
267 ; CHECK: load i64
268 ; CHECK: icmp
269 ; CHECK: br i1
270 ; CHECK: {{^[0-9]+}}:
271 ; Load the value from %p. This is done before accessing the shadow
272 ; to ease atomic handling.
273 ; CHECK: load i32
274 ; CHECK: [[REG:%[0-9]+]] = bitcast i32* %p to i8*
275 ; CHECK: @__msan_metadata_ptr_for_load_4(i8* [[REG]])
276 ; Load the shadow and origin.
277 ; CHECK: load i32
278 ; CHECK: load i32
280 define i64 @Load8(i64* nocapture %p) nounwind uwtable sanitize_memory {
281 entry:
282   %0 = load i64, i64* %p
283   ret i64 %0
286 ; CHECK-LABEL: @Load8
287 ; CHECK: entry:
288 ; CHECK: @__msan_get_context_state()
289 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
290 ; CHECK: entry.split:
291 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
292 ; Load the shadow of %p and check it
293 ; CHECK: load i64
294 ; CHECK: icmp
295 ; CHECK: br i1
296 ; CHECK: {{^[0-9]+}}:
297 ; Load the value from %p. This is done before accessing the shadow
298 ; to ease atomic handling.
299 ; CHECK: load i64
300 ; CHECK: [[REG:%[0-9]+]] = bitcast i64* %p to i8*
301 ; CHECK: @__msan_metadata_ptr_for_load_8(i8* [[REG]])
302 ; Load the shadow and origin.
303 ; CHECK: load i64
304 ; CHECK: load i32
306 define i128 @Load16(i128* nocapture %p) nounwind uwtable sanitize_memory {
307 entry:
308   %0 = load i128, i128* %p
309   ret i128 %0
312 ; CHECK-LABEL: @Load16
313 ; CHECK: entry:
314 ; CHECK: @__msan_get_context_state()
315 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
316 ; CHECK: entry.split:
317 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
318 ; Load the shadow of %p and check it
319 ; CHECK: load i64
320 ; CHECK: icmp
321 ; CHECK: br i1
322 ; CHECK: {{^[0-9]+}}:
323 ; Load the value from %p. This is done before accessing the shadow
324 ; to ease atomic handling.
325 ; CHECK: load i128
326 ; CHECK: [[REG:%[0-9]+]] = bitcast i128* %p to i8*
327 ; CHECK: @__msan_metadata_ptr_for_load_n(i8* [[REG]], i64 16)
328 ; Load the shadow and origin.
329 ; CHECK: load i128
330 ; CHECK: load i32
333 ; Test kernel-specific va_list instrumentation
335 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
336 declare void @llvm.va_start(i8*) nounwind
337 declare void @llvm.va_end(i8*)
338 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
339 declare dso_local i32 @VAListFn(i8*, %struct.__va_list_tag*) local_unnamed_addr
341 ; Function Attrs: nounwind uwtable
342 define dso_local i32 @VarArgFn(i8* %fmt, ...) local_unnamed_addr sanitize_memory #0 {
343 entry:
344   %args = alloca [1 x %struct.__va_list_tag], align 16
345   %0 = bitcast [1 x %struct.__va_list_tag]* %args to i8*
346   %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag], [1 x %struct.__va_list_tag]* %args, i64 0, i64 0
347   call void @llvm.va_start(i8* nonnull %0)
348   %call = call i32 @VAListFn(i8* %fmt, %struct.__va_list_tag* nonnull %arraydecay)
349   call void @llvm.va_end(i8* nonnull %0)
350   ret i32 %call
353 ; Kernel is built without SSE support.
354 attributes #0 = { "target-features"="+fxsr,+x87,-sse" }
356 ; CHECK-LABEL: @VarArgFn
357 ; CHECK: @__msan_get_context_state()
358 ; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2
359 ; CHECK: [[VA_ARG_ORIGIN:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 3
360 ; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4
362 ; CHECK: entry.split:
363 ; CHECK: [[OSIZE:%[0-9]+]] = load i64, i64* [[VA_ARG_OVERFLOW_SIZE]]
364 ; Register save area is 48 bytes for non-SSE builds.
365 ; CHECK: [[SIZE:%[0-9]+]] = add i64 48, [[OSIZE]]
366 ; CHECK: [[SHADOWS:%[0-9]+]] = alloca i8, i64 [[SIZE]]
367 ; CHECK: [[VA_ARG_SHADOW]]
368 ; CHECK: call void @llvm.memcpy{{.*}}(i8* align 8 [[SHADOWS]], {{.*}}, i64 [[SIZE]]
369 ; CHECK: [[ORIGINS:%[0-9]+]] = alloca i8, i64 [[SIZE]]
370 ; CHECK: [[VA_ARG_ORIGIN]]
371 ; CHECK: call void @llvm.memcpy{{.*}}(i8* align 8 [[ORIGINS]], {{.*}}, i64 [[SIZE]]
372 ; CHECK: call i32 @VAListFn
374 ; Function Attrs: nounwind uwtable
375 define dso_local void @VarArgCaller() local_unnamed_addr sanitize_memory {
376 entry:
377   %call = tail call i32 (i8*, ...) @VarArgFn(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 123)
378   ret void
381 ; CHECK-LABEL: @VarArgCaller
383 ; CHECK: entry:
384 ; CHECK: @__msan_get_context_state()
385 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
386 ; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2
387 ; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4
389 ; CHECK: entry.split:
390 ; CHECK: [[PARAM_SI:%[_a-z0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
391 ; CHECK: [[ARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[PARAM_SI]] to i64*
392 ; First argument is initialized
393 ; CHECK: store i64 0, i64* [[ARG1_S]]
395 ; Dangling cast of va_arg_shadow[0], unused because the first argument is fixed.
396 ; CHECK: [[VA_CAST0:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64
398 ; CHECK: [[VA_CAST1:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64
399 ; CHECK: [[ARG1_SI:%[_a-z0-9]+]] = add i64 [[VA_CAST1]], 8
400 ; CHECK: [[PARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[ARG1_SI]] to i32*
402 ; Shadow for 123 is 0.
403 ; CHECK: store i32 0, i32* [[ARG1_S]]
405 ; CHECK: store i64 0, i64* [[VA_ARG_OVERFLOW_SIZE]]
406 ; CHECK: call i32 (i8*, ...) @VarArgFn({{.*}} @.str{{.*}} i32 123)