1 ; RUN: opt -S -analyze -stack-safety-local -enable-new-pm=0 < %s | FileCheck %s
2 ; RUN: opt -S -passes="print<stack-safety-local>" -disable-output < %s 2>&1 | FileCheck %s
3 ; RUN: opt -S -analyze -stack-safety < %s -enable-new-pm=0 | FileCheck %s
4 ; RUN: opt -S -passes="print-stack-safety" -disable-output < %s 2>&1 | FileCheck %s
6 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7 target triple = "x86_64-unknown-linux-gnu"
9 declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
10 declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
11 declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
12 declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
14 define void @MemsetInBounds() {
15 ; CHECK-LABEL: MemsetInBounds dso_preemptable{{$}}
16 ; CHECK-NEXT: args uses:
17 ; CHECK-NEXT: allocas uses:
18 ; CHECK-NEXT: x[4]: [0,4){{$}}
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)
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){{$}}
35 %x = alloca i32, align 4
36 %x1 = bitcast i32* %x to i8*
37 call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 4, i1 true)
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){{$}}
48 %x = alloca i32, align 4
49 %x1 = bitcast i32* %x to i8*
50 call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 5, i1 false)
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){{$}}
61 %x = alloca i32, align 4
62 %x1 = bitcast i32* %x to i8*
63 call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 %size, i1 false)
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){{$}}
76 %x = alloca i32, align 4
77 %x1 = bitcast i32* %x to i8*
78 %size = select i1 %z, i32 3, i32 4
79 call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 %size, i1 false)
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{{$}}
91 %x = alloca i32, align 4
92 %y = alloca i32, align 4
93 %x1 = bitcast i32* %x to i8*
94 %xint = ptrtoint i32* %x to i32
95 %yint = ptrtoint i32* %y to i32
96 %d = sub i32 %xint, %yint
97 call void @llvm.memset.p0i8.i32(i8* %x1, i8 42, i32 %d, i1 false)
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){{$}}
109 %x = alloca i32, align 4
110 %y = alloca i32, align 4
111 %x1 = bitcast i32* %x to i8*
112 %y1 = bitcast i32* %y to i8*
113 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 4, i1 false)
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){{$}}
125 %x = alloca i64, align 4
126 %y = alloca i32, align 4
127 %x1 = bitcast i64* %x to i8*
128 %y1 = bitcast i32* %y to i8*
129 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 5, i1 false)
133 define void @MemcpyDstOutOfBounds() {
134 ; CHECK-LABEL: MemcpyDstOutOfBounds dso_preemptable{{$}}
135 ; CHECK-NEXT: args uses:
136 ; CHECK-NEXT: allocas uses:
137 ; CHECK-NEXT: x[4]: [0,5){{$}}
138 ; CHECK-NEXT: y[8]: [0,5){{$}}
141 %x = alloca i32, align 4
142 %y = alloca i64, align 4
143 %x1 = bitcast i32* %x to i8*
144 %y1 = bitcast i64* %y to i8*
145 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 5, i1 false)
149 define void @MemcpyBothOutOfBounds() {
150 ; CHECK-LABEL: MemcpyBothOutOfBounds dso_preemptable{{$}}
151 ; CHECK-NEXT: args uses:
152 ; CHECK-NEXT: allocas uses:
153 ; CHECK-NEXT: x[4]: [0,9){{$}}
154 ; CHECK-NEXT: y[8]: [0,9){{$}}
157 %x = alloca i32, align 4
158 %y = alloca i64, align 4
159 %x1 = bitcast i32* %x to i8*
160 %y1 = bitcast i64* %y to i8*
161 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %y1, i32 9, i1 false)
165 define void @MemcpySelfInBounds() {
166 ; CHECK-LABEL: MemcpySelfInBounds dso_preemptable{{$}}
167 ; CHECK-NEXT: args uses:
168 ; CHECK-NEXT: allocas uses:
169 ; CHECK-NEXT: x[8]: [0,8){{$}}
172 %x = alloca i64, align 4
173 %x1 = bitcast i64* %x to i8*
174 %x2 = getelementptr i8, i8* %x1, i64 5
175 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 3, i1 false)
179 define void @MemcpySelfSrcOutOfBounds() {
180 ; CHECK-LABEL: MemcpySelfSrcOutOfBounds dso_preemptable{{$}}
181 ; CHECK-NEXT: args uses:
182 ; CHECK-NEXT: allocas uses:
183 ; CHECK-NEXT: x[8]: [0,9){{$}}
186 %x = alloca i64, align 4
187 %x1 = bitcast i64* %x to i8*
188 %x2 = getelementptr i8, i8* %x1, i64 5
189 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 4, i1 false)
193 define void @MemcpySelfDstOutOfBounds() {
194 ; CHECK-LABEL: MemcpySelfDstOutOfBounds dso_preemptable{{$}}
195 ; CHECK-NEXT: args uses:
196 ; CHECK-NEXT: allocas uses:
197 ; CHECK-NEXT: x[8]: [0,9){{$}}
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* %x2, i8* %x1, i32 4, i1 false)
207 define void @MemmoveSelfBothOutOfBounds() {
208 ; CHECK-LABEL: MemmoveSelfBothOutOfBounds dso_preemptable{{$}}
209 ; CHECK-NEXT: args uses:
210 ; CHECK-NEXT: allocas uses:
211 ; CHECK-NEXT: x[8]: [0,14){{$}}
214 %x = alloca i64, align 4
215 %x1 = bitcast i64* %x to i8*
216 %x2 = getelementptr i8, i8* %x1, i64 5
217 call void @llvm.memmove.p0i8.p0i8.i32(i8* %x1, i8* %x2, i32 9, i1 false)