[win/asan] GetInstructionSize: Fix `83 E4 XX` to return 3. (#119644)
[llvm-project.git] / llvm / test / Analysis / StackSafetyAnalysis / memintrin.ll
blob6913816cc8fe7ad7ae2fddacbf1514721eeaaa7a
1 ; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s
2 ; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s --check-prefixes=CHECK,GLOBAL
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5 target triple = "x86_64-unknown-linux-gnu"
7 declare void @llvm.memset.p0.i64(ptr %dest, i8 %val, i64 %len, i1 %isvolatile)
8 declare void @llvm.memset.p0.i32(ptr %dest, i8 %val, i32 %len, i1 %isvolatile)
9 declare void @llvm.memcpy.p0.p0.i32(ptr %dest, ptr %src, i32 %len, i1 %isvolatile)
10 declare void @llvm.memmove.p0.p0.i32(ptr %dest, ptr %src, i32 %len, i1 %isvolatile)
12 define void @MemsetInBounds() {
13 ; CHECK-LABEL: MemsetInBounds dso_preemptable{{$}}
14 ; CHECK-NEXT: args uses:
15 ; CHECK-NEXT: allocas uses:
16 ; CHECK-NEXT: x[4]: [0,4){{$}}
17 ; GLOBAL-NEXT: safe accesses:
18 ; GLOBAL-NEXT: call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 4, i1 false)
19 ; CHECK-EMPTY:
20 entry:
21   %x = alloca i32, align 4
22   call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 4, i1 false)
23   ret void
26 ; Volatile does not matter for access bounds.
27 define void @VolatileMemsetInBounds() {
28 ; CHECK-LABEL: VolatileMemsetInBounds dso_preemptable{{$}}
29 ; CHECK-NEXT: args uses:
30 ; CHECK-NEXT: allocas uses:
31 ; CHECK-NEXT: x[4]: [0,4){{$}}
32 ; GLOBAL-NEXT: safe accesses:
33 ; GLOBAL-NEXT: call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 4, i1 true)
34 ; CHECK-EMPTY:
35 entry:
36   %x = alloca i32, align 4
37   call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 4, i1 true)
38   ret void
41 define void @MemsetOutOfBounds() {
42 ; CHECK-LABEL: MemsetOutOfBounds dso_preemptable{{$}}
43 ; CHECK-NEXT: args uses:
44 ; CHECK-NEXT: allocas uses:
45 ; CHECK-NEXT: x[4]: [0,5){{$}}
46 ; GLOBAL-NEXT: safe accesses:
47 ; CHECK-EMPTY:
48 entry:
49   %x = alloca i32, align 4
50   call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 5, i1 false)
51   ret void
54 define void @MemsetNonConst(i32 %size) {
55 ; CHECK-LABEL: MemsetNonConst dso_preemptable{{$}}
56 ; CHECK-NEXT: args uses:
57 ; CHECK-NEXT: allocas uses:
58 ; CHECK-NEXT: x[4]: [0,4294967295){{$}}
59 ; GLOBAL-NEXT: safe accesses:
60 ; CHECK-EMPTY:
61 entry:
62   %x = alloca i32, align 4
63   call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 %size, i1 false)
64   ret void
67 ; FIXME: memintrinsics should look at size range when possible
68 ; Right now we refuse any non-constant size.
69 define void @MemsetNonConstInBounds(i1 zeroext %z) {
70 ; CHECK-LABEL: MemsetNonConstInBounds dso_preemptable{{$}}
71 ; CHECK-NEXT: args uses:
72 ; CHECK-NEXT: allocas uses:
73 ; CHECK-NEXT: x[4]: [0,7){{$}}
74 ; GLOBAL-NEXT: safe accesses:
75 ; CHECK-EMPTY:
76 entry:
77   %x = alloca i32, align 4
78   %size = select i1 %z, i32 3, i32 4
79   call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 %size, i1 false)
80   ret void
83 define void @MemsetNonConstSize() {
84 ; CHECK-LABEL: MemsetNonConstSize dso_preemptable{{$}}
85 ; CHECK-NEXT: args uses:
86 ; CHECK-NEXT: allocas uses:
87 ; CHECK-NEXT: x[4]: [0,4294967295){{$}}
88 ; CHECK-NEXT: y[4]: empty-set{{$}}
89 ; GLOBAL-NEXT: safe accesses:
90 ; CHECK-EMPTY:
91 entry:
92   %x = alloca i32, align 4
93   %y = alloca i32, align 4
94   %xint = ptrtoint ptr %x to i32
95   %yint = ptrtoint ptr %y to i32
96   %d = sub i32 %xint, %yint
97   call void @llvm.memset.p0.i32(ptr %x, i8 42, i32 %d, i1 false)
98   ret void
101 define void @MemsetHugeUpper_m1(i1 %bool) {
102 ; CHECK-LABEL: MemsetHugeUpper_m1 dso_preemptable{{$}}
103 ; CHECK-NEXT: args uses:
104 ; CHECK-NEXT: allocas uses:
105 ; CHECK-NEXT:   x[4]: full-set
106 entry:
107   %x = alloca i32, align 4
108   br i1 %bool, label %if.then, label %if.end
110 if.then:
111   call void @llvm.memset.p0.i64(ptr %x, i8 0, i64 -1, i1 false)
112   br label %if.end
114 if.end:
115   ret void
118 define void @MemsetHugeUpper_m2(i1 %bool) {
119 ; CHECK-LABEL: MemsetHugeUpper_m2 dso_preemptable{{$}}
120 ; CHECK-NEXT: args uses:
121 ; CHECK-NEXT: allocas uses:
122 ; CHECK-NEXT:   x[4]: full-set
123 entry:
124   %x = alloca i32, align 4
125   br i1 %bool, label %if.then, label %if.end
127 if.then:
128   call void @llvm.memset.p0.i64(ptr %x, i8 0, i64 -2, i1 false)
129   br label %if.end
131 if.end:
132   ret void
135 define void @MemcpyInBounds() {
136 ; CHECK-LABEL: MemcpyInBounds dso_preemptable{{$}}
137 ; CHECK-NEXT: args uses:
138 ; CHECK-NEXT: allocas uses:
139 ; CHECK-NEXT: x[4]: [0,4){{$}}
140 ; CHECK-NEXT: y[4]: [0,4){{$}}
141 ; GLOBAL-NEXT: safe accesses:
142 ; GLOBAL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 4, i1 false)
143 ; CHECK-EMPTY:
144 entry:
145   %x = alloca i32, align 4
146   %y = alloca i32, align 4
147   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 4, i1 false)
148   ret void
151 define void @MemcpySrcOutOfBounds() {
152 ; CHECK-LABEL: MemcpySrcOutOfBounds dso_preemptable{{$}}
153 ; CHECK-NEXT: args uses:
154 ; CHECK-NEXT: allocas uses:
155 ; CHECK-NEXT: x[8]: [0,5){{$}}
156 ; CHECK-NEXT: y[4]: [0,5){{$}}
157 ; GLOBAL-NEXT: safe accesses
158 ; CHECK-EMPTY:
159 entry:
160   %x = alloca i64, align 4
161   %y = alloca i32, align 4
162   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 5, i1 false)
163   ret void
166 define void @MemcpyDstOutOfBounds() {
167 ; CHECK-LABEL: MemcpyDstOutOfBounds dso_preemptable{{$}}
168 ; CHECK-NEXT: args uses:
169 ; CHECK-NEXT: allocas uses:
170 ; CHECK-NEXT: x[4]: [0,5){{$}}
171 ; CHECK-NEXT: y[8]: [0,5){{$}}
172 ; GLOBAL-NEXT: safe accesses
173 ; CHECK-EMPTY:
174 entry:
175   %x = alloca i32, align 4
176   %y = alloca i64, align 4
177   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 5, i1 false)
178   ret void
181 define void @MemcpyBothOutOfBounds() {
182 ; CHECK-LABEL: MemcpyBothOutOfBounds dso_preemptable{{$}}
183 ; CHECK-NEXT: args uses:
184 ; CHECK-NEXT: allocas uses:
185 ; CHECK-NEXT: x[4]: [0,9){{$}}
186 ; CHECK-NEXT: y[8]: [0,9){{$}}
187 ; GLOBAL-NEXT: safe accesses
188 ; CHECK-EMPTY:
189 entry:
190   %x = alloca i32, align 4
191   %y = alloca i64, align 4
192   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 9, i1 false)
193   ret void
196 define void @MemcpySelfInBounds() {
197 ; CHECK-LABEL: MemcpySelfInBounds dso_preemptable{{$}}
198 ; CHECK-NEXT: args uses:
199 ; CHECK-NEXT: allocas uses:
200 ; CHECK-NEXT: x[8]: [0,8){{$}}
201 ; GLOBAL-NEXT: safe accesses
202 ; GLOBAL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %x2, i32 3, i1 false)
203 ; CHECK-EMPTY:
204 entry:
205   %x = alloca i64, align 4
206   %x2 = getelementptr i8, ptr %x, i64 5
207   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %x2, i32 3, i1 false)
208   ret void
211 define void @MemcpySelfSrcOutOfBounds() {
212 ; CHECK-LABEL: MemcpySelfSrcOutOfBounds dso_preemptable{{$}}
213 ; CHECK-NEXT: args uses:
214 ; CHECK-NEXT: allocas uses:
215 ; CHECK-NEXT: x[8]: [0,9){{$}}
216 ; GLOBAL-NEXT: safe accesses:
217 ; CHECK-EMPTY:
218 entry:
219   %x = alloca i64, align 4
220   %x2 = getelementptr i8, ptr %x, i64 5
221   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %x2, i32 4, i1 false)
222   ret void
225 define void @MemcpySelfDstOutOfBounds() {
226 ; CHECK-LABEL: MemcpySelfDstOutOfBounds dso_preemptable{{$}}
227 ; CHECK-NEXT: args uses:
228 ; CHECK-NEXT: allocas uses:
229 ; CHECK-NEXT: x[8]: [0,9){{$}}
230 ; GLOBAL-NEXT: safe accesses:
231 ; CHECK-EMPTY:
232 entry:
233   %x = alloca i64, align 4
234   %x2 = getelementptr i8, ptr %x, i64 5
235   call void @llvm.memcpy.p0.p0.i32(ptr %x2, ptr %x, i32 4, i1 false)
236   ret void
239 define void @MemmoveSelfBothOutOfBounds() {
240 ; CHECK-LABEL: MemmoveSelfBothOutOfBounds dso_preemptable{{$}}
241 ; CHECK-NEXT: args uses:
242 ; CHECK-NEXT: allocas uses:
243 ; CHECK-NEXT: x[8]: [0,14){{$}}
244 ; GLOBAL-NEXT: safe accesses:
245 ; CHECK-EMPTY:
246 entry:
247   %x = alloca i64, align 4
248   %x2 = getelementptr i8, ptr %x, i64 5
249   call void @llvm.memmove.p0.p0.i32(ptr %x, ptr %x2, i32 9, i1 false)
250   ret void
253 define void @MemsetInBoundsCast() {
254 ; CHECK-LABEL: MemsetInBoundsCast dso_preemptable{{$}}
255 ; CHECK-NEXT: args uses:
256 ; CHECK-NEXT: allocas uses:
257 ; CHECK-NEXT: x[4]: [0,4){{$}}
258 ; CHECK-NEXT: y[1]: empty-set{{$}}
259 ; GLOBAL-NEXT: safe accesses:
260 ; GLOBAL-NEXT: call void @llvm.memset.p0.i32(ptr %x, i8 %yint, i32 4, i1 false)
261 ; CHECK-EMPTY:
262 entry:
263   %x = alloca i32, align 4
264   %y = alloca i8, align 1
265   %yint = ptrtoint ptr %y to i8
266   call void @llvm.memset.p0.i32(ptr %x, i8 %yint, i32 4, i1 false)
267   ret void
270 define void @MemcpyInBoundsCast2(i8 %zint8) {
271 ; CHECK-LABEL: MemcpyInBoundsCast2 dso_preemptable{{$}}
272 ; CHECK-NEXT: args uses:
273 ; CHECK-NEXT: allocas uses:
274 ; CHECK-NEXT: x[256]: [0,255){{$}}
275 ; CHECK-NEXT: y[256]: [0,255){{$}}
276 ; CHECK-NEXT: z[1]: empty-set{{$}}
277 ; GLOBAL-NEXT: safe accesses:
278 ; GLOBAL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 %zint32, i1 false)
279 ; CHECK-EMPTY:
280 entry:
281   %x = alloca [256 x i8], align 4
282   %y = alloca [256 x i8], align 4
283   %z = alloca i8, align 1
284   %zint32 = zext i8 %zint8 to i32
285   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 %zint32, i1 false)
286   ret void