• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck  \
2; RUN: %s "--check-prefixes=CHECK,INLINE"
3; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s --check-prefixes=CHECK,INLINE
4; RUN: opt < %s -msan-check-access-address=0 -msan-poison-stack-with-call=1 -S \
5; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,CALL"
6; RUN: opt < %s -msan -msan-check-access-address=0 -msan-poison-stack-with-call=1 -S | FileCheck %s --check-prefixes=CHECK,CALL
7; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=1 -S          \
8; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN"
9; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,ORIGIN
10; RUN: opt < %s -msan-check-access-address=0 -msan-track-origins=2 -S          \
11; RUN: -passes=msan 2>&1 | FileCheck %s "--check-prefixes=CHECK,ORIGIN"
12; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s --check-prefixes=CHECK,ORIGIN
13; RUN: opt < %s -S -passes="msan<kernel>" 2>&1 | FileCheck %s             \
14; RUN: "--check-prefixes=CHECK,KMSAN"
15; RUN: opt < %s -msan-kernel=1 -S -passes=msan 2>&1 | FileCheck %s             \
16; RUN: "--check-prefixes=CHECK,KMSAN"
17; RUN: opt < %s -msan -msan-kernel=1 -S | FileCheck %s --check-prefixes=CHECK,KMSAN
18
19target 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"
20target triple = "x86_64-unknown-linux-gnu"
21
22define void @static() sanitize_memory {
23entry:
24  %x = alloca i32, align 4
25  ret void
26}
27
28; CHECK-LABEL: define void @static(
29; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
30; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
31; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
32; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
33; CHECK: ret void
34
35
36define void @dynamic() sanitize_memory {
37entry:
38  br label %l
39l:
40  %x = alloca i32, align 4
41  ret void
42}
43
44; CHECK-LABEL: define void @dynamic(
45; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
46; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
47; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
48; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
49; CHECK: ret void
50
51define void @array() sanitize_memory {
52entry:
53  %x = alloca i32, i64 5, align 4
54  ret void
55}
56
57; CHECK-LABEL: define void @array(
58; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 20, i1 false)
59; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 20)
60; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 20,
61; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 20,
62; CHECK: ret void
63
64define void @array_non_const(i64 %cnt) sanitize_memory {
65entry:
66  %x = alloca i32, i64 %cnt, align 4
67  ret void
68}
69
70; CHECK-LABEL: define void @array_non_const(
71; CHECK: %[[A:.*]] = mul i64 4, %cnt
72; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 %[[A]], i1 false)
73; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 %[[A]])
74; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 %[[A]],
75; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 %[[A]],
76; CHECK: ret void
77
78; Check that the local is unpoisoned in the absence of sanitize_memory
79define void @unpoison_local() {
80entry:
81  %x = alloca i32, i64 5, align 4
82  ret void
83}
84
85; CHECK-LABEL: define void @unpoison_local(
86; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 0, i64 20, i1 false)
87; CALL: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 0, i64 20, i1 false)
88; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 20,
89; KMSAN: call void @__msan_unpoison_alloca(i8* {{.*}}, i64 20)
90; CHECK: ret void
91
92; Check that every llvm.lifetime.start() causes poisoning of locals.
93define void @lifetime_start() sanitize_memory {
94entry:
95  %x = alloca i32, align 4
96  %c = bitcast i32* %x to i8*
97  br label %another_bb
98
99another_bb:
100  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %c)
101  store i32 7, i32* %x
102  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %c)
103  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %c)
104  store i32 8, i32* %x
105  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %c)
106  ret void
107}
108
109; CHECK-LABEL: define void @lifetime_start(
110; CHECK-LABEL: entry:
111; CHECK: %x = alloca i32
112; CHECK-LABEL: another_bb:
113
114; CHECK: call void @llvm.lifetime.start
115; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
116; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
117; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
118; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
119
120; CHECK: call void @llvm.lifetime.start
121; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
122; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
123; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
124; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
125; CHECK: ret void
126
127; Make sure variable-length arrays are handled correctly.
128define void @lifetime_start_var(i64 %cnt) sanitize_memory {
129entry:
130  %x = alloca i32, i64 %cnt, align 4
131  %c = bitcast i32* %x to i8*
132  call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %c)
133  call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %c)
134  ret void
135}
136
137; CHECK-LABEL: define void @lifetime_start_var(
138; CHECK-LABEL: entry:
139; CHECK: %x = alloca i32, i64 %cnt
140; CHECK: call void @llvm.lifetime.start
141; CHECK: %[[A:.*]] = mul i64 4, %cnt
142; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 %[[A]], i1 false)
143; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 %[[A]])
144; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 %[[A]],
145; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 %[[A]],
146; CHECK: call void @llvm.lifetime.end
147; CHECK: ret void
148
149
150; If we can't trace one of the lifetime markers to a single alloca, fall back
151; to poisoning allocas at the beginning of the function.
152; Each alloca must be poisoned only once.
153define void @lifetime_no_alloca(i8 %v) sanitize_memory {
154entry:
155  %x = alloca i32, align 4
156  %y = alloca i32, align 4
157  %z = alloca i32, align 4
158  %cx = bitcast i32* %x to i8*
159  %cy = bitcast i32* %y to i8*
160  %cz = bitcast i32* %z to i8*
161  %tobool = icmp eq i8 %v, 0
162  %xy = select i1 %tobool, i32* %x, i32* %y
163  %cxcy = select i1 %tobool, i8* %cx, i8* %cy
164  br label %another_bb
165
166another_bb:
167  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %cz)
168  store i32 7, i32* %z
169  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %cz)
170  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %cz)
171  store i32 7, i32* %z
172  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %cz)
173  call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %cxcy)
174  store i32 8, i32* %xy
175  call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %cxcy)
176  ret void
177}
178
179; CHECK-LABEL: define void @lifetime_no_alloca(
180; CHECK-LABEL: entry:
181; CHECK: %x = alloca i32
182; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
183; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
184; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
185; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
186; CHECK: %y = alloca i32
187; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
188; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
189; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
190; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
191; CHECK: %z = alloca i32
192; INLINE: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
193; CALL: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
194; ORIGIN: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
195; KMSAN: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
196
197; There're two lifetime intrinsics for %z, but we must instrument it only once.
198; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
199; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
200; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
201; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
202; CHECK-LABEL: another_bb:
203
204; CHECK: call void @llvm.lifetime.start
205; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
206; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
207; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
208; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
209; CHECK: call void @llvm.lifetime.end
210; CHECK: call void @llvm.lifetime.start
211; INLINE-NOT: call void @llvm.memset.p0i8.i64(i8* align 4 {{.*}}, i8 -1, i64 4, i1 false)
212; CALL-NOT: call void @__msan_poison_stack(i8* {{.*}}, i64 4)
213; ORIGIN-NOT: call void @__msan_set_alloca_origin4(i8* {{.*}}, i64 4,
214; KMSAN-NOT: call void @__msan_poison_alloca(i8* {{.*}}, i64 4,
215; CHECK: call void @llvm.lifetime.end
216
217
218
219declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
220declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
221