OSDN Git Service

[msan] Fix handling of scalar select of vectors.
[android-x86/external-llvm.git] / test / Instrumentation / MemorySanitizer / msan_basic.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 -check-prefix=CHECK-ORIGINS %s
3 ; RUN: opt < %s -msan -msan-check-access-address=1 -S | FileCheck %s -check-prefix=CHECK-AA
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 ; Check the presence of __msan_init
9 ; CHECK: @llvm.global_ctors {{.*}} @__msan_init
10
11 ; Check the presence and the linkage type of __msan_track_origins and
12 ; other interface symbols.
13 ; CHECK-NOT: @__msan_track_origins
14 ; CHECK-ORIGINS: @__msan_track_origins = weak_odr constant i32 1
15 ; CHECK-NOT: @__msan_keep_going = weak_odr constant i32 0
16 ; CHECK: @__msan_retval_tls = external thread_local(initialexec) global [{{.*}}]
17 ; CHECK: @__msan_retval_origin_tls = external thread_local(initialexec) global i32
18 ; CHECK: @__msan_param_tls = external thread_local(initialexec) global [{{.*}}]
19 ; CHECK: @__msan_param_origin_tls = external thread_local(initialexec) global [{{.*}}]
20 ; CHECK: @__msan_va_arg_tls = external thread_local(initialexec) global [{{.*}}]
21 ; CHECK: @__msan_va_arg_overflow_size_tls = external thread_local(initialexec) global i64
22 ; CHECK: @__msan_origin_tls = external thread_local(initialexec) global i32
23
24
25 ; Check instrumentation of stores
26
27 define void @Store(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory {
28 entry:
29   store i32 %x, i32* %p, align 4
30   ret void
31 }
32
33 ; CHECK: @Store
34 ; CHECK: load {{.*}} @__msan_param_tls
35 ; CHECK: store
36 ; CHECK: store
37 ; CHECK: ret void
38 ; CHECK-ORIGINS: @Store
39 ; CHECK-ORIGINS: load {{.*}} @__msan_param_tls
40 ; CHECK-ORIGINS: store
41 ; CHECK-ORIGINS: icmp
42 ; CHECK-ORIGINS: br i1
43 ; CHECK-ORIGINS: <label>
44 ; CHECK-ORIGINS: store
45 ; CHECK-ORIGINS: br label
46 ; CHECK-ORIGINS: <label>
47 ; CHECK-ORIGINS: store
48 ; CHECK-ORIGINS: ret void
49
50
51 ; Check instrumentation of aligned stores
52 ; Shadow store has the same alignment as the original store; origin store
53 ; does not specify explicit alignment.
54
55 define void @AlignedStore(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory {
56 entry:
57   store i32 %x, i32* %p, align 32
58   ret void
59 }
60
61 ; CHECK: @AlignedStore
62 ; CHECK: load {{.*}} @__msan_param_tls
63 ; CHECK: store {{.*}} align 32
64 ; CHECK: store {{.*}} align 32
65 ; CHECK: ret void
66 ; CHECK-ORIGINS: @AlignedStore
67 ; CHECK-ORIGINS: load {{.*}} @__msan_param_tls
68 ; CHECK-ORIGINS: store {{.*}} align 32
69 ; CHECK-ORIGINS: icmp
70 ; CHECK-ORIGINS: br i1
71 ; CHECK-ORIGINS: <label>
72 ; CHECK-ORIGINS: store {{.*}} align 32
73 ; CHECK-ORIGINS: br label
74 ; CHECK-ORIGINS: <label>
75 ; CHECK-ORIGINS: store {{.*}} align 32
76 ; CHECK-ORIGINS: ret void
77
78
79 ; load followed by cmp: check that we load the shadow and call __msan_warning.
80 define void @LoadAndCmp(i32* nocapture %a) nounwind uwtable sanitize_memory {
81 entry:
82   %0 = load i32* %a, align 4
83   %tobool = icmp eq i32 %0, 0
84   br i1 %tobool, label %if.end, label %if.then
85
86 if.then:                                          ; preds = %entry
87   tail call void (...)* @foo() nounwind
88   br label %if.end
89
90 if.end:                                           ; preds = %entry, %if.then
91   ret void
92 }
93
94 declare void @foo(...)
95
96 ; CHECK: @LoadAndCmp
97 ; CHECK: = load
98 ; CHECK: = load
99 ; CHECK: call void @__msan_warning_noreturn()
100 ; CHECK-NEXT: call void asm sideeffect
101 ; CHECK-NEXT: unreachable
102 ; CHECK: ret void
103
104 ; Check that we store the shadow for the retval.
105 define i32 @ReturnInt() nounwind uwtable readnone sanitize_memory {
106 entry:
107   ret i32 123
108 }
109
110 ; CHECK: @ReturnInt
111 ; CHECK: store i32 0,{{.*}}__msan_retval_tls
112 ; CHECK: ret i32
113
114 ; Check that we get the shadow for the retval.
115 define void @CopyRetVal(i32* nocapture %a) nounwind uwtable sanitize_memory {
116 entry:
117   %call = tail call i32 @ReturnInt() nounwind
118   store i32 %call, i32* %a, align 4
119   ret void
120 }
121
122 ; CHECK: @CopyRetVal
123 ; CHECK: load{{.*}}__msan_retval_tls
124 ; CHECK: store
125 ; CHECK: store
126 ; CHECK: ret void
127
128
129 ; Check that we generate PHIs for shadow.
130 define void @FuncWithPhi(i32* nocapture %a, i32* %b, i32* nocapture %c) nounwind uwtable sanitize_memory {
131 entry:
132   %tobool = icmp eq i32* %b, null
133   br i1 %tobool, label %if.else, label %if.then
134
135   if.then:                                          ; preds = %entry
136   %0 = load i32* %b, align 4
137   br label %if.end
138
139   if.else:                                          ; preds = %entry
140   %1 = load i32* %c, align 4
141   br label %if.end
142
143   if.end:                                           ; preds = %if.else, %if.then
144   %t.0 = phi i32 [ %0, %if.then ], [ %1, %if.else ]
145   store i32 %t.0, i32* %a, align 4
146   ret void
147 }
148
149 ; CHECK: @FuncWithPhi
150 ; CHECK: = phi
151 ; CHECK-NEXT: = phi
152 ; CHECK: store
153 ; CHECK: store
154 ; CHECK: ret void
155
156 ; Compute shadow for "x << 10"
157 define void @ShlConst(i32* nocapture %x) nounwind uwtable sanitize_memory {
158 entry:
159   %0 = load i32* %x, align 4
160   %1 = shl i32 %0, 10
161   store i32 %1, i32* %x, align 4
162   ret void
163 }
164
165 ; CHECK: @ShlConst
166 ; CHECK: = load
167 ; CHECK: = load
168 ; CHECK: shl
169 ; CHECK: shl
170 ; CHECK: store
171 ; CHECK: store
172 ; CHECK: ret void
173
174 ; Compute shadow for "10 << x": it should have 'sext i1'.
175 define void @ShlNonConst(i32* nocapture %x) nounwind uwtable sanitize_memory {
176 entry:
177   %0 = load i32* %x, align 4
178   %1 = shl i32 10, %0
179   store i32 %1, i32* %x, align 4
180   ret void
181 }
182
183 ; CHECK: @ShlNonConst
184 ; CHECK: = load
185 ; CHECK: = load
186 ; CHECK: = sext i1
187 ; CHECK: store
188 ; CHECK: store
189 ; CHECK: ret void
190
191 ; SExt
192 define void @SExt(i32* nocapture %a, i16* nocapture %b) nounwind uwtable sanitize_memory {
193 entry:
194   %0 = load i16* %b, align 2
195   %1 = sext i16 %0 to i32
196   store i32 %1, i32* %a, align 4
197   ret void
198 }
199
200 ; CHECK: @SExt
201 ; CHECK: = load
202 ; CHECK: = load
203 ; CHECK: = sext
204 ; CHECK: = sext
205 ; CHECK: store
206 ; CHECK: store
207 ; CHECK: ret void
208
209
210 ; memset
211 define void @MemSet(i8* nocapture %x) nounwind uwtable sanitize_memory {
212 entry:
213   call void @llvm.memset.p0i8.i64(i8* %x, i8 42, i64 10, i32 1, i1 false)
214   ret void
215 }
216
217 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
218
219 ; CHECK: @MemSet
220 ; CHECK: call i8* @__msan_memset
221 ; CHECK: ret void
222
223
224 ; memcpy
225 define void @MemCpy(i8* nocapture %x, i8* nocapture %y) nounwind uwtable sanitize_memory {
226 entry:
227   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x, i8* %y, i64 10, i32 1, i1 false)
228   ret void
229 }
230
231 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
232
233 ; CHECK: @MemCpy
234 ; CHECK: call i8* @__msan_memcpy
235 ; CHECK: ret void
236
237
238 ; memmove is lowered to a call
239 define void @MemMove(i8* nocapture %x, i8* nocapture %y) nounwind uwtable sanitize_memory {
240 entry:
241   call void @llvm.memmove.p0i8.p0i8.i64(i8* %x, i8* %y, i64 10, i32 1, i1 false)
242   ret void
243 }
244
245 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
246
247 ; CHECK: @MemMove
248 ; CHECK: call i8* @__msan_memmove
249 ; CHECK: ret void
250
251
252 ; Check that we propagate shadow for "select"
253
254 define i32 @Select(i32 %a, i32 %b, i32 %c) nounwind uwtable readnone sanitize_memory {
255 entry:
256   %tobool = icmp ne i32 %c, 0
257   %cond = select i1 %tobool, i32 %a, i32 %b
258   ret i32 %cond
259 }
260
261 ; CHECK: @Select
262 ; CHECK: select
263 ; CHECK-NEXT: sext i1 {{.*}} to i32
264 ; CHECK-NEXT: or i32
265 ; CHECK-NEXT: select
266 ; CHECK: ret i32
267
268
269 ; Check that we propagate origin for "select" with vector condition.
270 ; Select condition is flattened to i1, which is then used to select one of the
271 ; argument origins.
272
273 define <8 x i16> @SelectVector(<8 x i16> %a, <8 x i16> %b, <8 x i1> %c) nounwind uwtable readnone sanitize_memory {
274 entry:
275   %cond = select <8 x i1> %c, <8 x i16> %a, <8 x i16> %b
276   ret <8 x i16> %cond
277 }
278
279 ; CHECK: @SelectVector
280 ; CHECK: select <8 x i1>
281 ; CHECK-NEXT: sext <8 x i1> {{.*}} to <8 x i16>
282 ; CHECK-NEXT: or <8 x i16>
283 ; CHECK-NEXT: select <8 x i1>
284 ; CHECK: ret <8 x i16>
285
286 ; CHECK-ORIGINS: @SelectVector
287 ; CHECK-ORIGINS: bitcast <8 x i1> {{.*}} to i8
288 ; CHECK-ORIGINS: icmp ne i8
289 ; CHECK-ORIGINS: select i1
290 ; CHECK-ORIGINS: ret <8 x i16>
291
292
293 ; Check that we propagate origin for "select" with scalar condition and vector
294 ; arguments. Select condition shadow is sign-extended to the vector type and
295 ; mixed into the result shadow.
296
297 define <8 x i16> @SelectVector2(<8 x i16> %a, <8 x i16> %b, i1 %c) nounwind uwtable readnone sanitize_memory {
298 entry:
299   %cond = select i1 %c, <8 x i16> %a, <8 x i16> %b
300   ret <8 x i16> %cond
301 }
302
303 ; CHECK: @SelectVector2
304 ; CHECK: select i1
305 ; CHECK: sext i1 {{.*}} to i128
306 ; CHECK: bitcast i128 {{.*}} to <8 x i16>
307 ; CHECK: or <8 x i16>
308 ; CHECK: select i1
309 ; CHECK: ret <8 x i16>
310
311
312 define { i64, i64 } @SelectStruct(i1 zeroext %x, { i64, i64 } %a, { i64, i64 } %b) readnone sanitize_memory {
313 entry:
314   %c = select i1 %x, { i64, i64 } %a, { i64, i64 } %b
315   ret { i64, i64 } %c
316 }
317
318 ; CHECK: @SelectStruct
319 ; CHECK: select i1 {{.*}}, { i64, i64 }
320 ; CHECK-NEXT: select i1 {{.*}}, { i64, i64 } { i64 -1, i64 -1 }, { i64, i64 }
321 ; CHECK-NEXT: select i1 {{.*}}, { i64, i64 }
322 ; CHECK: ret { i64, i64 }
323
324
325 define i8* @IntToPtr(i64 %x) nounwind uwtable readnone sanitize_memory {
326 entry:
327   %0 = inttoptr i64 %x to i8*
328   ret i8* %0
329 }
330
331 ; CHECK: @IntToPtr
332 ; CHECK: load i64*{{.*}}__msan_param_tls
333 ; CHECK-NEXT: inttoptr
334 ; CHECK-NEXT: store i64{{.*}}__msan_retval_tls
335 ; CHECK: ret i8
336
337
338 define i8* @IntToPtr_ZExt(i16 %x) nounwind uwtable readnone sanitize_memory {
339 entry:
340   %0 = inttoptr i16 %x to i8*
341   ret i8* %0
342 }
343
344 ; CHECK: @IntToPtr_ZExt
345 ; CHECK: zext
346 ; CHECK-NEXT: inttoptr
347 ; CHECK: ret i8
348
349
350 ; Check that we insert exactly one check on udiv
351 ; (2nd arg shadow is checked, 1st arg shadow is propagated)
352
353 define i32 @Div(i32 %a, i32 %b) nounwind uwtable readnone sanitize_memory {
354 entry:
355   %div = udiv i32 %a, %b
356   ret i32 %div
357 }
358
359 ; CHECK: @Div
360 ; CHECK: icmp
361 ; CHECK: call void @__msan_warning
362 ; CHECK-NOT: icmp
363 ; CHECK: udiv
364 ; CHECK-NOT: icmp
365 ; CHECK: ret i32
366
367
368 ; Check that we propagate shadow for x<0, x>=0, etc (i.e. sign bit tests)
369
370 define zeroext i1 @ICmpSLT(i32 %x) nounwind uwtable readnone sanitize_memory {
371   %1 = icmp slt i32 %x, 0
372   ret i1 %1
373 }
374
375 ; CHECK: @ICmpSLT
376 ; CHECK: icmp slt
377 ; CHECK-NOT: call void @__msan_warning
378 ; CHECK: icmp slt
379 ; CHECK-NOT: call void @__msan_warning
380 ; CHECK: ret i1
381
382 define zeroext i1 @ICmpSGE(i32 %x) nounwind uwtable readnone sanitize_memory {
383   %1 = icmp sge i32 %x, 0
384   ret i1 %1
385 }
386
387 ; CHECK: @ICmpSGE
388 ; CHECK: icmp slt
389 ; CHECK-NOT: call void @__msan_warning
390 ; CHECK: icmp sge
391 ; CHECK-NOT: call void @__msan_warning
392 ; CHECK: ret i1
393
394 define zeroext i1 @ICmpSGT(i32 %x) nounwind uwtable readnone sanitize_memory {
395   %1 = icmp sgt i32 0, %x
396   ret i1 %1
397 }
398
399 ; CHECK: @ICmpSGT
400 ; CHECK: icmp slt
401 ; CHECK-NOT: call void @__msan_warning
402 ; CHECK: icmp sgt
403 ; CHECK-NOT: call void @__msan_warning
404 ; CHECK: ret i1
405
406 define zeroext i1 @ICmpSLE(i32 %x) nounwind uwtable readnone sanitize_memory {
407   %1 = icmp sle i32 0, %x
408   ret i1 %1
409 }
410
411 ; CHECK: @ICmpSLE
412 ; CHECK: icmp slt
413 ; CHECK-NOT: call void @__msan_warning
414 ; CHECK: icmp sle
415 ; CHECK-NOT: call void @__msan_warning
416 ; CHECK: ret i1
417
418
419 ; Check that we propagate shadow for x<0, x>=0, etc (i.e. sign bit tests)
420 ; of the vector arguments.
421
422 define <2 x i1> @ICmpSLT_vector(<2 x i32*> %x) nounwind uwtable readnone sanitize_memory {
423   %1 = icmp slt <2 x i32*> %x, zeroinitializer
424   ret <2 x i1> %1
425 }
426
427 ; CHECK: @ICmpSLT_vector
428 ; CHECK: icmp slt <2 x i64>
429 ; CHECK-NOT: call void @__msan_warning
430 ; CHECK: icmp slt <2 x i32*>
431 ; CHECK-NOT: call void @__msan_warning
432 ; CHECK: ret <2 x i1>
433
434
435 ; Check that we propagate shadow for unsigned relational comparisons with
436 ; constants
437
438 define zeroext i1 @ICmpUGTConst(i32 %x) nounwind uwtable readnone sanitize_memory {
439 entry:
440   %cmp = icmp ugt i32 %x, 7
441   ret i1 %cmp
442 }
443
444 ; CHECK: @ICmpUGTConst
445 ; CHECK: icmp ugt i32
446 ; CHECK-NOT: call void @__msan_warning
447 ; CHECK: icmp ugt i32
448 ; CHECK-NOT: call void @__msan_warning
449 ; CHECK: icmp ugt i32
450 ; CHECK-NOT: call void @__msan_warning
451 ; CHECK: ret i1
452
453
454 ; Check that loads of shadow have the same aligment as the original loads.
455 ; Check that loads of origin have the aligment of max(4, original alignment).
456
457 define i32 @ShadowLoadAlignmentLarge() nounwind uwtable sanitize_memory {
458   %y = alloca i32, align 64
459   %1 = load volatile i32* %y, align 64
460   ret i32 %1
461 }
462
463 ; CHECK: @ShadowLoadAlignmentLarge
464 ; CHECK: load volatile i32* {{.*}} align 64
465 ; CHECK: load i32* {{.*}} align 64
466 ; CHECK: ret i32
467
468 define i32 @ShadowLoadAlignmentSmall() nounwind uwtable sanitize_memory {
469   %y = alloca i32, align 2
470   %1 = load volatile i32* %y, align 2
471   ret i32 %1
472 }
473
474 ; CHECK: @ShadowLoadAlignmentSmall
475 ; CHECK: load volatile i32* {{.*}} align 2
476 ; CHECK: load i32* {{.*}} align 2
477 ; CHECK: ret i32
478
479 ; CHECK-ORIGINS: @ShadowLoadAlignmentSmall
480 ; CHECK-ORIGINS: load volatile i32* {{.*}} align 2
481 ; CHECK-ORIGINS: load i32* {{.*}} align 2
482 ; CHECK-ORIGINS: load i32* {{.*}} align 4
483 ; CHECK-ORIGINS: ret i32
484
485
486 ; Test vector manipulation instructions.
487 ; Check that the same bit manipulation is applied to the shadow values.
488 ; Check that there is a zero test of the shadow of %idx argument, where present.
489
490 define i32 @ExtractElement(<4 x i32> %vec, i32 %idx) sanitize_memory {
491   %x = extractelement <4 x i32> %vec, i32 %idx
492   ret i32 %x
493 }
494
495 ; CHECK: @ExtractElement
496 ; CHECK: extractelement
497 ; CHECK: call void @__msan_warning
498 ; CHECK: extractelement
499 ; CHECK: ret i32
500
501 define <4 x i32> @InsertElement(<4 x i32> %vec, i32 %idx, i32 %x) sanitize_memory {
502   %vec1 = insertelement <4 x i32> %vec, i32 %x, i32 %idx
503   ret <4 x i32> %vec1
504 }
505
506 ; CHECK: @InsertElement
507 ; CHECK: insertelement
508 ; CHECK: call void @__msan_warning
509 ; CHECK: insertelement
510 ; CHECK: ret <4 x i32>
511
512 define <4 x i32> @ShuffleVector(<4 x i32> %vec, <4 x i32> %vec1) sanitize_memory {
513   %vec2 = shufflevector <4 x i32> %vec, <4 x i32> %vec1,
514                         <4 x i32> <i32 0, i32 4, i32 1, i32 5>
515   ret <4 x i32> %vec2
516 }
517
518 ; CHECK: @ShuffleVector
519 ; CHECK: shufflevector
520 ; CHECK-NOT: call void @__msan_warning
521 ; CHECK: shufflevector
522 ; CHECK: ret <4 x i32>
523
524
525 ; Test bswap intrinsic instrumentation
526 define i32 @BSwap(i32 %x) nounwind uwtable readnone sanitize_memory {
527   %y = tail call i32 @llvm.bswap.i32(i32 %x)
528   ret i32 %y
529 }
530
531 declare i32 @llvm.bswap.i32(i32) nounwind readnone
532
533 ; CHECK: @BSwap
534 ; CHECK-NOT: call void @__msan_warning
535 ; CHECK: @llvm.bswap.i32
536 ; CHECK-NOT: call void @__msan_warning
537 ; CHECK: @llvm.bswap.i32
538 ; CHECK-NOT: call void @__msan_warning
539 ; CHECK: ret i32
540
541
542 ; Store intrinsic.
543
544 define void @StoreIntrinsic(i8* %p, <4 x float> %x) nounwind uwtable sanitize_memory {
545   call void @llvm.x86.sse.storeu.ps(i8* %p, <4 x float> %x)
546   ret void
547 }
548
549 declare void @llvm.x86.sse.storeu.ps(i8*, <4 x float>) nounwind
550
551 ; CHECK: @StoreIntrinsic
552 ; CHECK-NOT: br
553 ; CHECK-NOT: = or
554 ; CHECK: store <4 x i32> {{.*}} align 1
555 ; CHECK: call void @llvm.x86.sse.storeu.ps
556 ; CHECK: ret void
557
558
559 ; Load intrinsic.
560
561 define <16 x i8> @LoadIntrinsic(i8* %p) nounwind uwtable sanitize_memory {
562   %call = call <16 x i8> @llvm.x86.sse3.ldu.dq(i8* %p)
563   ret <16 x i8> %call
564 }
565
566 declare <16 x i8> @llvm.x86.sse3.ldu.dq(i8* %p) nounwind
567
568 ; CHECK: @LoadIntrinsic
569 ; CHECK: load <16 x i8>* {{.*}} align 1
570 ; CHECK-NOT: br
571 ; CHECK-NOT: = or
572 ; CHECK: call <16 x i8> @llvm.x86.sse3.ldu.dq
573 ; CHECK: store <16 x i8> {{.*}} @__msan_retval_tls
574 ; CHECK: ret <16 x i8>
575
576 ; CHECK-ORIGINS: @LoadIntrinsic
577 ; CHECK-ORIGINS: [[ORIGIN:%[01-9a-z]+]] = load i32* {{.*}}
578 ; CHECK-ORIGINS: call <16 x i8> @llvm.x86.sse3.ldu.dq
579 ; CHECK-ORIGINS: store i32 {{.*}}[[ORIGIN]], i32* @__msan_retval_origin_tls
580 ; CHECK-ORIGINS: ret <16 x i8>
581
582
583 ; Simple NoMem intrinsic
584 ; Check that shadow is OR'ed, and origin is Select'ed
585 ; And no shadow checks!
586
587 define <8 x i16> @Paddsw128(<8 x i16> %a, <8 x i16> %b) nounwind uwtable sanitize_memory {
588   %call = call <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %a, <8 x i16> %b)
589   ret <8 x i16> %call
590 }
591
592 declare <8 x i16> @llvm.x86.sse2.padds.w(<8 x i16> %a, <8 x i16> %b) nounwind
593
594 ; CHECK: @Paddsw128
595 ; CHECK-NEXT: load <8 x i16>* {{.*}} @__msan_param_tls
596 ; CHECK-NEXT: load <8 x i16>* {{.*}} @__msan_param_tls
597 ; CHECK-NEXT: = or <8 x i16>
598 ; CHECK-NEXT: call <8 x i16> @llvm.x86.sse2.padds.w
599 ; CHECK-NEXT: store <8 x i16> {{.*}} @__msan_retval_tls
600 ; CHECK-NEXT: ret <8 x i16>
601
602 ; CHECK-ORIGINS: @Paddsw128
603 ; CHECK-ORIGINS: load i32* {{.*}} @__msan_param_origin_tls
604 ; CHECK-ORIGINS: load i32* {{.*}} @__msan_param_origin_tls
605 ; CHECK-ORIGINS: = bitcast <8 x i16> {{.*}} to i128
606 ; CHECK-ORIGINS-NEXT: = icmp ne i128 {{.*}}, 0
607 ; CHECK-ORIGINS-NEXT: = select i1 {{.*}}, i32 {{.*}}, i32
608 ; CHECK-ORIGINS: call <8 x i16> @llvm.x86.sse2.padds.w
609 ; CHECK-ORIGINS: store i32 {{.*}} @__msan_retval_origin_tls
610 ; CHECK-ORIGINS: ret <8 x i16>
611
612
613 ; Test handling of vectors of pointers.
614 ; Check that shadow of such vector is a vector of integers.
615
616 define <8 x i8*> @VectorOfPointers(<8 x i8*>* %p) nounwind uwtable sanitize_memory {
617   %x = load <8 x i8*>* %p
618   ret <8 x i8*> %x
619 }
620
621 ; CHECK: @VectorOfPointers
622 ; CHECK: load <8 x i8*>*
623 ; CHECK: load <8 x i64>*
624 ; CHECK: store <8 x i64> {{.*}} @__msan_retval_tls
625 ; CHECK: ret <8 x i8*>
626
627 ; Test handling of va_copy.
628
629 declare void @llvm.va_copy(i8*, i8*) nounwind
630
631 define void @VACopy(i8* %p1, i8* %p2) nounwind uwtable sanitize_memory {
632   call void @llvm.va_copy(i8* %p1, i8* %p2) nounwind
633   ret void
634 }
635
636 ; CHECK: @VACopy
637 ; CHECK: call void @llvm.memset.p0i8.i64({{.*}}, i8 0, i64 24, i32 8, i1 false)
638 ; CHECK: ret void
639
640
641 ; Test that va_start instrumentation does not use va_arg_tls*.
642 ; It should work with a local stack copy instead.
643
644 %struct.__va_list_tag = type { i32, i32, i8*, i8* }
645 declare void @llvm.va_start(i8*) nounwind
646
647 ; Function Attrs: nounwind uwtable
648 define void @VAStart(i32 %x, ...) {
649 entry:
650   %x.addr = alloca i32, align 4
651   %va = alloca [1 x %struct.__va_list_tag], align 16
652   store i32 %x, i32* %x.addr, align 4
653   %arraydecay = getelementptr inbounds [1 x %struct.__va_list_tag]* %va, i32 0, i32 0
654   %arraydecay1 = bitcast %struct.__va_list_tag* %arraydecay to i8*
655   call void @llvm.va_start(i8* %arraydecay1)
656   ret void
657 }
658
659 ; CHECK: @VAStart
660 ; CHECK: call void @llvm.va_start
661 ; CHECK-NOT: @__msan_va_arg_tls
662 ; CHECK-NOT: @__msan_va_arg_overflow_size_tls
663 ; CHECK: ret void
664
665
666 ; Test handling of volatile stores.
667 ; Check that MemorySanitizer does not add a check of the value being stored.
668
669 define void @VolatileStore(i32* nocapture %p, i32 %x) nounwind uwtable sanitize_memory {
670 entry:
671   store volatile i32 %x, i32* %p, align 4
672   ret void
673 }
674
675 ; CHECK: @VolatileStore
676 ; CHECK-NOT: @__msan_warning
677 ; CHECK: ret void
678
679
680 ; Test that checks are omitted but shadow propagation is kept if
681 ; sanitize_memory attribute is missing.
682
683 define i32 @NoSanitizeMemory(i32 %x) uwtable {
684 entry:
685   %tobool = icmp eq i32 %x, 0
686   br i1 %tobool, label %if.end, label %if.then
687
688 if.then:                                          ; preds = %entry
689   tail call void @bar()
690   br label %if.end
691
692 if.end:                                           ; preds = %entry, %if.then
693   ret i32 %x
694 }
695
696 declare void @bar()
697
698 ; CHECK: @NoSanitizeMemory
699 ; CHECK-NOT: @__msan_warning
700 ; CHECK: load i32* {{.*}} @__msan_param_tls
701 ; CHECK-NOT: @__msan_warning
702 ; CHECK: store {{.*}} @__msan_retval_tls
703 ; CHECK-NOT: @__msan_warning
704 ; CHECK: ret i32
705
706
707 ; Test that stack allocations are unpoisoned in functions missing
708 ; sanitize_memory attribute
709
710 define i32 @NoSanitizeMemoryAlloca() {
711 entry:
712   %p = alloca i32, align 4
713   %x = call i32 @NoSanitizeMemoryAllocaHelper(i32* %p)
714   ret i32 %x
715 }
716
717 declare i32 @NoSanitizeMemoryAllocaHelper(i32* %p)
718
719 ; CHECK: @NoSanitizeMemoryAlloca
720 ; CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 4, i32 4, i1 false)
721 ; CHECK: call i32 @NoSanitizeMemoryAllocaHelper(i32*
722 ; CHECK: ret i32
723
724
725 ; Test that undef is unpoisoned in functions missing
726 ; sanitize_memory attribute
727
728 define i32 @NoSanitizeMemoryUndef() {
729 entry:
730   %x = call i32 @NoSanitizeMemoryUndefHelper(i32 undef)
731   ret i32 %x
732 }
733
734 declare i32 @NoSanitizeMemoryUndefHelper(i32 %x)
735
736 ; CHECK: @NoSanitizeMemoryAlloca
737 ; CHECK: store i32 0, i32* {{.*}} @__msan_param_tls
738 ; CHECK: call i32 @NoSanitizeMemoryUndefHelper(i32 undef)
739 ; CHECK: ret i32
740
741
742 ; Test argument shadow alignment
743
744 define <2 x i64> @ArgumentShadowAlignment(i64 %a, <2 x i64> %b) sanitize_memory {
745 entry:
746   ret <2 x i64> %b
747 }
748
749 ; CHECK: @ArgumentShadowAlignment
750 ; CHECK: load <2 x i64>* {{.*}} @__msan_param_tls {{.*}}, align 8
751 ; CHECK: store <2 x i64> {{.*}} @__msan_retval_tls {{.*}}, align 8
752 ; CHECK: ret <2 x i64>
753
754
755 ; Test byval argument shadow alignment
756
757 define <2 x i64> @ByValArgumentShadowLargeAlignment(<2 x i64>* byval %p) sanitize_memory {
758 entry:
759   %x = load <2 x i64>* %p
760   ret <2 x i64> %x
761 }
762
763 ; CHECK-AA: @ByValArgumentShadowLargeAlignment
764 ; CHECK-AA: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 16, i32 8, i1 false)
765 ; CHECK-AA: ret <2 x i64>
766
767
768 define i16 @ByValArgumentShadowSmallAlignment(i16* byval %p) sanitize_memory {
769 entry:
770   %x = load i16* %p
771   ret i16 %x
772 }
773
774 ; CHECK-AA: @ByValArgumentShadowSmallAlignment
775 ; CHECK-AA: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{.*}}, i8* {{.*}}, i64 2, i32 2, i1 false)
776 ; CHECK-AA: ret i16
777