[Alignment][NFC] Instructions::getLoadStoreAlignment
[llvm-complete.git] / test / Instrumentation / MemorySanitizer / PowerPC / vararg-ppc64.ll
blob9e74752bcd50900dc9984a68af17a5357a2f9ee0
1 ; RUN: opt < %s -S -passes=msan 2>&1 | FileCheck %s
2 ; RUN: opt < %s -msan -S | FileCheck %s
4 target datalayout = "E-m:e-i64:64-n32:64"
5 target triple = "powerpc64--linux"
7 define i32 @foo(i32 %guard, ...) {
8   %vl = alloca i8*, align 8
9   %1 = bitcast i8** %vl to i8*
10   call void @llvm.lifetime.start.p0i8(i64 32, i8* %1)
11   call void @llvm.va_start(i8* %1)
12   call void @llvm.va_end(i8* %1)
13   call void @llvm.lifetime.end.p0i8(i64 32, i8* %1)
14   ret i32 0
17 ; First, check allocation of the save area.
19 ; CHECK-LABEL: @foo
20 ; CHECK: [[A:%.*]] = load {{.*}} @__msan_va_arg_overflow_size_tls
21 ; CHECK: [[B:%.*]] = add i64 0, [[A]]
22 ; CHECK: [[C:%.*]] = alloca {{.*}} [[B]]
24 ; CHECK: [[STACK:%.*]] = bitcast {{.*}} @__msan_va_arg_tls to i8*
25 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[C]], i8* align 8 [[STACK]], i64 [[B]], i1 false)
27 declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
28 declare void @llvm.va_start(i8*) #2
29 declare void @llvm.va_end(i8*) #2
30 declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
32 define i32 @bar() {
33   %1 = call i32 (i32, ...) @foo(i32 0, i32 1, i64 2, double 3.000000e+00)
34   ret i32 %1
37 ; Save the incoming shadow value from the arguments in the __msan_va_arg_tls
38 ; array.  The first argument is stored at position 4, since it's right
39 ; justified.
40 ; CHECK-LABEL: @bar
41 ; CHECK: store i32 0, i32* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 4) to i32*), align 8
42 ; CHECK: store i64 0, i64* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 8) to i64*), align 8
43 ; CHECK: store i64 0, i64* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 16) to i64*), align 8
44 ; CHECK: store {{.*}} 24, {{.*}} @__msan_va_arg_overflow_size_tls
46 ; Check vector argument.
47 define i32 @bar2() {
48   %1 = call i32 (i32, ...) @foo(i32 0, <2 x i64> <i64 1, i64 2>)
49   ret i32 %1
52 ; The vector is at offset 16 of parameter save area, but __msan_va_arg_tls
53 ; corresponds to offset 8+ of parameter save area - so the offset from
54 ; __msan_va_arg_tls is actually misaligned.
55 ; CHECK-LABEL: @bar2
56 ; CHECK: store <2 x i64> zeroinitializer, <2 x i64>* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 8) to <2 x i64>*), align 8
57 ; CHECK: store {{.*}} 24, {{.*}} @__msan_va_arg_overflow_size_tls
59 ; Check QPX vector argument.
60 define i32 @bar3() "target-features"="+qpx" {
61   %1 = call i32 (i32, ...) @foo(i32 0, i32 1, i32 2, <4 x double> <double 1.0, double 2.0, double 3.0, double 4.0>)
62   ret i32 %1
65 ; That one is even stranger: the parameter save area starts at offset 48 from
66 ; (32-byte aligned) stack pointer, the vector parameter is at 96 bytes from
67 ; the stack pointer, so its offset from parameter save area is misaligned.
68 ; CHECK-LABEL: @bar3
69 ; CHECK: store i32 0, i32* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 4) to i32*), align 8
70 ; CHECK: store i32 0, i32* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 12) to i32*), align 8
71 ; CHECK: store <4 x i64> zeroinitializer, <4 x i64>* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 40) to <4 x i64>*), align 8
72 ; CHECK: store {{.*}} 72, {{.*}} @__msan_va_arg_overflow_size_tls
74 ; Check i64 array.
75 define i32 @bar4() {
76   %1 = call i32 (i32, ...) @foo(i32 0, [2 x i64] [i64 1, i64 2])
77   ret i32 %1
80 ; CHECK-LABEL: @bar4
81 ; CHECK: store [2 x i64] zeroinitializer, [2 x i64]* bitcast ([100 x i64]* @__msan_va_arg_tls to [2 x i64]*), align 8
82 ; CHECK: store {{.*}} 16, {{.*}} @__msan_va_arg_overflow_size_tls
84 ; Check i128 array.
85 define i32 @bar5() {
86   %1 = call i32 (i32, ...) @foo(i32 0, [2 x i128] [i128 1, i128 2])
87   ret i32 %1
90 ; CHECK-LABEL: @bar5
91 ; CHECK: store [2 x i128] zeroinitializer, [2 x i128]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 8) to [2 x i128]*), align 8
92 ; CHECK: store {{.*}} 40, {{.*}} @__msan_va_arg_overflow_size_tls
94 ; Check 8-aligned byval.
95 define i32 @bar6([2 x i64]* %arg) {
96   %1 = call i32 (i32, ...) @foo(i32 0, [2 x i64]* byval align 8 %arg)
97   ret i32 %1
100 ; CHECK-LABEL: @bar6
101 ; CHECK: [[SHADOW:%[0-9]+]] = bitcast [2 x i64]* bitcast ([100 x i64]* @__msan_va_arg_tls to [2 x i64]*) to i8*
102 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[SHADOW]], i8* align 8 {{.*}}, i64 16, i1 false)
103 ; CHECK: store {{.*}} 16, {{.*}} @__msan_va_arg_overflow_size_tls
105 ; Check 16-aligned byval.
106 define i32 @bar7([4 x i64]* %arg) {
107   %1 = call i32 (i32, ...) @foo(i32 0, [4 x i64]* byval align 16 %arg)
108   ret i32 %1
111 ; CHECK-LABEL: @bar7
112 ; CHECK: [[SHADOW:%[0-9]+]] = bitcast [4 x i64]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 8) to [4 x i64]*)
113 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 8 [[SHADOW]], i8* align 8 {{.*}}, i64 32, i1 false)
114 ; CHECK: store {{.*}} 40, {{.*}} @__msan_va_arg_overflow_size_tls
117 ; Test that MSan doesn't generate code overflowing __msan_va_arg_tls when too many arguments are
118 ; passed to a variadic function.
119 define dso_local i64 @many_args() {
120 entry:
121   %ret = call i64 (i64, ...) @sum(i64 120,
122     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
123     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
124     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
125     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
126     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
127     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
128     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
129     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
130     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
131     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
132     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1,
133     i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1, i64 1
134   )
135   ret i64 %ret
138 ; If the size of __msan_va_arg_tls changes the second argument of `add` must also be changed.
139 ; CHECK-LABEL: @many_args
140 ; CHECK: i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 792)
141 ; CHECK-NOT: i64 add (i64 ptrtoint ([100 x i64]* @__msan_va_arg_tls to i64), i64 800)
142 declare i64 @sum(i64 %n, ...)