1; RUN: opt -debugify -dce -S < %s | FileCheck %s
2; RUN: opt -passes='module(debugify),function(dce)' -S < %s | FileCheck %s
3
4; CHECK-LABEL: @test
5define void @test() {
6  %add = add i32 1, 2
7; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 1, metadata [[add:![0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 2, DW_OP_stack_value))
8  %sub = sub i32 %add, 1
9; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 1, metadata [[sub:![0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 2, DW_OP_constu, 1, DW_OP_minus, DW_OP_stack_value))
10; CHECK-NEXT: ret void
11  ret void
12}
13
14declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
15declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) nounwind
16
17; CHECK-LABEL: @test_lifetime_alloca
18define i32 @test_lifetime_alloca() {
19; Check that lifetime intrinsics are removed along with the pointer.
20; CHECK-NEXT: @llvm.dbg.value
21; CHECK-NEXT: ret i32 0
22; CHECK-NOT: llvm.lifetime.start
23; CHECK-NOT: llvm.lifetime.end
24  %i = alloca i8, align 4
25  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %i)
26  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %i)
27  ret i32 0
28}
29
30; CHECK-LABEL: @test_lifetime_arg
31define i32 @test_lifetime_arg(i8*) {
32; Check that lifetime intrinsics are removed along with the pointer.
33; CHECK-NEXT: llvm.dbg.value
34; CHECK-NEXT: ret i32 0
35; CHECK-NOT: llvm.lifetime.start
36; CHECK-NOT: llvm.lifetime.end
37  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %0)
38  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %0)
39  ret i32 0
40}
41
42@glob = global i8 1
43
44; CHECK-LABEL: @test_lifetime_global
45define i32 @test_lifetime_global() {
46; Check that lifetime intrinsics are removed along with the pointer.
47; CHECK-NEXT: llvm.dbg.value
48; CHECK-NEXT: ret i32 0
49; CHECK-NOT: llvm.lifetime.start
50; CHECK-NOT: llvm.lifetime.end
51  call void @llvm.lifetime.start.p0i8(i64 -1, i8* @glob)
52  call void @llvm.lifetime.end.p0i8(i64 -1, i8* @glob)
53  ret i32 0
54}
55
56; CHECK-LABEL: @test_lifetime_bitcast
57define i32 @test_lifetime_bitcast(i32*) {
58; Check that lifetime intrinsics are NOT removed when the pointer is a bitcast.
59; It's not uncommon for two bitcasts to be made: one for lifetime, one for use.
60; TODO: Support the above case.
61; CHECK-NEXT: bitcast
62; CHECK-NEXT: llvm.dbg.value
63; CHECK-NEXT: llvm.lifetime.start
64; CHECK-NEXT: llvm.lifetime.end
65; CHECK-NEXT: ret i32 0
66  %2 = bitcast i32* %0 to i8*
67  call void @llvm.lifetime.start.p0i8(i64 -1, i8* %2)
68  call void @llvm.lifetime.end.p0i8(i64 -1, i8* %2)
69  ret i32 0
70}
71
72; CHECK: [[add]] = !DILocalVariable
73; CHECK: [[sub]] = !DILocalVariable
74