@@ -330,6 +330,123 @@ use_block:
330
330
ret i32 %var3
331
331
}
332
332
333
+ define i32 @sink_lifetime1 (i1 %c ) {
334
+ ; CHECK-LABEL: @sink_lifetime1(
335
+ ; CHECK-NEXT: entry:
336
+ ; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 4
337
+ ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
338
+ ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
339
+ ; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
340
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
341
+ ; CHECK: early_return:
342
+ ; CHECK-NEXT: ret i32 0
343
+ ; CHECK: use_block:
344
+ ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
345
+ ; CHECK-NEXT: ret i32 [[VAR3]]
346
+ ;
347
+ entry:
348
+ %var = alloca i32 , align 4
349
+ %bitcast = bitcast i32* %var to i8*
350
+ call void @llvm.lifetime.start.p0i8 (i64 4 , i8* %bitcast )
351
+ %var3 = call i32 @unknown (i32* %var ) argmemonly nounwind willreturn
352
+ br i1 %c , label %early_return , label %use_block
353
+
354
+ early_return:
355
+ ret i32 0
356
+
357
+ use_block:
358
+ call void @llvm.lifetime.end.p0i8 (i64 4 , i8* %bitcast )
359
+ ret i32 %var3
360
+ }
361
+
362
+ define i32 @sink_lifetime2 (i1 %c ) {
363
+ ; CHECK-LABEL: @sink_lifetime2(
364
+ ; CHECK-NEXT: entry:
365
+ ; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 4
366
+ ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
367
+ ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
368
+ ; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
369
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[MERGE:%.*]], label [[USE_BLOCK:%.*]]
370
+ ; CHECK: merge:
371
+ ; CHECK-NEXT: [[RET:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[VAR3]], [[USE_BLOCK]] ]
372
+ ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
373
+ ; CHECK-NEXT: ret i32 [[RET]]
374
+ ; CHECK: use_block:
375
+ ; CHECK-NEXT: br label [[MERGE]]
376
+ ;
377
+ entry:
378
+ %var = alloca i32 , align 4
379
+ %bitcast = bitcast i32* %var to i8*
380
+ call void @llvm.lifetime.start.p0i8 (i64 4 , i8* %bitcast )
381
+ %var3 = call i32 @unknown (i32* %var ) argmemonly nounwind willreturn
382
+ br i1 %c , label %merge , label %use_block
383
+
384
+ merge:
385
+ %ret = phi i32 [0 , %entry ], [%var3 , %use_block ]
386
+ call void @llvm.lifetime.end.p0i8 (i64 4 , i8* %bitcast )
387
+ ret i32 %ret
388
+
389
+ use_block:
390
+ br label %merge
391
+ }
392
+
393
+ define i32 @sink_lifetime3 (i1 %c ) {
394
+ ; CHECK-LABEL: @sink_lifetime3(
395
+ ; CHECK-NEXT: entry:
396
+ ; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 4
397
+ ; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
398
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
399
+ ; CHECK: early_return:
400
+ ; CHECK-NEXT: ret i32 0
401
+ ; CHECK: use_block:
402
+ ; CHECK-NEXT: ret i32 [[VAR3]]
403
+ ;
404
+ entry:
405
+ %var = alloca i32 , align 4
406
+ %bitcast = bitcast i32* %var to i8*
407
+ call void @llvm.lifetime.start.p0i8 (i64 4 , i8* %bitcast )
408
+ call void @llvm.lifetime.end.p0i8 (i64 4 , i8* %bitcast )
409
+ ; If unknown accesses %var, that's UB
410
+ %var3 = call i32 @unknown (i32* %var ) argmemonly nounwind willreturn
411
+ br i1 %c , label %early_return , label %use_block
412
+
413
+ early_return:
414
+ ret i32 0
415
+
416
+ use_block:
417
+ ret i32 %var3
418
+ }
419
+
420
+ define i32 @sink_lifetime4 (i1 %c ) {
421
+ ; CHECK-LABEL: @sink_lifetime4(
422
+ ; CHECK-NEXT: entry:
423
+ ; CHECK-NEXT: [[VAR:%.*]] = alloca i32, align 4
424
+ ; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[VAR]] to i8*
425
+ ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[BITCAST]])
426
+ ; CHECK-NEXT: [[VAR3:%.*]] = call i32 @unknown(i32* nonnull [[VAR]]) #[[ATTR1]]
427
+ ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[BITCAST]])
428
+ ; CHECK-NEXT: br i1 [[C:%.*]], label [[EARLY_RETURN:%.*]], label [[USE_BLOCK:%.*]]
429
+ ; CHECK: early_return:
430
+ ; CHECK-NEXT: ret i32 0
431
+ ; CHECK: use_block:
432
+ ; CHECK-NEXT: ret i32 [[VAR3]]
433
+ ;
434
+ entry:
435
+ %var = alloca i32 , align 4
436
+ %bitcast = bitcast i32* %var to i8*
437
+ call void @llvm.lifetime.start.p0i8 (i64 4 , i8* %bitcast )
438
+ %var3 = call i32 @unknown (i32* %var ) argmemonly nounwind willreturn
439
+ call void @llvm.lifetime.end.p0i8 (i64 4 , i8* %bitcast )
440
+ br i1 %c , label %early_return , label %use_block
441
+
442
+ early_return:
443
+ ret i32 0
444
+
445
+ use_block:
446
+ ret i32 %var3
447
+ }
448
+
333
449
declare i32 @bar ()
334
450
declare void @llvm.lifetime.start.p0i8 (i64 immarg, i8* nocapture )
335
451
declare void @llvm.lifetime.end.p0i8 (i64 immarg, i8* nocapture )
452
+
0 commit comments