[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / llvm / test / Instrumentation / MemorySanitizer / msan_kernel_basic.ll
blob309921bfc352b6836b3fbddcb984287f106527eb
1 ; KMSAN instrumentation tests
2 ; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s             \
3 ; RUN: -check-prefixes=CHECK
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"
8 ; Check the instrumentation prologue.
9 define void @Empty() nounwind uwtable sanitize_memory {
10 entry:
11   ret void
14 ; CHECK-LABEL: @Empty
15 ; CHECK: entry:
16 ; CHECK: @__msan_get_context_state()
17 ; %param_shadow:
18 ; CHECK: getelementptr {{.*}} i32 0, i32 0
19 ; %retval_shadow:
20 ; CHECK: getelementptr {{.*}} i32 0, i32 1
21 ; %va_arg_shadow:
22 ; CHECK: getelementptr {{.*}} i32 0, i32 2
23 ; %va_arg_origin:
24 ; CHECK: getelementptr {{.*}} i32 0, i32 3
25 ; %va_arg_overflow_size:
26 ; CHECK: getelementptr {{.*}} i32 0, i32 4
27 ; %param_origin:
28 ; CHECK: getelementptr {{.*}} i32 0, i32 5
29 ; %retval_origin:
30 ; CHECK: getelementptr {{.*}} i32 0, i32 6
32 ; Check instrumentation of stores
34 define void @Store1(ptr nocapture %p, i8 %x) nounwind uwtable sanitize_memory {
35 entry:
36   store i8 %x, ptr %p
37   ret void
40 ; CHECK-LABEL: @Store1
41 ; CHECK: entry:
42 ; CHECK: @__msan_get_context_state()
43 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
44 ; CHECK: [[BASE:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
45 ; CHECK: [[SHADOW_PTR:%[a-z0-9_]+]] = inttoptr {{.*}} [[BASE]]
46 ; CHECK: [[SHADOW:%[a-z0-9]+]] = load i64, ptr [[SHADOW_PTR]]
47 ; CHECK: [[BASE2:%[0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
48 ; Load the shadow of %p and check it
49 ; CHECK: icmp ne i64 [[SHADOW]]
50 ; CHECK: br i1
51 ; CHECK: {{^[0-9]+}}:
52 ; CHECK: @__msan_metadata_ptr_for_store_1(ptr %p)
53 ; CHECK: store i8
54 ; If the new shadow is non-zero, jump to __msan_chain_origin()
55 ; CHECK: icmp
56 ; CHECK: br i1
57 ; CHECK: {{^[0-9]+}}:
58 ; CHECK: @__msan_chain_origin
59 ; Storing origin here:
60 ; CHECK: store i32
61 ; CHECK: br label
62 ; CHECK: {{^[0-9]+}}:
63 ; CHECK: store i8
64 ; CHECK: ret void
66 define void @Store2(ptr nocapture %p, i16 %x) nounwind uwtable sanitize_memory {
67 entry:
68   store i16 %x, ptr %p
69   ret void
72 ; CHECK-LABEL: @Store2
73 ; CHECK: entry:
74 ; CHECK: @__msan_get_context_state()
75 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
76 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
77 ; Load the shadow of %p and check it
78 ; CHECK: load i64
79 ; CHECK: icmp
80 ; CHECK: br i1
81 ; CHECK: {{^[0-9]+}}:
82 ; CHECK: @__msan_metadata_ptr_for_store_2(ptr %p)
83 ; CHECK: store i16
84 ; If the new shadow is non-zero, jump to __msan_chain_origin()
85 ; CHECK: icmp
86 ; CHECK: br i1
87 ; CHECK: {{^[0-9]+}}:
88 ; CHECK: @__msan_chain_origin
89 ; Storing origin here:
90 ; CHECK: store i32
91 ; CHECK: br label
92 ; CHECK: {{^[0-9]+}}:
93 ; CHECK: store i16
94 ; CHECK: ret void
97 define void @Store4(ptr nocapture %p, i32 %x) nounwind uwtable sanitize_memory {
98 entry:
99   store i32 %x, ptr %p
100   ret void
103 ; CHECK-LABEL: @Store4
104 ; CHECK: entry:
105 ; CHECK: @__msan_get_context_state()
106 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
107 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
108 ; Load the shadow of %p and check it
109 ; CHECK: load i32
110 ; CHECK: icmp
111 ; CHECK: br i1
112 ; CHECK: {{^[0-9]+}}:
113 ; CHECK: @__msan_metadata_ptr_for_store_4(ptr %p)
114 ; CHECK: store i32
115 ; If the new shadow is non-zero, jump to __msan_chain_origin()
116 ; CHECK: icmp
117 ; CHECK: br i1
118 ; CHECK: {{^[0-9]+}}:
119 ; CHECK: @__msan_chain_origin
120 ; Storing origin here:
121 ; CHECK: store i32
122 ; CHECK: br label
123 ; CHECK: {{^[0-9]+}}:
124 ; CHECK: store i32
125 ; CHECK: ret void
127 define void @Store8(ptr nocapture %p, i64 %x) nounwind uwtable sanitize_memory {
128 entry:
129   store i64 %x, ptr %p
130   ret void
133 ; CHECK-LABEL: @Store8
134 ; CHECK: entry:
135 ; CHECK: @__msan_get_context_state()
136 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
137 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
138 ; Load the shadow of %p and check it
139 ; CHECK: load i64
140 ; CHECK: icmp
141 ; CHECK: br i1
142 ; CHECK: {{^[0-9]+}}:
143 ; CHECK: @__msan_metadata_ptr_for_store_8(ptr %p)
144 ; CHECK: store i64
145 ; If the new shadow is non-zero, jump to __msan_chain_origin()
146 ; CHECK: icmp
147 ; CHECK: br i1
148 ; CHECK: {{^[0-9]+}}:
149 ; CHECK: @__msan_chain_origin
150 ; Storing origin here:
151 ; CHECK: store i64
152 ; CHECK: br label
153 ; CHECK: {{^[0-9]+}}:
154 ; CHECK: store i64
155 ; CHECK: ret void
157 define void @Store16(ptr nocapture %p, i128 %x) nounwind uwtable sanitize_memory {
158 entry:
159   store i128 %x, ptr %p
160   ret void
163 ; CHECK-LABEL: @Store16
164 ; CHECK: entry:
165 ; CHECK: @__msan_get_context_state()
166 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
167 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
168 ; Load the shadow of %p and check it
169 ; CHECK: load i64
170 ; CHECK: icmp
171 ; CHECK: br i1
172 ; CHECK: {{^[0-9]+}}:
173 ; CHECK: @__msan_metadata_ptr_for_store_n(ptr %p, i64 16)
174 ; CHECK: store i128
175 ; If the new shadow is non-zero, jump to __msan_chain_origin()
176 ; CHECK: icmp
177 ; CHECK: br i1
178 ; CHECK: {{^[0-9]+}}:
179 ; CHECK: @__msan_chain_origin
180 ; Storing origin here:
181 ; CHECK: store i64
182 ; CHECK: br label
183 ; CHECK: {{^[0-9]+}}:
184 ; CHECK: store i128
185 ; CHECK: ret void
188 ; Check instrumentation of loads
190 define i8 @Load1(ptr nocapture %p) nounwind uwtable sanitize_memory {
191 entry:
192   %0 = load i8, ptr %p
193   ret i8 %0
196 ; CHECK-LABEL: @Load1
197 ; CHECK: entry:
198 ; CHECK: @__msan_get_context_state()
199 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
200 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
201 ; Load the shadow of %p and check it
202 ; CHECK: load i64
203 ; CHECK: icmp
204 ; CHECK: br i1
205 ; CHECK: {{^[0-9]+}}:
206 ; Load the value from %p. This is done before accessing the shadow
207 ; to ease atomic handling.
208 ; CHECK: load i8
209 ; CHECK: @__msan_metadata_ptr_for_load_1(ptr %p)
210 ; Load the shadow and origin.
211 ; CHECK: load i8
212 ; CHECK: load i32
215 define i16 @Load2(ptr nocapture %p) nounwind uwtable sanitize_memory {
216 entry:
217   %0 = load i16, ptr %p
218   ret i16 %0
221 ; CHECK-LABEL: @Load2
222 ; CHECK: entry:
223 ; CHECK: @__msan_get_context_state()
224 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
225 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
226 ; Load the shadow of %p and check it
227 ; CHECK: load i64
228 ; CHECK: icmp
229 ; CHECK: br i1
230 ; CHECK: {{^[0-9]+}}:
231 ; Load the value from %p. This is done before accessing the shadow
232 ; to ease atomic handling.
233 ; CHECK: load i16
234 ; CHECK: @__msan_metadata_ptr_for_load_2(ptr %p)
235 ; Load the shadow and origin.
236 ; CHECK: load i16
237 ; CHECK: load i32
240 define i32 @Load4(ptr nocapture %p) nounwind uwtable sanitize_memory {
241 entry:
242   %0 = load i32, ptr %p
243   ret i32 %0
246 ; CHECK-LABEL: @Load4
247 ; CHECK: entry:
248 ; CHECK: @__msan_get_context_state()
249 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
250 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
251 ; Load the shadow of %p and check it
252 ; CHECK: load i64
253 ; CHECK: icmp
254 ; CHECK: br i1
255 ; CHECK: {{^[0-9]+}}:
256 ; Load the value from %p. This is done before accessing the shadow
257 ; to ease atomic handling.
258 ; CHECK: load i32
259 ; CHECK: @__msan_metadata_ptr_for_load_4(ptr %p)
260 ; Load the shadow and origin.
261 ; CHECK: load i32
262 ; CHECK: load i32
264 define i64 @Load8(ptr nocapture %p) nounwind uwtable sanitize_memory {
265 entry:
266   %0 = load i64, ptr %p
267   ret i64 %0
270 ; CHECK-LABEL: @Load8
271 ; CHECK: entry:
272 ; CHECK: @__msan_get_context_state()
273 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
274 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
275 ; Load the shadow of %p and check it
276 ; CHECK: load i64
277 ; CHECK: icmp
278 ; CHECK: br i1
279 ; CHECK: {{^[0-9]+}}:
280 ; Load the value from %p. This is done before accessing the shadow
281 ; to ease atomic handling.
282 ; CHECK: load i64
283 ; CHECK: @__msan_metadata_ptr_for_load_8(ptr %p)
284 ; Load the shadow and origin.
285 ; CHECK: load i64
286 ; CHECK: load i32
288 define i128 @Load16(ptr nocapture %p) nounwind uwtable sanitize_memory {
289 entry:
290   %0 = load i128, ptr %p
291   ret i128 %0
294 ; CHECK-LABEL: @Load16
295 ; CHECK: entry:
296 ; CHECK: @__msan_get_context_state()
297 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
298 ; CHECK: ptrtoint {{.*}} [[PARAM_SHADOW]]
299 ; Load the shadow of %p and check it
300 ; CHECK: load i64
301 ; CHECK: icmp
302 ; CHECK: br i1
303 ; CHECK: {{^[0-9]+}}:
304 ; Load the value from %p. This is done before accessing the shadow
305 ; to ease atomic handling.
306 ; CHECK: load i128
307 ; CHECK: @__msan_metadata_ptr_for_load_n(ptr %p, i64 16)
308 ; Load the shadow and origin.
309 ; CHECK: load i128
310 ; CHECK: load i32
313 ; Test kernel-specific va_list instrumentation
315 %struct.__va_list_tag = type { i32, i32, ptr, ptr }
316 declare void @llvm.va_start(ptr) nounwind
317 declare void @llvm.va_end(ptr)
318 @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
319 declare dso_local i32 @VAListFn(ptr, ptr) local_unnamed_addr
321 ; Function Attrs: nounwind uwtable
322 define dso_local i32 @VarArgFn(ptr %fmt, ...) local_unnamed_addr sanitize_memory #0 {
323 entry:
324   %args = alloca [1 x %struct.__va_list_tag], align 16
325   call void @llvm.va_start(ptr nonnull %args)
326   %call = call i32 @VAListFn(ptr %fmt, ptr nonnull %args)
327   call void @llvm.va_end(ptr nonnull %args)
328   ret i32 %call
331 ; Kernel is built without SSE support.
332 attributes #0 = { "target-features"="+fxsr,+x87,-sse" }
334 ; CHECK-LABEL: @VarArgFn
335 ; CHECK: @__msan_get_context_state()
336 ; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2
337 ; CHECK: [[VA_ARG_ORIGIN:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 3
338 ; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4
340 ; CHECK: [[OSIZE:%[0-9]+]] = load i64, ptr [[VA_ARG_OVERFLOW_SIZE]]
341 ; Register save area is 48 bytes for non-SSE builds.
342 ; CHECK: [[SIZE:%[0-9]+]] = add i64 48, [[OSIZE]]
343 ; CHECK: [[SHADOWS:%[0-9]+]] = alloca i8, i64 [[SIZE]]
344 ; CHECK: call void @llvm.memset{{.*}}(ptr align 8 [[SHADOWS]], i8 0, i64 [[SIZE]], i1 false)
345 ; CHECK: [[COPYSZ:%[0-9]+]] = call i64 @llvm.umin.i64(i64 [[SIZE]], i64 800)
346 ; CHECK: call void @llvm.memcpy{{.*}}(ptr align 8 [[SHADOWS]], ptr align 8 [[VA_ARG_SHADOW]], i64 [[COPYSZ]]
347 ; CHECK: [[ORIGINS:%[0-9]+]] = alloca i8, i64 [[SIZE]]
348 ; CHECK: call void @llvm.memcpy{{.*}}(ptr align 8 [[ORIGINS]], ptr align 8 [[VA_ARG_ORIGIN]], i64 [[COPYSZ]]
349 ; CHECK: call i32 @VAListFn
351 ; Function Attrs: nounwind uwtable
352 define dso_local void @VarArgCaller() local_unnamed_addr sanitize_memory {
353 entry:
354   %call = tail call i32 (ptr, ...) @VarArgFn(ptr @.str, i32 123)
355   ret void
358 ; CHECK-LABEL: @VarArgCaller
360 ; CHECK: entry:
361 ; CHECK: @__msan_get_context_state()
362 ; CHECK: [[PARAM_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 0
363 ; CHECK: [[VA_ARG_SHADOW:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 2
364 ; CHECK: [[VA_ARG_OVERFLOW_SIZE:%[a-z0-9_]+]] = getelementptr {{.*}} i32 0, i32 4
366 ; CHECK: [[PARAM_SI:%[_a-z0-9]+]] = ptrtoint {{.*}} [[PARAM_SHADOW]]
367 ; CHECK: [[ARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[PARAM_SI]] to ptr
368 ; First argument is initialized
369 ; CHECK: store i64 0, ptr [[ARG1_S]]
371 ; Dangling cast of va_arg_shadow[0], unused because the first argument is fixed.
372 ; CHECK: [[VA_CAST0:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64
374 ; CHECK: [[VA_CAST1:%[_a-z0-9]+]] = ptrtoint {{.*}} [[VA_ARG_SHADOW]] to i64
375 ; CHECK: [[ARG1_SI:%[_a-z0-9]+]] = add i64 [[VA_CAST1]], 8
376 ; CHECK: [[PARG1_S:%[_a-z0-9]+]] = inttoptr i64 [[ARG1_SI]] to ptr
378 ; Shadow for 123 is 0.
379 ; CHECK: store i32 0, ptr [[ARG1_S]]
381 ; CHECK: store i64 0, ptr [[VA_ARG_OVERFLOW_SIZE]]
382 ; CHECK: call i32 (ptr, ...) @VarArgFn({{.*}} @.str{{.*}} i32 123)