[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Analysis / StackSafetyAnalysis / memintrin.ll
blob9e1c49cb90be1048ee09e8d51dde02dc868dbf98
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.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
8 declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
9 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
10 declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %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.p0i8.i32(i8* %x1, i8 42, i32 4, i1 false)
19 ; CHECK-EMPTY:
20 entry:
21   %x = alloca i32, align 4
22   %x1 = bitcast i32* %x to i8*
23   call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 4, i1 false)
24   ret void
27 ; Volatile does not matter for access bounds.
28 define void @VolatileMemsetInBounds() {
29 ; CHECK-LABEL: VolatileMemsetInBounds dso_preemptable{{$}}
30 ; CHECK-NEXT: args uses:
31 ; CHECK-NEXT: allocas uses:
32 ; CHECK-NEXT: x[4]: [0,4){{$}}
33 ; GLOBAL-NEXT: safe accesses:
34 ; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 4, i1 true)
35 ; CHECK-EMPTY:
36 entry:
37   %x = alloca i32, align 4
38   %x1 = bitcast i32* %x to i8*
39   call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 4, i1 true)
40   ret void
43 define void @MemsetOutOfBounds() {
44 ; CHECK-LABEL: MemsetOutOfBounds dso_preemptable{{$}}
45 ; CHECK-NEXT: args uses:
46 ; CHECK-NEXT: allocas uses:
47 ; CHECK-NEXT: x[4]: [0,5){{$}}
48 ; GLOBAL-NEXT: safe accesses:
49 ; CHECK-EMPTY:
50 entry:
51   %x = alloca i32, align 4
52   %x1 = bitcast i32* %x to i8*
53   call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 5, i1 false)
54   ret void
57 define void @MemsetNonConst(i32 %size) {
58 ; CHECK-LABEL: MemsetNonConst dso_preemptable{{$}}
59 ; CHECK-NEXT: args uses:
60 ; CHECK-NEXT: allocas uses:
61 ; CHECK-NEXT: x[4]: [0,4294967295){{$}}
62 ; GLOBAL-NEXT: safe accesses:
63 ; CHECK-EMPTY:
64 entry:
65   %x = alloca i32, align 4
66   %x1 = bitcast i32* %x to i8*
67   call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 %size, i1 false)
68   ret void
71 ; FIXME: memintrinsics should look at size range when possible
72 ; Right now we refuse any non-constant size.
73 define void @MemsetNonConstInBounds(i1 zeroext %z) {
74 ; CHECK-LABEL: MemsetNonConstInBounds dso_preemptable{{$}}
75 ; CHECK-NEXT: args uses:
76 ; CHECK-NEXT: allocas uses:
77 ; CHECK-NEXT: x[4]: [0,7){{$}}
78 ; GLOBAL-NEXT: safe accesses:
79 ; CHECK-EMPTY:
80 entry:
81   %x = alloca i32, align 4
82   %x1 = bitcast i32* %x to i8*
83   %size = select i1 %z, i32 3, i32 4
84   call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 %size, i1 false)
85   ret void
88 define void @MemsetNonConstSize() {
89 ; CHECK-LABEL: MemsetNonConstSize dso_preemptable{{$}}
90 ; CHECK-NEXT: args uses:
91 ; CHECK-NEXT: allocas uses:
92 ; CHECK-NEXT: x[4]: [0,4294967295){{$}}
93 ; CHECK-NEXT: y[4]: empty-set{{$}}
94 ; GLOBAL-NEXT: safe accesses:
95 ; CHECK-EMPTY:
96 entry:
97   %x = alloca i32, align 4
98   %y = alloca i32, align 4
99   %x1 = bitcast i32* %x to i8*
100   %xint = ptrtoint i32* %x to i32
101   %yint = ptrtoint i32* %y to i32
102   %d = sub i32 %xint, %yint
103   call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 %d, i1 false)
104   ret void
107 define void @MemcpyInBounds() {
108 ; CHECK-LABEL: MemcpyInBounds dso_preemptable{{$}}
109 ; CHECK-NEXT: args uses:
110 ; CHECK-NEXT: allocas uses:
111 ; CHECK-NEXT: x[4]: [0,4){{$}}
112 ; CHECK-NEXT: y[4]: [0,4){{$}}
113 ; GLOBAL-NEXT: safe accesses:
114 ; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 4, i1 false)
115 ; CHECK-EMPTY:
116 entry:
117   %x = alloca i32, align 4
118   %y = alloca i32, align 4
119   %x1 = bitcast i32* %x to i8*
120   %y1 = bitcast i32* %y to i8*
121   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 4, i1 false)
122   ret void
125 define void @MemcpySrcOutOfBounds() {
126 ; CHECK-LABEL: MemcpySrcOutOfBounds dso_preemptable{{$}}
127 ; CHECK-NEXT: args uses:
128 ; CHECK-NEXT: allocas uses:
129 ; CHECK-NEXT: x[8]: [0,5){{$}}
130 ; CHECK-NEXT: y[4]: [0,5){{$}}
131 ; GLOBAL-NEXT: safe accesses
132 ; CHECK-EMPTY:
133 entry:
134   %x = alloca i64, align 4
135   %y = alloca i32, align 4
136   %x1 = bitcast i64* %x to i8*
137   %y1 = bitcast i32* %y to i8*
138   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 5, i1 false)
139   ret void
142 define void @MemcpyDstOutOfBounds() {
143 ; CHECK-LABEL: MemcpyDstOutOfBounds dso_preemptable{{$}}
144 ; CHECK-NEXT: args uses:
145 ; CHECK-NEXT: allocas uses:
146 ; CHECK-NEXT: x[4]: [0,5){{$}}
147 ; CHECK-NEXT: y[8]: [0,5){{$}}
148 ; GLOBAL-NEXT: safe accesses
149 ; CHECK-EMPTY:
150 entry:
151   %x = alloca i32, align 4
152   %y = alloca i64, align 4
153   %x1 = bitcast i32* %x to i8*
154   %y1 = bitcast i64* %y to i8*
155   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 5, i1 false)
156   ret void
159 define void @MemcpyBothOutOfBounds() {
160 ; CHECK-LABEL: MemcpyBothOutOfBounds dso_preemptable{{$}}
161 ; CHECK-NEXT: args uses:
162 ; CHECK-NEXT: allocas uses:
163 ; CHECK-NEXT: x[4]: [0,9){{$}}
164 ; CHECK-NEXT: y[8]: [0,9){{$}}
165 ; GLOBAL-NEXT: safe accesses
166 ; CHECK-EMPTY:
167 entry:
168   %x = alloca i32, align 4
169   %y = alloca i64, align 4
170   %x1 = bitcast i32* %x to i8*
171   %y1 = bitcast i64* %y to i8*
172   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 9, i1 false)
173   ret void
176 define void @MemcpySelfInBounds() {
177 ; CHECK-LABEL: MemcpySelfInBounds dso_preemptable{{$}}
178 ; CHECK-NEXT: args uses:
179 ; CHECK-NEXT: allocas uses:
180 ; CHECK-NEXT: x[8]: [0,8){{$}}
181 ; GLOBAL-NEXT: safe accesses
182 ; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 3, i1 false)
183 ; CHECK-EMPTY:
184 entry:
185   %x = alloca i64, align 4
186   %x1 = bitcast i64* %x to i8*
187   %x2 = getelementptr i8, i8* %x1, i64 5
188   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 3, i1 false)
189   ret void
192 define void @MemcpySelfSrcOutOfBounds() {
193 ; CHECK-LABEL: MemcpySelfSrcOutOfBounds dso_preemptable{{$}}
194 ; CHECK-NEXT: args uses:
195 ; CHECK-NEXT: allocas uses:
196 ; CHECK-NEXT: x[8]: [0,9){{$}}
197 ; GLOBAL-NEXT: safe accesses:
198 ; CHECK-EMPTY:
199 entry:
200   %x = alloca i64, align 4
201   %x1 = bitcast i64* %x to i8*
202   %x2 = getelementptr i8, i8* %x1, i64 5
203   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 4, i1 false)
204   ret void
207 define void @MemcpySelfDstOutOfBounds() {
208 ; CHECK-LABEL: MemcpySelfDstOutOfBounds dso_preemptable{{$}}
209 ; CHECK-NEXT: args uses:
210 ; CHECK-NEXT: allocas uses:
211 ; CHECK-NEXT: x[8]: [0,9){{$}}
212 ; GLOBAL-NEXT: safe accesses:
213 ; CHECK-EMPTY:
214 entry:
215   %x = alloca i64, align 4
216   %x1 = bitcast i64* %x to i8*
217   %x2 = getelementptr i8, i8* %x1, i64 5
218   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x2, i8* %x1, i32 4, i1 false)
219   ret void
222 define void @MemmoveSelfBothOutOfBounds() {
223 ; CHECK-LABEL: MemmoveSelfBothOutOfBounds dso_preemptable{{$}}
224 ; CHECK-NEXT: args uses:
225 ; CHECK-NEXT: allocas uses:
226 ; CHECK-NEXT: x[8]: [0,14){{$}}
227 ; GLOBAL-NEXT: safe accesses:
228 ; CHECK-EMPTY:
229 entry:
230   %x = alloca i64, align 4
231   %x1 = bitcast i64* %x to i8*
232   %x2 = getelementptr i8, i8* %x1, i64 5
233   call void @llvm.memmove.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 9, i1 false)
234   ret void
237 define void @MemsetInBoundsCast() {
238 ; CHECK-LABEL: MemsetInBoundsCast dso_preemptable{{$}}
239 ; CHECK-NEXT: args uses:
240 ; CHECK-NEXT: allocas uses:
241 ; CHECK-NEXT: x[4]: [0,4){{$}}
242 ; CHECK-NEXT: y[1]: empty-set{{$}}
243 ; GLOBAL-NEXT: safe accesses:
244 ; GLOBAL-NEXT: call void @llvm.memset.p0i8.i32(i8* %x1, i8 %yint, i32 4, i1 false)
245 ; CHECK-EMPTY:
246 entry:
247   %x = alloca i32, align 4
248   %y = alloca i8, align 1
249   %x1 = bitcast i32* %x to i8*
250   %yint = ptrtoint i8* %y to i8
251   call void @llvm.memset.p0i8.i32(i8* %x1, i8 %yint, i32 4, i1 false)
252   ret void
255 define void @MemcpyInBoundsCast2(i8 %zint8) {
256 ; CHECK-LABEL: MemcpyInBoundsCast2 dso_preemptable{{$}}
257 ; CHECK-NEXT: args uses:
258 ; CHECK-NEXT: allocas uses:
259 ; CHECK-NEXT: x[256]: [0,255){{$}}
260 ; CHECK-NEXT: y[256]: [0,255){{$}}
261 ; CHECK-NEXT: z[1]: empty-set{{$}}
262 ; GLOBAL-NEXT: safe accesses:
263 ; GLOBAL-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 %zint32, i1 false)
264 ; CHECK-EMPTY:
265 entry:
266   %x = alloca [256 x i8], align 4
267   %y = alloca [256 x i8], align 4
268   %z = alloca i8, align 1
269   %x1 = bitcast [256 x i8]* %x to i8*
270   %y1 = bitcast [256 x i8]* %y to i8*
271   %zint32 = zext i8 %zint8 to i32
272   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 %zint32, i1 false)
273   ret void