74d9670d5946ad2f7cffd682458903c130ae16e9
[oota-llvm.git] / test / Instrumentation / MemorySanitizer / msan_basic.ll
1 ; RUN: opt < %s -msan -S | FileCheck %s
2 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"
3
4 ; Check the presence of __msan_init
5 ; CHECK: @llvm.global_ctors {{.*}} @__msan_init
6
7 ; load followed by cmp: check that we load the shadow and call __msan_warning.
8 define void @LoadAndCmp(i32* nocapture %a) nounwind uwtable {
9 entry:
10   %0 = load i32* %a, align 4
11   %tobool = icmp eq i32 %0, 0
12   br i1 %tobool, label %if.end, label %if.then
13
14 if.then:                                          ; preds = %entry
15   tail call void (...)* @foo() nounwind
16   br label %if.end
17
18 if.end:                                           ; preds = %entry, %if.then
19   ret void
20 }
21
22 declare void @foo(...)
23
24 ; CHECK: define void @LoadAndCmp
25 ; CHECK: = load
26 ; CHECK: = load
27 ; CHECK: call void @__msan_warning_noreturn()
28 ; CHECK: }
29
30 ; Check that we store the shadow for the retval.
31 define i32 @ReturnInt() nounwind uwtable readnone {
32 entry:
33   ret i32 123
34 }
35
36 ; CHECK: define i32 @ReturnInt()
37 ; CHECK: store i32 0,{{.*}}__msan_retval_tls
38 ; CHECK: }
39
40 ; Check that we get the shadow for the retval.
41 define void @CopyRetVal(i32* nocapture %a) nounwind uwtable {
42 entry:
43   %call = tail call i32 @ReturnInt() nounwind
44   store i32 %call, i32* %a, align 4
45   ret void
46 }
47
48 ; CHECK: define void @CopyRetVal
49 ; CHECK: load{{.*}}__msan_retval_tls
50 ; CHECK: store
51 ; CHECK: store
52 ; CHECK: }
53
54
55 ; Check that we generate PHIs for shadow.
56 define void @FuncWithPhi(i32* nocapture %a, i32* %b, i32* nocapture %c) nounwind uwtable {
57 entry:
58   %tobool = icmp eq i32* %b, null
59   br i1 %tobool, label %if.else, label %if.then
60
61   if.then:                                          ; preds = %entry
62   %0 = load i32* %b, align 4
63   br label %if.end
64
65   if.else:                                          ; preds = %entry
66   %1 = load i32* %c, align 4
67   br label %if.end
68
69   if.end:                                           ; preds = %if.else, %if.then
70   %t.0 = phi i32 [ %0, %if.then ], [ %1, %if.else ]
71   store i32 %t.0, i32* %a, align 4
72   ret void
73 }
74
75 ; CHECK: define void @FuncWithPhi
76 ; CHECK: = phi
77 ; CHECK-NEXT: = phi
78 ; CHECK: store
79 ; CHECK: store
80 ; CHECK: }
81
82 ; Compute shadow for "x << 10"
83 define void @ShlConst(i32* nocapture %x) nounwind uwtable {
84 entry:
85   %0 = load i32* %x, align 4
86   %1 = shl i32 %0, 10
87   store i32 %1, i32* %x, align 4
88   ret void
89 }
90
91 ; CHECK: define void @ShlConst
92 ; CHECK: = load
93 ; CHECK: = load
94 ; CHECK: shl
95 ; CHECK: shl
96 ; CHECK: store
97 ; CHECK: store
98 ; CHECK: }
99
100 ; Compute shadow for "10 << x": it should have 'sext i1'.
101 define void @ShlNonConst(i32* nocapture %x) nounwind uwtable {
102 entry:
103   %0 = load i32* %x, align 4
104   %1 = shl i32 10, %0
105   store i32 %1, i32* %x, align 4
106   ret void
107 }
108
109 ; CHECK: define void @ShlNonConst
110 ; CHECK: = load
111 ; CHECK: = load
112 ; CHECK: = sext i1
113 ; CHECK: store
114 ; CHECK: store
115 ; CHECK: }
116
117 ; SExt
118 define void @SExt(i32* nocapture %a, i16* nocapture %b) nounwind uwtable {
119 entry:
120   %0 = load i16* %b, align 2
121   %1 = sext i16 %0 to i32
122   store i32 %1, i32* %a, align 4
123   ret void
124 }
125
126 ; CHECK: define void @SExt
127 ; CHECK: = load
128 ; CHECK: = load
129 ; CHECK: = sext
130 ; CHECK: = sext
131 ; CHECK: store
132 ; CHECK: store
133 ; CHECK: }
134
135
136 ; memset
137 define void @MemSet(i8* nocapture %x) nounwind uwtable {
138 entry:
139   call void @llvm.memset.p0i8.i64(i8* %x, i8 42, i64 10, i32 1, i1 false)
140   ret void
141 }
142
143 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
144
145 ; CHECK: define void @MemSet
146 ; CHECK: call i8* @__msan_memset
147 ; CHECK: }
148
149
150 ; memcpy
151 define void @MemCpy(i8* nocapture %x, i8* nocapture %y) nounwind uwtable {
152 entry:
153   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %x, i8* %y, i64 10, i32 1, i1 false)
154   ret void
155 }
156
157 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
158
159 ; CHECK: define void @MemCpy
160 ; CHECK: call i8* @__msan_memcpy
161 ; CHECK: }
162
163
164 ; memmove is lowered to a call
165 define void @MemMove(i8* nocapture %x, i8* nocapture %y) nounwind uwtable {
166 entry:
167   call void @llvm.memmove.p0i8.p0i8.i64(i8* %x, i8* %y, i64 10, i32 1, i1 false)
168   ret void
169 }
170
171 declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
172
173 ; CHECK: define void @MemMove
174 ; CHECK: call i8* @__msan_memmove
175 ; CHECK: }
176
177
178 ; Check that we propagate shadow for "select"
179
180 define i32 @Select(i32 %a, i32 %b, i32 %c) nounwind uwtable readnone {
181 entry:
182   %tobool = icmp ne i32 %c, 0
183   %cond = select i1 %tobool, i32 %a, i32 %b
184   ret i32 %cond
185 }
186
187 ; CHECK: define i32 @Select
188 ; CHECK: select
189 ; CHECK-NEXT: select
190 ; CHECK: }
191
192
193 define i8* @IntToPtr(i64 %x) nounwind uwtable readnone {
194 entry:
195   %0 = inttoptr i64 %x to i8*
196   ret i8* %0
197 }
198
199 ; CHECK: define i8* @IntToPtr
200 ; CHECK: load i64*{{.*}}__msan_param_tls
201 ; CHECK-NEXT: inttoptr
202 ; CHECK-NEXT: store i64{{.*}}__msan_retval_tls
203 ; CHECK: }
204
205
206 define i8* @IntToPtr_ZExt(i16 %x) nounwind uwtable readnone {
207 entry:
208   %0 = inttoptr i16 %x to i8*
209   ret i8* %0
210 }
211
212 ; CHECK: define i8* @IntToPtr_ZExt
213 ; CHECK: zext
214 ; CHECK-NEXT: inttoptr
215 ; CHECK: }
216
217
218 ; Check that we insert exactly one check on udiv
219 ; (2nd arg shadow is checked, 1st arg shadow is propagated)
220
221 define i32 @Div(i32 %a, i32 %b) nounwind uwtable readnone {
222 entry:
223   %div = udiv i32 %a, %b
224   ret i32 %div
225 }
226
227 ; CHECK: define i32 @Div
228 ; CHECK: icmp
229 ; CHECK: br
230 ; CHECK-NOT: icmp
231 ; CHECK: udiv
232 ; CHECK-NOT: icmp
233 ; CHECK: }