+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S -ipsccp < %s | FileCheck %s
declare void @BB0_f()
; Make sure we can eliminate what is in BB0 as we know that the indirectbr is going to BB1.
;
-; CHECK-LABEL: define void @indbrtest1(
-; CHECK-NOT: call void @BB0_f()
-; CHECK: ret void
define void @indbrtest1() {
+; CHECK-LABEL: @indbrtest1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB1:%.*]]
+; CHECK: BB1:
+; CHECK-NEXT: call void @BB1_f()
+; CHECK-NEXT: ret void
+;
entry:
indirectbr i8* blockaddress(@indbrtest1, %BB1), [label %BB0, label %BB1]
BB0:
; by looking through the casts. The casts should be folded away when they are visited
; before the indirectbr instruction.
;
-; CHECK-LABEL: define void @indbrtest2(
-; CHECK-NOT: call void @BB0_f()
-; CHECK: ret void
define void @indbrtest2() {
+; CHECK-LABEL: @indbrtest2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB1:%.*]]
+; CHECK: BB1:
+; CHECK-NEXT: call void @BB1_f()
+; CHECK-NEXT: ret void
+;
entry:
%a = ptrtoint i8* blockaddress(@indbrtest2, %BB1) to i64
%b = inttoptr i64 %a to i8*
}
; Make sure we can not eliminate BB0 as we do not know the target of the indirectbr.
-;
-; CHECK-LABEL: define void @indbrtest3(
-; CHECK: call void @BB0_f()
-; CHECK: ret void
+
define void @indbrtest3(i8** %Q) {
+; CHECK-LABEL: @indbrtest3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[T:%.*]] = load i8*, i8** [[Q:%.*]], align 8
+; CHECK-NEXT: indirectbr i8* [[T]], [label [[BB0:%.*]], label %BB1]
+; CHECK: BB0:
+; CHECK-NEXT: call void @BB0_f()
+; CHECK-NEXT: br label [[BB1:%.*]]
+; CHECK: BB1:
+; CHECK-NEXT: call void @BB1_f()
+; CHECK-NEXT: ret void
+;
entry:
%t = load i8*, i8** %Q
indirectbr i8* %t, [label %BB0, label %BB1]
}
; Make sure we eliminate BB1 as we pick the first successor on undef.
-;
-; CHECK-LABEL: define void @indbrtest4(
-; CHECK: call void @BB0_f()
-; CHECK: ret void
+
define void @indbrtest4(i8** %Q) {
+; CHECK-LABEL: @indbrtest4(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[BB0:%.*]]
+; CHECK: BB0:
+; CHECK-NEXT: call void @BB0_f()
+; CHECK-NEXT: ret void
+;
entry:
indirectbr i8* undef, [label %BB0, label %BB1]
BB0:
call void @BB0_f()
- br label %BB1
+ ret void
BB1:
call void @BB1_f()
ret void
}
-
-; CHECK-LABEL: define internal i32 @indbrtest5(
-; CHECK: ret i32 undef
define internal i32 @indbrtest5(i1 %c) {
+; CHECK-LABEL: @indbrtest5(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK: bb1:
+; CHECK-NEXT: br label [[BRANCH_BLOCK:%.*]]
+; CHECK: bb2:
+; CHECK-NEXT: br label [[BRANCH_BLOCK]]
+; CHECK: branch.block:
+; CHECK-NEXT: [[ADDR:%.*]] = phi i8* [ blockaddress(@indbrtest5, [[TARGET1:%.*]]), [[BB1]] ], [ blockaddress(@indbrtest5, [[TARGET2:%.*]]), [[BB2]] ]
+; CHECK-NEXT: indirectbr i8* [[ADDR]], [label [[TARGET1]], label %target2]
+; CHECK: target1:
+; CHECK-NEXT: br label [[TARGET2]]
+; CHECK: target2:
+; CHECK-NEXT: ret i32 undef
+;
entry:
br i1 %c, label %bb1, label %bb2
define i32 @indbrtest5_callee(i1 %c) {
-; CHECK-LABEL: define i32 @indbrtest5_callee(
-; CHECK-NEXT: %r = call i32 @indbrtest5(i1 %c)
+; CHECK-LABEL: @indbrtest5_callee(
+; CHECK-NEXT: [[R:%.*]] = call i32 @indbrtest5(i1 [[C:%.*]])
; CHECK-NEXT: ret i32 10
+;
%r = call i32 @indbrtest5(i1 %c)
ret i32 %r
}