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