| ; RUN: opt -passes='print<stack-lifetime><may>' -disable-output %s 2>&1 | FileCheck %s --check-prefixes=CHECK,MAY | |
| ; RUN: opt -passes='print<stack-lifetime><must>' -disable-output %s 2>&1 | FileCheck %s --check-prefixes=CHECK,MUST | |
| define void @f() { | |
| ; CHECK-LABEL: define void @f() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| ; CHECK: %y = alloca i32, align 4 | |
| ; CHECK-NEXT: Alive: <> | |
| %z = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <z> | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x z> | |
| call void @capture32(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <z> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y z> | |
| call void @capture32(ptr %y) | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <z> | |
| call void @capture32(ptr %z) | |
| call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @no_markers() { | |
| ; CHECK-LABEL: define void @no_markers() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <y> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x y> | |
| call void @capture32(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @capture32(ptr %y) | |
| ret void | |
| } | |
| define void @g() { | |
| ; CHECK-LABEL: define void @g() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| %z = alloca i64, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x y> | |
| call void @capture32(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @capture32(ptr %y) | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <z> | |
| call void @capture64(ptr %z) | |
| call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| ; CHECK: ret void | |
| ; CHECK-NEXT: Alive: <> | |
| } | |
| define void @h() { | |
| ; CHECK-LABEL: define void @h() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 16 | |
| ; CHECK: %x = alloca i32, align 16 | |
| ; CHECK-NEXT: Alive: <> | |
| %z = alloca i64, align 4 | |
| %y = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x y> | |
| call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <x y z> | |
| call void @capture32(ptr %x) | |
| call void @capture32(ptr %y) | |
| call void @capture64(ptr %z) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <y z> | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <z> | |
| call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @i(i1 zeroext %a, i1 zeroext %b) { | |
| ; CHECK-LABEL: define void @i(i1 zeroext %a, i1 zeroext %b) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x1 = alloca i64, align 8 | |
| %x2 = alloca i64, align 8 | |
| %y = alloca i64, align 8 | |
| %y1 = alloca i64, align 8 | |
| %y2 = alloca i64, align 8 | |
| %z = alloca i64, align 8 | |
| %z1 = alloca i64, align 8 | |
| %z2 = alloca i64, align 8 | |
| call void @llvm.lifetime.start.p0(ptr %x1) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x1) | |
| ; CHECK-NEXT: Alive: <x1> | |
| call void @llvm.lifetime.start.p0(ptr %x2) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x2) | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| call void @capture64(ptr nonnull %x1) | |
| call void @capture64(ptr nonnull %x2) | |
| br i1 %a, label %if.then, label %if.else4 | |
| ; CHECK: br i1 %a, label %if.then, label %if.else4 | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| if.then: ; preds = %entry | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x1 x2 y> | |
| call void @capture64(ptr nonnull %y) | |
| br i1 %b, label %if.then3, label %if.else | |
| if.then3: ; preds = %if.then | |
| ; CHECK: if.then3: | |
| ; CHECK-NEXT: Alive: <x1 x2 y> | |
| call void @llvm.lifetime.start.p0(ptr %y1) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y1) | |
| ; CHECK-NEXT: Alive: <x1 x2 y y1> | |
| call void @capture64(ptr nonnull %y1) | |
| call void @llvm.lifetime.end.p0(ptr %y1) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y1) | |
| ; CHECK-NEXT: Alive: <x1 x2 y> | |
| br label %if.end | |
| if.else: ; preds = %if.then | |
| ; CHECK: if.else: | |
| ; CHECK-NEXT: Alive: <x1 x2 y> | |
| call void @llvm.lifetime.start.p0(ptr %y2) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y2) | |
| ; CHECK-NEXT: Alive: <x1 x2 y y2> | |
| call void @capture64(ptr nonnull %y2) | |
| call void @llvm.lifetime.end.p0(ptr %y2) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y2) | |
| ; CHECK-NEXT: Alive: <x1 x2 y> | |
| br label %if.end | |
| if.end: ; preds = %if.else, %if.then3 | |
| ; CHECK: if.end: | |
| ; CHECK-NEXT: Alive: <x1 x2 y> | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| br label %if.end9 | |
| if.else4: ; preds = %entry | |
| ; CHECK: if.else4: | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| %z.cast = bitcast ptr %z to ptr | |
| ; CHECK: %z.cast = bitcast ptr %z to ptr | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <x1 x2 z> | |
| call void @capture64(ptr nonnull %z) | |
| br i1 %b, label %if.then6, label %if.else7 | |
| if.then6: ; preds = %if.else4 | |
| ; CHECK: if.then6: | |
| ; CHECK-NEXT: Alive: <x1 x2 z> | |
| call void @llvm.lifetime.start.p0(ptr %z1) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %z1) | |
| ; CHECK-NEXT: Alive: <x1 x2 z z1> | |
| call void @capture64(ptr nonnull %z1) | |
| call void @llvm.lifetime.end.p0(ptr %z1) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %z1) | |
| ; CHECK-NEXT: Alive: <x1 x2 z> | |
| br label %if.end8 | |
| if.else7: ; preds = %if.else4 | |
| ; CHECK: if.else7: | |
| ; CHECK-NEXT: Alive: <x1 x2 z> | |
| call void @llvm.lifetime.start.p0(ptr %z2) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %z2) | |
| ; CHECK-NEXT: Alive: <x1 x2 z z2> | |
| call void @capture64(ptr nonnull %z2) | |
| call void @llvm.lifetime.end.p0(ptr %z2) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %z2) | |
| ; CHECK-NEXT: Alive: <x1 x2 z> | |
| br label %if.end8 | |
| if.end8: ; preds = %if.else7, %if.then6 | |
| ; CHECK: if.end8: | |
| ; CHECK-NEXT: Alive: <x1 x2 z> | |
| call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %z) | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| br label %if.end9 | |
| if.end9: ; preds = %if.end8, %if.end | |
| ; CHECK: if.end9: | |
| ; CHECK-NEXT: Alive: <x1 x2> | |
| call void @llvm.lifetime.end.p0(ptr %x2) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x2) | |
| ; CHECK-NEXT: Alive: <x1> | |
| call void @llvm.lifetime.end.p0(ptr %x1) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x1) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @no_merge1(i1 %d) { | |
| ; CHECK-LABEL: define void @no_merge1(i1 %d) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @capture32(ptr %x) | |
| br i1 %d, label %bb2, label %bb3 | |
| bb2: ; preds = %entry | |
| ; CHECK: bb2: | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x y> | |
| call void @capture32(ptr %y) | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| bb3: ; preds = %entry | |
| ; CHECK: bb3: | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @merge1(i1 %d) { | |
| ; CHECK-LABEL: define void @merge1(i1 %d) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @capture32(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| br i1 %d, label %bb2, label %bb3 | |
| bb2: ; preds = %entry | |
| ; CHECK: bb2: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @capture32(ptr %y) | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| bb3: ; preds = %entry | |
| ; CHECK: bb3: | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @merge2_noend(i1 %d) { | |
| ; CHECK-LABEL: define void @merge2_noend(i1 %d) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @capture32(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| br i1 %d, label %bb2, label %bb3 | |
| bb2: ; preds = %entry | |
| ; CHECK: bb2: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @capture32(ptr %y) | |
| ret void | |
| bb3: ; preds = %entry | |
| ; CHECK: bb3: | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @merge3_noend(i1 %d) { | |
| ; CHECK-LABEL: define void @merge3_noend(i1 %d) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @capture32(ptr %x) | |
| br i1 %d, label %bb2, label %bb3 | |
| bb2: ; preds = %entry | |
| ; CHECK: bb2: | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @capture32(ptr %y) | |
| ret void | |
| bb3: ; preds = %entry | |
| ; CHECK: bb3: | |
| ; CHECK-NEXT: Alive: <x> | |
| ret void | |
| } | |
| define void @nomerge4_nostart(i1 %d) { | |
| ; CHECK-LABEL: define void @nomerge4_nostart(i1 %d) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <x> | |
| %x = alloca i32, align 4 | |
| %y = alloca i32, align 4 | |
| call void @capture32(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| br i1 %d, label %bb2, label %bb3 | |
| bb2: ; preds = %entry | |
| ; CHECK: bb2: | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x y> | |
| call void @capture32(ptr %y) | |
| ret void | |
| bb3: ; preds = %entry | |
| ; CHECK: bb3: | |
| ; CHECK-NEXT: Alive: <x> | |
| ret void | |
| } | |
| define void @array_merge() { | |
| ; CHECK-LABEL: define void @array_merge() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %A.i1 = alloca [100 x i32], align 4 | |
| %B.i2 = alloca [100 x i32], align 4 | |
| %A.i = alloca [100 x i32], align 4 | |
| %B.i = alloca [100 x i32], align 4 | |
| call void @llvm.lifetime.start.p0(ptr %A.i) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %A.i) | |
| ; CHECK-NEXT: Alive: <A.i> | |
| call void @llvm.lifetime.start.p0(ptr %B.i) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %B.i) | |
| ; CHECK-NEXT: Alive: <A.i B.i> | |
| call void @capture100x32(ptr %A.i) | |
| ; CHECK: call void @capture100x32(ptr %A.i) | |
| ; CHECK-NEXT: Alive: <A.i B.i> | |
| call void @capture100x32(ptr %B.i) | |
| call void @llvm.lifetime.end.p0(ptr %A.i) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %A.i) | |
| ; CHECK-NEXT: Alive: <B.i> | |
| call void @llvm.lifetime.end.p0(ptr %B.i) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %B.i) | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %A.i1) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %A.i1) | |
| ; CHECK-NEXT: Alive: <A.i1> | |
| call void @llvm.lifetime.start.p0(ptr %B.i2) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %B.i2) | |
| ; CHECK-NEXT: Alive: <A.i1 B.i2> | |
| call void @capture100x32(ptr %A.i1) | |
| call void @capture100x32(ptr %B.i2) | |
| call void @llvm.lifetime.end.p0(ptr %A.i1) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %A.i1) | |
| ; CHECK-NEXT: Alive: <B.i2> | |
| call void @llvm.lifetime.end.p0(ptr %B.i2) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %B.i2) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @myCall_pr15707() { | |
| ; CHECK-LABEL: define void @myCall_pr15707() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %buf1 = alloca i8, i32 100000, align 16 | |
| %buf2 = alloca i8, i32 100000, align 16 | |
| call void @llvm.lifetime.start.p0(ptr %buf1) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %buf1) | |
| ; CHECK-NEXT: Alive: <buf1> | |
| call void @llvm.lifetime.end.p0(ptr %buf1) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %buf1) | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %buf1) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %buf1) | |
| ; CHECK-NEXT: Alive: <buf1> | |
| call void @llvm.lifetime.start.p0(ptr %buf2) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %buf2) | |
| ; CHECK-NEXT: Alive: <buf1 buf2> | |
| call void @capture8(ptr %buf1) | |
| call void @capture8(ptr %buf2) | |
| ret void | |
| } | |
| define void @bad_range() { | |
| ; CHECK-LABEL: define void @bad_range() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <A.i1 B.i2> | |
| %A.i1 = alloca [100 x i32], align 4 | |
| %B.i2 = alloca [100 x i32], align 4 | |
| %A.i = alloca [100 x i32], align 4 | |
| %B.i = alloca [100 x i32], align 4 | |
| call void @llvm.lifetime.start.p0(ptr %A.i) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %A.i) | |
| ; CHECK-NEXT: Alive: <A.i A.i1 B.i2> | |
| call void @llvm.lifetime.start.p0(ptr %B.i) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %B.i) | |
| ; CHECK-NEXT: Alive: <A.i A.i1 B.i B.i2> | |
| call void @capture100x32(ptr %A.i) | |
| call void @capture100x32(ptr %B.i) | |
| call void @llvm.lifetime.end.p0(ptr %A.i) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %A.i) | |
| ; CHECK-NEXT: Alive: <A.i1 B.i B.i2> | |
| call void @llvm.lifetime.end.p0(ptr %B.i) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %B.i) | |
| ; CHECK-NEXT: Alive: <A.i1 B.i2> | |
| br label %block2 | |
| block2: ; preds = %entry | |
| ; CHECK: block2: | |
| ; CHECK-NEXT: Alive: <A.i1 B.i2> | |
| call void @capture100x32(ptr %A.i) | |
| call void @capture100x32(ptr %B.i) | |
| ret void | |
| } | |
| %struct.Klass = type { i32, i32 } | |
| define i32 @shady_range(i32 %argc, ptr captures(none) %argv) { | |
| ; CHECK-LABEL: define i32 @shady_range(i32 %argc, ptr captures(none) %argv) | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %a.i = alloca [4 x %struct.Klass], align 16 | |
| %b.i = alloca [4 x %struct.Klass], align 16 | |
| call void @llvm.lifetime.start.p0(ptr %a.i) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %a.i) | |
| ; CHECK-NEXT: Alive: <a.i> | |
| call void @llvm.lifetime.start.p0(ptr %b.i) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %b.i) | |
| ; CHECK-NEXT: Alive: <a.i b.i> | |
| call void @capture8(ptr %a.i) | |
| call void @capture8(ptr %b.i) | |
| %z3 = load i32, ptr %a.i, align 16 | |
| call void @llvm.lifetime.end.p0(ptr %a.i) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %a.i) | |
| ; CHECK-NEXT: Alive: <b.i> | |
| call void @llvm.lifetime.end.p0(ptr %b.i) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %b.i) | |
| ; CHECK-NEXT: Alive: <> | |
| ret i32 %z3 | |
| } | |
| define void @end_loop() { | |
| ; CHECK-LABEL: define void @end_loop() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| br label %l2 | |
| l2: ; preds = %l2, %entry | |
| ; CHECK: l2: | |
| ; MAY-NEXT: Alive: <x> | |
| ; MUST-NEXT: Alive: <> | |
| call void @capture8(ptr %x) | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| br label %l2 | |
| } | |
| define void @start_loop() { | |
| ; CHECK-LABEL: define void @start_loop() | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| %y = alloca i8, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| br label %l2 | |
| l2: ; preds = %l2, %entry | |
| ; CHECK: l2: | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x y> | |
| call void @capture8(ptr %y) | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @capture8(ptr %x) | |
| br label %l2 | |
| } | |
| %struct.char_array = type { [500 x i8] } | |
| define dso_local void @gep_test(i32 %cond) { | |
| ; CHECK-LABEL: define dso_local void @gep_test | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %a = alloca %struct.char_array, align 8 | |
| %b = alloca %struct.char_array, align 8 | |
| %tobool.not = icmp eq i32 %cond, 0 | |
| br i1 %tobool.not, label %if.else, label %if.then | |
| if.then: ; preds = %entry | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr nonnull %a) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr nonnull %a) | |
| ; CHECK-NEXT: Alive: <a> | |
| tail call void @capture8(ptr %a) | |
| call void @llvm.lifetime.end.p0(ptr nonnull %a) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr nonnull %a) | |
| ; CHECK-NEXT: Alive: <> | |
| br label %if.end | |
| if.else: ; preds = %entry | |
| ; CHECK: if.else: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr nonnull %b) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr nonnull %b) | |
| ; CHECK-NEXT: Alive: <b> | |
| tail call void @capture8(ptr %b) | |
| call void @llvm.lifetime.end.p0(ptr nonnull %b) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr nonnull %b) | |
| ; CHECK-NEXT: Alive: <> | |
| br label %if.end | |
| if.end: ; preds = %if.else, %if.then | |
| ; CHECK: if.end: | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @if_must(i1 %a) { | |
| ; CHECK-LABEL: define void @if_must | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| %y = alloca i8, align 4 | |
| br i1 %a, label %if.then, label %if.else | |
| ; CHECK: br i1 %a, label %if.then, label %if.else | |
| ; CHECK-NEXT: Alive: <> | |
| if.then: | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| br label %if.end | |
| ; CHECK: br label %if.end | |
| ; CHECK-NEXT: Alive: <y> | |
| if.else: | |
| ; CHECK: if.else: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x y> | |
| br label %if.end | |
| ; CHECK: br label %if.end | |
| ; CHECK-NEXT: Alive: <x y> | |
| if.end: | |
| ; CHECK: if.end: | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <y> | |
| ret void | |
| } | |
| define void @unreachable() { | |
| ; CHECK-LABEL: define void @unreachable | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| %y = alloca i8, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x y> | |
| br label %end | |
| ; CHECK: br label %end | |
| ; CHECK-NEXT: Alive: <x y> | |
| dead: | |
| ; CHECK: dead: | |
| ; CHECK-NOT: Alive: | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| br label %end | |
| ; CHECK: br label %end | |
| ; CHECK-NOT: Alive: | |
| end: | |
| ; CHECK: end: | |
| ; CHECK-NEXT: Alive: <x y> | |
| ret void | |
| } | |
| define void @multiple_start_end() { | |
| ; CHECK-LABEL: define void @multiple_start_end | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @if_must1(i1 %a) { | |
| ; CHECK-LABEL: define void @if_must1 | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| %y = alloca i8, align 4 | |
| br i1 %a, label %if.then, label %if.else | |
| ; CHECK: br i1 %a, label %if.then, label %if.else | |
| ; CHECK-NEXT: Alive: <> | |
| if.then: | |
| ; CHECK: if.then: | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <> | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; MAY-NEXT: Alive: <x> | |
| ; MUST-NEXT: Alive: <> | |
| br label %if.end | |
| ; CHECK: br label %if.end | |
| ; MAY-NEXT: Alive: <x> | |
| ; MUST-NEXT: Alive: <> | |
| if.else: | |
| ; CHECK: if.else: | |
| ; CHECK-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <y> | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x y> | |
| br label %if.then | |
| ; CHECK: br label %if.then | |
| ; CHECK-NEXT: Alive: <x y> | |
| if.end: | |
| ; CHECK: if.end: | |
| ; MAY-NEXT: Alive: <x> | |
| ; MUST-NEXT: Alive: <> | |
| ret void | |
| } | |
| define void @if_must2(i1 %a) { | |
| ; CHECK-LABEL: define void @if_must2 | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| %y = alloca i8, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| br i1 %a, label %if.then, label %if.else | |
| ; CHECK: br i1 %a, label %if.then, label %if.else | |
| ; CHECK-NEXT: Alive: <x> | |
| if.then: | |
| ; CHECK: if.then: | |
| ; MAY-NEXT: Alive: <x> | |
| ; MUST-NEXT: Alive: <> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <y> | |
| br label %if.end | |
| ; CHECK: br label %if.end | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <y> | |
| if.else: | |
| ; CHECK: if.else: | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x> | |
| call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.end.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <> | |
| br label %if.then | |
| ; CHECK: br label %if.then | |
| ; CHECK-NEXT: Alive: <> | |
| if.end: | |
| ; CHECK: if.end: | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <y> | |
| ret void | |
| } | |
| define void @cycle(i1 %a) { | |
| ; CHECK-LABEL: define void @cycle | |
| entry: | |
| ; CHECK: entry: | |
| ; CHECK-NEXT: Alive: <> | |
| %x = alloca i8, align 4 | |
| %y = alloca i8, align 4 | |
| call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %x) | |
| ; CHECK-NEXT: Alive: <x> | |
| br i1 %a, label %if.then, label %if.end | |
| ; CHECK: br i1 %a, label %if.then, label %if.end | |
| ; CHECK-NEXT: Alive: <x> | |
| if.then: | |
| ; CHECK: if.then: | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <x> | |
| call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK: call void @llvm.lifetime.start.p0(ptr %y) | |
| ; CHECK-NEXT: Alive: <x y> | |
| br i1 %a, label %if.then, label %if.end | |
| ; CHECK: br i1 %a, label %if.then, label %if.end | |
| ; CHECK-NEXT: Alive: <x y> | |
| if.end: | |
| ; CHECK: if.end: | |
| ; MAY-NEXT: Alive: <x y> | |
| ; MUST-NEXT: Alive: <x> | |
| ret void | |
| } | |
| declare void @llvm.lifetime.start.p0(ptr captures(none)) | |
| declare void @llvm.lifetime.end.p0(ptr captures(none)) | |
| declare void @capture8(ptr) | |
| declare void @capture32(ptr) | |
| declare void @capture64(ptr) | |
| declare void @capture100x32(ptr) |