Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / Analysis / StackSafetyAnalysis / memintrin.ll
blob791fb35ce2b759afc5e7e17ba83f36e846ec855e
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 @MemcpyInBounds() {
102 ; CHECK-LABEL: MemcpyInBounds dso_preemptable{{$}}
103 ; CHECK-NEXT: args uses:
104 ; CHECK-NEXT: allocas uses:
105 ; CHECK-NEXT: x[4]: [0,4){{$}}
106 ; CHECK-NEXT: y[4]: [0,4){{$}}
107 ; GLOBAL-NEXT: safe accesses:
108 ; GLOBAL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 4, i1 false)
109 ; CHECK-EMPTY:
110 entry:
111   %x = alloca i32, align 4
112   %y = alloca i32, align 4
113   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 4, i1 false)
114   ret void
117 define void @MemcpySrcOutOfBounds() {
118 ; CHECK-LABEL: MemcpySrcOutOfBounds dso_preemptable{{$}}
119 ; CHECK-NEXT: args uses:
120 ; CHECK-NEXT: allocas uses:
121 ; CHECK-NEXT: x[8]: [0,5){{$}}
122 ; CHECK-NEXT: y[4]: [0,5){{$}}
123 ; GLOBAL-NEXT: safe accesses
124 ; CHECK-EMPTY:
125 entry:
126   %x = alloca i64, align 4
127   %y = alloca i32, align 4
128   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 5, i1 false)
129   ret void
132 define void @MemcpyDstOutOfBounds() {
133 ; CHECK-LABEL: MemcpyDstOutOfBounds dso_preemptable{{$}}
134 ; CHECK-NEXT: args uses:
135 ; CHECK-NEXT: allocas uses:
136 ; CHECK-NEXT: x[4]: [0,5){{$}}
137 ; CHECK-NEXT: y[8]: [0,5){{$}}
138 ; GLOBAL-NEXT: safe accesses
139 ; CHECK-EMPTY:
140 entry:
141   %x = alloca i32, align 4
142   %y = alloca i64, align 4
143   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 5, i1 false)
144   ret void
147 define void @MemcpyBothOutOfBounds() {
148 ; CHECK-LABEL: MemcpyBothOutOfBounds dso_preemptable{{$}}
149 ; CHECK-NEXT: args uses:
150 ; CHECK-NEXT: allocas uses:
151 ; CHECK-NEXT: x[4]: [0,9){{$}}
152 ; CHECK-NEXT: y[8]: [0,9){{$}}
153 ; GLOBAL-NEXT: safe accesses
154 ; CHECK-EMPTY:
155 entry:
156   %x = alloca i32, align 4
157   %y = alloca i64, align 4
158   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 9, i1 false)
159   ret void
162 define void @MemcpySelfInBounds() {
163 ; CHECK-LABEL: MemcpySelfInBounds dso_preemptable{{$}}
164 ; CHECK-NEXT: args uses:
165 ; CHECK-NEXT: allocas uses:
166 ; CHECK-NEXT: x[8]: [0,8){{$}}
167 ; GLOBAL-NEXT: safe accesses
168 ; GLOBAL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %x2, i32 3, i1 false)
169 ; CHECK-EMPTY:
170 entry:
171   %x = alloca i64, align 4
172   %x2 = getelementptr i8, ptr %x, i64 5
173   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %x2, i32 3, i1 false)
174   ret void
177 define void @MemcpySelfSrcOutOfBounds() {
178 ; CHECK-LABEL: MemcpySelfSrcOutOfBounds dso_preemptable{{$}}
179 ; CHECK-NEXT: args uses:
180 ; CHECK-NEXT: allocas uses:
181 ; CHECK-NEXT: x[8]: [0,9){{$}}
182 ; GLOBAL-NEXT: safe accesses:
183 ; CHECK-EMPTY:
184 entry:
185   %x = alloca i64, align 4
186   %x2 = getelementptr i8, ptr %x, i64 5
187   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %x2, i32 4, i1 false)
188   ret void
191 define void @MemcpySelfDstOutOfBounds() {
192 ; CHECK-LABEL: MemcpySelfDstOutOfBounds dso_preemptable{{$}}
193 ; CHECK-NEXT: args uses:
194 ; CHECK-NEXT: allocas uses:
195 ; CHECK-NEXT: x[8]: [0,9){{$}}
196 ; GLOBAL-NEXT: safe accesses:
197 ; CHECK-EMPTY:
198 entry:
199   %x = alloca i64, align 4
200   %x2 = getelementptr i8, ptr %x, i64 5
201   call void @llvm.memcpy.p0.p0.i32(ptr %x2, ptr %x, i32 4, i1 false)
202   ret void
205 define void @MemmoveSelfBothOutOfBounds() {
206 ; CHECK-LABEL: MemmoveSelfBothOutOfBounds dso_preemptable{{$}}
207 ; CHECK-NEXT: args uses:
208 ; CHECK-NEXT: allocas uses:
209 ; CHECK-NEXT: x[8]: [0,14){{$}}
210 ; GLOBAL-NEXT: safe accesses:
211 ; CHECK-EMPTY:
212 entry:
213   %x = alloca i64, align 4
214   %x2 = getelementptr i8, ptr %x, i64 5
215   call void @llvm.memmove.p0.p0.i32(ptr %x, ptr %x2, i32 9, i1 false)
216   ret void
219 define void @MemsetInBoundsCast() {
220 ; CHECK-LABEL: MemsetInBoundsCast dso_preemptable{{$}}
221 ; CHECK-NEXT: args uses:
222 ; CHECK-NEXT: allocas uses:
223 ; CHECK-NEXT: x[4]: [0,4){{$}}
224 ; CHECK-NEXT: y[1]: empty-set{{$}}
225 ; GLOBAL-NEXT: safe accesses:
226 ; GLOBAL-NEXT: call void @llvm.memset.p0.i32(ptr %x, i8 %yint, i32 4, i1 false)
227 ; CHECK-EMPTY:
228 entry:
229   %x = alloca i32, align 4
230   %y = alloca i8, align 1
231   %yint = ptrtoint ptr %y to i8
232   call void @llvm.memset.p0.i32(ptr %x, i8 %yint, i32 4, i1 false)
233   ret void
236 define void @MemcpyInBoundsCast2(i8 %zint8) {
237 ; CHECK-LABEL: MemcpyInBoundsCast2 dso_preemptable{{$}}
238 ; CHECK-NEXT: args uses:
239 ; CHECK-NEXT: allocas uses:
240 ; CHECK-NEXT: x[256]: [0,255){{$}}
241 ; CHECK-NEXT: y[256]: [0,255){{$}}
242 ; CHECK-NEXT: z[1]: empty-set{{$}}
243 ; GLOBAL-NEXT: safe accesses:
244 ; GLOBAL-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 %zint32, i1 false)
245 ; CHECK-EMPTY:
246 entry:
247   %x = alloca [256 x i8], align 4
248   %y = alloca [256 x i8], align 4
249   %z = alloca i8, align 1
250   %zint32 = zext i8 %zint8 to i32
251   call void @llvm.memcpy.p0.p0.i32(ptr %x, ptr %y, i32 %zint32, i1 false)
252   ret void