1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -inferattrs -basic-aa -dse | FileCheck %s
3 ; RUN: opt < %s -S -aa-pipeline=basic-aa -passes=inferattrs,dse | FileCheck %s
5 target triple = "x86_64-unknown-linux-gnu"
7 declare i8* @strcpy(i8* %dest, i8* %src) nounwind
8 define void @test1(i8* %src) {
10 ; CHECK-NEXT: ret void
13 %dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
14 %call = call i8* @strcpy(i8* %dest, i8* %src)
18 declare i8* @strncpy(i8* %dest, i8* %src, i64 %n) nounwind
19 define void @test2(i8* %src) {
20 ; CHECK-LABEL: @test2(
21 ; CHECK-NEXT: ret void
24 %dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
25 %call = call i8* @strncpy(i8* %dest, i8* %src, i64 12)
29 declare i8* @strcat(i8* %dest, i8* %src) nounwind
30 define void @test3(i8* %src) {
31 ; CHECK-LABEL: @test3(
32 ; CHECK-NEXT: ret void
35 %dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
36 %call = call i8* @strcat(i8* %dest, i8* %src)
40 define void @test_strcat_with_lifetime(i8* %src) {
41 ; CHECK-LABEL: @test_strcat_with_lifetime(
42 ; CHECK-NEXT: [[B:%.*]] = alloca [16 x i8], align 1
43 ; CHECK-NEXT: [[B_CAST:%.*]] = bitcast [16 x i8]* [[B]] to i8*
44 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull [[B_CAST]])
45 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull [[B_CAST]])
46 ; CHECK-NEXT: ret void
49 %B.cast = bitcast [16 x i8]* %B to i8*
50 call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %B.cast)
51 %dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
52 %call = call i8* @strcat(i8* %dest, i8* %src)
53 call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %B.cast)
57 define void @test_strcat_with_lifetime_nonlocal(i8* %dest, i8* %src) {
58 ; CHECK-LABEL: @test_strcat_with_lifetime_nonlocal(
59 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull [[DEST:%.*]])
60 ; CHECK-NEXT: [[CALL:%.*]] = call i8* @strcat(i8* [[DEST]], i8* [[SRC:%.*]])
61 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull [[DEST]])
62 ; CHECK-NEXT: ret void
64 call void @llvm.lifetime.start.p0i8(i64 16, i8* nonnull %dest)
65 %call = call i8* @strcat(i8* %dest, i8* %src)
66 call void @llvm.lifetime.end.p0i8(i64 16, i8* nonnull %dest)
70 declare i8* @strncat(i8* %dest, i8* %src, i64 %n) nounwind
71 define void @test4(i8* %src) {
72 ; CHECK-LABEL: @test4(
73 ; CHECK-NEXT: ret void
76 %dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
77 %call = call i8* @strncat(i8* %dest, i8* %src, i64 12)
81 define void @test5(i8* nocapture %src) {
82 ; CHECK-LABEL: @test5(
83 ; CHECK-NEXT: ret void
85 %dest = alloca [100 x i8], align 16
86 %arraydecay = getelementptr inbounds [100 x i8], [100 x i8]* %dest, i64 0, i64 0
87 %call = call i8* @strcpy(i8* %arraydecay, i8* %src)
88 %arrayidx = getelementptr inbounds i8, i8* %call, i64 10
89 store i8 97, i8* %arrayidx, align 1
93 declare void @user(i8* %p)
94 define void @test6(i8* %src) {
95 ; CHECK-LABEL: @test6(
96 ; CHECK-NEXT: [[B:%.*]] = alloca [16 x i8], align 1
97 ; CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds [16 x i8], [16 x i8]* [[B]], i64 0, i64 0
98 ; CHECK-NEXT: [[CALL:%.*]] = call i8* @strcpy(i8* [[DEST]], i8* [[SRC:%.*]])
99 ; CHECK-NEXT: call void @user(i8* [[DEST]])
100 ; CHECK-NEXT: ret void
102 %B = alloca [16 x i8]
103 %dest = getelementptr inbounds [16 x i8], [16 x i8]* %B, i64 0, i64 0
104 %call = call i8* @strcpy(i8* %dest, i8* %src)
105 call void @user(i8* %dest)
109 declare i32 @memcmp(i8*, i8*, i64)
111 define i32 @test_memcmp_const_size(i8* noalias %foo) {
112 ; CHECK-LABEL: @test_memcmp_const_size(
114 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
115 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
116 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
117 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
118 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
119 ; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(i8* nonnull dereferenceable(2) [[FOO:%.*]], i8* nonnull dereferenceable(2) [[STACK_PTR]], i64 2)
120 ; CHECK-NEXT: ret i32 [[RES]]
123 %stack = alloca [10 x i8]
124 %stack.ptr = bitcast [10 x i8]* %stack to i8*
125 store i8 49, i8* %stack.ptr, align 1
126 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
127 store i8 50, i8* %gep.1, align 1
128 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
129 store i8 51, i8* %gep.2, align 1
130 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
131 store i8 52, i8* %gep.3, align 1
132 %res = call i32 @memcmp(i8* nonnull dereferenceable(2) %foo, i8* nonnull dereferenceable(2) %stack.ptr, i64 2)
136 define i32 @test_memcmp_variable_size(i8* noalias %foo, i64 %n) {
137 ; CHECK-LABEL: @test_memcmp_variable_size(
139 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
140 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
141 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
142 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
143 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
144 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
145 ; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
146 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3
147 ; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
148 ; CHECK-NEXT: [[RES:%.*]] = call i32 @memcmp(i8* nonnull [[FOO:%.*]], i8* nonnull [[STACK_PTR]], i64 [[N:%.*]])
149 ; CHECK-NEXT: ret i32 [[RES]]
152 %stack = alloca [10 x i8]
153 %stack.ptr = bitcast [10 x i8]* %stack to i8*
154 store i8 49, i8* %stack.ptr, align 1
155 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
156 store i8 50, i8* %gep.1, align 1
157 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
158 store i8 51, i8* %gep.2, align 1
159 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
160 store i8 52, i8* %gep.3, align 1
161 %res = call i32 @memcmp(i8* nonnull %foo, i8* nonnull %stack.ptr, i64 %n)
165 declare i32 @bcmp(i8*, i8*, i64)
167 define i1 @test_bcmp_const_size(i8* noalias %foo) {
168 ; CHECK-LABEL: @test_bcmp_const_size(
170 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
171 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
172 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
173 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
174 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
175 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* nonnull dereferenceable(2) [[FOO:%.*]], i8* nonnull dereferenceable(2) [[STACK_PTR]], i64 2)
176 ; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 0
177 ; CHECK-NEXT: ret i1 [[RES]]
180 %stack = alloca [10 x i8]
181 %stack.ptr = bitcast [10 x i8]* %stack to i8*
182 store i8 49, i8* %stack.ptr, align 1
183 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
184 store i8 50, i8* %gep.1, align 1
185 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
186 store i8 51, i8* %gep.2, align 1
187 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
188 store i8 52, i8* %gep.3, align 1
189 %call = call i32 @bcmp(i8* nonnull dereferenceable(2) %foo, i8* nonnull dereferenceable(2) %stack.ptr, i64 2)
190 %res = icmp eq i32 %call, 0
194 define i1 @test_bcmp_variable_size(i8* noalias %foo, i64 %n) {
195 ; CHECK-LABEL: @test_bcmp_variable_size(
197 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
198 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
199 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
200 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
201 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
202 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
203 ; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
204 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3
205 ; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
206 ; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* nonnull [[FOO:%.*]], i8* nonnull [[STACK_PTR]], i64 [[N:%.*]])
207 ; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CALL]], 0
208 ; CHECK-NEXT: ret i1 [[RES]]
211 %stack = alloca [10 x i8]
212 %stack.ptr = bitcast [10 x i8]* %stack to i8*
213 store i8 49, i8* %stack.ptr, align 1
214 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
215 store i8 50, i8* %gep.1, align 1
216 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
217 store i8 51, i8* %gep.2, align 1
218 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
219 store i8 52, i8* %gep.3, align 1
220 %call = call i32 @bcmp(i8* nonnull %foo, i8* nonnull %stack.ptr, i64 %n)
221 %res = icmp eq i32 %call, 0
225 declare i8* @memchr(i8*, i32, i64)
227 define i8* @test_memchr_const_size() {
228 ; CHECK-LABEL: @test_memchr_const_size(
230 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
231 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
232 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
233 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
234 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
235 ; CHECK-NEXT: [[CALL:%.*]] = call i8* @memchr(i8* [[STACK_PTR]], i32 42, i64 2)
236 ; CHECK-NEXT: ret i8* [[CALL]]
239 %stack = alloca [10 x i8]
240 %stack.ptr = bitcast [10 x i8]* %stack to i8*
241 store i8 49, i8* %stack.ptr, align 1
242 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
243 store i8 50, i8* %gep.1, align 1
244 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
245 store i8 51, i8* %gep.2, align 1
246 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
247 store i8 52, i8* %gep.3, align 1
248 %call = call i8* @memchr(i8* %stack.ptr, i32 42, i64 2)
252 define i8* @test_memchr_variable_size(i64 %n) {
253 ; CHECK-LABEL: @test_memchr_variable_size(
255 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
256 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
257 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
258 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
259 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
260 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
261 ; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
262 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 4
263 ; CHECK-NEXT: store i8 52, i8* [[GEP]], align 1
264 ; CHECK-NEXT: [[CALL:%.*]] = call i8* @memchr(i8* [[STACK_PTR]], i32 42, i64 [[N:%.*]])
265 ; CHECK-NEXT: ret i8* [[CALL]]
268 %stack = alloca [10 x i8]
269 %stack.ptr = bitcast [10 x i8]* %stack to i8*
270 store i8 49, i8* %stack.ptr, align 1
271 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
272 store i8 50, i8* %gep.1, align 1
273 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
274 store i8 51, i8* %gep.2, align 1
275 %gep = getelementptr i8, i8* %stack.ptr, i64 4
276 store i8 52, i8* %gep, align 1
277 %call = call i8* @memchr(i8* %stack.ptr, i32 42, i64 %n)
281 declare i8* @memccpy(i8*, i8*, i32, i64)
283 define i8* @test_memccpy_const_size(i8* %foo) {
284 ; CHECK-LABEL: @test_memccpy_const_size(
286 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
287 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
288 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
289 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
290 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
291 ; CHECK-NEXT: [[RES:%.*]] = call i8* @memccpy(i8* [[FOO:%.*]], i8* [[STACK_PTR]], i32 42, i64 2)
292 ; CHECK-NEXT: ret i8* [[RES]]
295 %stack = alloca [10 x i8]
296 %stack.ptr = bitcast [10 x i8]* %stack to i8*
297 store i8 49, i8* %stack.ptr, align 1
298 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
299 store i8 50, i8* %gep.1, align 1
300 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
301 store i8 51, i8* %gep.2, align 1
302 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
303 store i8 52, i8* %gep.3, align 1
304 %res = call i8* @memccpy(i8* %foo, i8* %stack.ptr, i32 42, i64 2)
308 define i8* @test_memccpy_variable_size(i8* %foo, i64 %n) {
309 ; CHECK-LABEL: @test_memccpy_variable_size(
311 ; CHECK-NEXT: [[STACK:%.*]] = alloca [10 x i8], align 1
312 ; CHECK-NEXT: [[STACK_PTR:%.*]] = bitcast [10 x i8]* [[STACK]] to i8*
313 ; CHECK-NEXT: store i8 49, i8* [[STACK_PTR]], align 1
314 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 1
315 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
316 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 2
317 ; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
318 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[STACK_PTR]], i64 3
319 ; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
320 ; CHECK-NEXT: [[RES:%.*]] = call i8* @memccpy(i8* [[FOO:%.*]], i8* [[STACK_PTR]], i32 42, i64 [[N:%.*]])
321 ; CHECK-NEXT: ret i8* [[RES]]
324 %stack = alloca [10 x i8]
325 %stack.ptr = bitcast [10 x i8]* %stack to i8*
326 store i8 49, i8* %stack.ptr, align 1
327 %gep.1 = getelementptr i8, i8* %stack.ptr, i64 1
328 store i8 50, i8* %gep.1, align 1
329 %gep.2 = getelementptr i8, i8* %stack.ptr, i64 2
330 store i8 51, i8* %gep.2, align 1
331 %gep.3 = getelementptr i8, i8* %stack.ptr, i64 3
332 store i8 52, i8* %gep.3, align 1
333 %res = call i8* @memccpy(i8* %foo, i8* %stack.ptr, i32 42, i64 %n)
337 ; Make sure memccpy does not kill any stores, because it is not known how many
339 define i8* @test_memccpy_const_size_does_not_kill_stores(i8* noalias %dest, i8* noalias %foo) {
340 ; CHECK-LABEL: @test_memccpy_const_size_does_not_kill_stores(
342 ; CHECK-NEXT: store i8 49, i8* [[DEST:%.*]], align 1
343 ; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr i8, i8* [[DEST]], i64 1
344 ; CHECK-NEXT: store i8 50, i8* [[GEP_1]], align 1
345 ; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr i8, i8* [[DEST]], i64 2
346 ; CHECK-NEXT: store i8 51, i8* [[GEP_2]], align 1
347 ; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr i8, i8* [[DEST]], i64 3
348 ; CHECK-NEXT: store i8 52, i8* [[GEP_3]], align 1
349 ; CHECK-NEXT: [[RES:%.*]] = call i8* @memccpy(i8* [[DEST]], i8* [[FOO:%.*]], i32 42, i64 2)
350 ; CHECK-NEXT: ret i8* [[RES]]
353 store i8 49, i8* %dest, align 1
354 %gep.1 = getelementptr i8, i8* %dest, i64 1
355 store i8 50, i8* %gep.1, align 1
356 %gep.2 = getelementptr i8, i8* %dest, i64 2
357 store i8 51, i8* %gep.2, align 1
358 %gep.3 = getelementptr i8, i8* %dest, i64 3
359 store i8 52, i8* %gep.3, align 1
360 %res = call i8* @memccpy(i8* %dest, i8* %foo, i32 42, i64 2)
364 define void @dse_strcpy(i8* nocapture readonly %src) {
365 ; CHECK-LABEL: @dse_strcpy(
366 ; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
367 ; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
368 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
369 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
370 ; CHECK-NEXT: ret void
372 %a = alloca [256 x i8], align 16
373 %buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
374 call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
375 call i8* @strcpy(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src)
376 call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
380 define void @dse_strncpy(i8* nocapture readonly %src) {
381 ; CHECK-LABEL: @dse_strncpy(
382 ; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
383 ; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
384 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
385 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
386 ; CHECK-NEXT: ret void
388 %a = alloca [256 x i8], align 16
389 %buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
390 call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
391 call i8* @strncpy(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src, i64 6)
392 call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
396 define void @dse_strcat(i8* nocapture readonly %src) {
397 ; CHECK-LABEL: @dse_strcat(
398 ; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
399 ; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
400 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
401 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
402 ; CHECK-NEXT: ret void
404 %a = alloca [256 x i8], align 16
405 %buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
406 call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
407 call i8* @strcat(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src)
408 call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
412 define void @dse_strncat(i8* nocapture readonly %src) {
413 ; CHECK-LABEL: @dse_strncat(
414 ; CHECK-NEXT: [[A:%.*]] = alloca [256 x i8], align 16
415 ; CHECK-NEXT: [[BUF:%.*]] = getelementptr inbounds [256 x i8], [256 x i8]* [[A]], i64 0, i64 0
416 ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull [[BUF]])
417 ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull [[BUF]])
418 ; CHECK-NEXT: ret void
420 %a = alloca [256 x i8], align 16
421 %buf = getelementptr inbounds [256 x i8], [256 x i8]* %a, i64 0, i64 0
422 call void @llvm.lifetime.start.p0i8(i64 256, i8* nonnull %buf)
423 call i8* @strncat(i8* nonnull %buf, i8* nonnull dereferenceable(1) %src, i64 6)
424 call void @llvm.lifetime.end.p0i8(i64 256, i8* nonnull %buf)
428 declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture)
429 declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)