123 lines · plain
1; RUN: not opt -S %s -passes=verify 2>&1 | FileCheck %s2 3; CHECK: Number of label constraints does not match number of callbr dests4; CHECK-NEXT: #too_few_label_constraints5define void @too_few_label_constraints() {6 callbr void asm sideeffect "#too_few_label_constraints", "!i"()7 to label %1 [label %2, label %3]81:9 ret void102:11 ret void123:13 ret void14}15 16; CHECK-NOT: Number of label constraints does not match number of callbr dests17define void @correct_label_constraints() {18 callbr void asm sideeffect "${0:l} ${1:l}", "!i,!i"()19 to label %1 [label %2, label %3]201:21 ret void222:23 ret void243:25 ret void26}27 28; CHECK: Number of label constraints does not match number of callbr dests29; CHECK-NEXT: #too_many_label_constraints30define void @too_many_label_constraints() {31 callbr void asm sideeffect "#too_many_label_constraints", "!i,!i,!i"()32 to label %1 [label %2, label %3]331:34 ret void352:36 ret void373:38 ret void39}40 41; CHECK: Label constraints can only be used with callbr42; CHECK-NEXT: #label_constraint_without_callbr43define void @label_constraint_without_callbr() {44 call void asm sideeffect "#label_constraint_without_callbr", "!i"()45 ret void46}47 48; CHECK: Number of label constraints does not match number of callbr dests49; CHECK-NEXT: #callbr_without_label_constraint50define void @callbr_without_label_constraint() {51 callbr void asm sideeffect "#callbr_without_label_constraint", ""()52 to label %1 [label %2]531:54 ret void552:56 ret void57}58 59;; Ensure you can use the return value of a callbr in indirect targets.60;; No issue!61define i32 @test4(i1 %var) {62entry:63 %ret = callbr i32 asm sideeffect "#test4", "=r,!i"() to label %normal [label %abnormal]64 65normal:66 ret i32 067 68abnormal:69 ret i32 %ret70}71 72;; Tests of the callbr.landingpad intrinsic function.73declare i32 @llvm.callbr.landingpad.i64(i64)74define void @callbrpad_bad_type() {75entry:76; CHECK: Intrinsic has incorrect argument type!77; CHECK-NEXT: ptr @llvm.callbr.landingpad.i6478 %foo = call i32 @llvm.callbr.landingpad.i64(i64 42)79 ret void80}81 82declare i32 @llvm.callbr.landingpad.i32(i32)83define i32 @callbrpad_multi_preds() {84entry:85 %foo = callbr i32 asm "", "=r,!i"() to label %direct [label %indirect]86direct:87 br label %indirect88indirect:89; CHECK-NEXT: Intrinsic in block must have 1 unique predecessor90; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32(i32 %foo)91 %out = call i32 @llvm.callbr.landingpad.i32(i32 %foo)92 ret i32 %out93}94 95define void @callbrpad_wrong_callbr() {96entry:97 %foo = callbr i32 asm "", "=r,!i"() to label %direct [label %indirect]98direct:99; CHECK-NEXT: Intrinsic's corresponding callbr must have intrinsic's parent basic block in indirect destination list100; CHECK-NEXT: %x = call i32 @llvm.callbr.landingpad.i32(i32 %foo)101 %x = call i32 @llvm.callbr.landingpad.i32(i32 %foo)102 ret void103indirect:104 ret void105}106 107declare i32 @foo(i32)108define i32 @test_callbr_landingpad_not_first_inst() {109entry:110 %0 = callbr i32 asm "", "=r,!i"()111 to label %asm.fallthrough [label %landingpad]112 113asm.fallthrough:114 ret i32 42115 116landingpad:117 %foo = call i32 @foo(i32 42)118; CHECK-NEXT: No other instructions may proceed intrinsic119; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32(i32 %0)120 %out = call i32 @llvm.callbr.landingpad.i32(i32 %0)121 ret i32 %out122}123