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