diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -622,7 +622,8 @@ // This intrinsic is intentionally undocumented and users shouldn't call it; // it's produced then quickly consumed during codegen. -def int_callbr_landingpad : Intrinsic<[llvm_any_ty], [], [IntrNoMerge]>; +def int_callbr_landingpad : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>], + [IntrNoMerge]>; //===------------------- Standard C Library Intrinsics --------------------===// // diff --git a/llvm/lib/CodeGen/CallBrPrepare.cpp b/llvm/lib/CodeGen/CallBrPrepare.cpp --- a/llvm/lib/CodeGen/CallBrPrepare.cpp +++ b/llvm/lib/CodeGen/CallBrPrepare.cpp @@ -42,6 +42,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" @@ -132,7 +133,7 @@ continue; Builder.SetInsertPoint(&*IndDest->begin()); CallInst *Intrinsic = Builder.CreateIntrinsic( - CBR->getType(), llvm::Intrinsic::callbr_landingpad, {}); + CBR->getType(), Intrinsic::callbr_landingpad, {CBR}); SSAUpdate.AddAvailableValue(IndDest, Intrinsic); UpdateSSA(DT, CBR, Intrinsic, SSAUpdate); Changed = true; @@ -176,6 +177,11 @@ PrintDebugDomInfo(DT, *U, DefaultDest, /*IsDefaultDest*/ true); #endif + // Don't rewrite the use in the newly inserted intrinsic. + if (const auto *II = dyn_cast(U->getUser())) + if (II->getIntrinsicID() == Intrinsic::callbr_landingpad) + continue; + // If the Use is in the same BasicBlock as the Intrinsic call, replace // the Use with the value of the Intrinsic call. if (IsInSameBasicBlock(*U, LandingPad)) { diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -31,7 +31,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" -#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -41,26 +41,12 @@ #define DEBUG_TYPE "function-lowering-info" -static bool isUsedOutsideOfDefiningBlock(const CallBrInst *CBR) { - return llvm::any_of(CBR->getIndirectDests(), [](BasicBlock *Dest) { - if (const auto *CI = dyn_cast(Dest->begin())) { - if (Function *F = CI->getCalledFunction()) { - return F->getIntrinsicID() == Intrinsic::callbr_landingpad; - } - } - return false; - }); -} - /// isUsedOutsideOfDefiningBlock - Return true if this instruction is used by /// PHI nodes or outside of the basic block that defines it, or used by a /// switch or atomic instruction, which may expand to multiple basic blocks. static bool isUsedOutsideOfDefiningBlock(const Instruction *I) { - if (I->use_empty()) { - if (const auto *CBR = dyn_cast(I)) - return isUsedOutsideOfDefiningBlock(CBR); + if (I->use_empty()) return false; - } if (isa(I)) return true; const BasicBlock *BB = I->getParent(); for (const User *U : I->users()) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2123,8 +2123,7 @@ DenseMap::iterator VMI = FuncInfo.ValueMap.find(V); if (VMI != FuncInfo.ValueMap.end()) { - assert((!V->use_empty() || isa(V)) && - "Unused value assigned virtual registers!"); + assert(!V->use_empty() && "Unused value assigned virtual registers!"); CopyValueToVirtualRegister(V, VMI->second); } } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -5825,14 +5825,18 @@ break; } case Intrinsic::callbr_landingpad: { + const auto *CBR = dyn_cast(Call.getOperand(0)); + Check(CBR, "intrinstic requires callbr operand", &Call); + if (!CBR) + break; + const BasicBlock *LandingPadBB = Call.getParent(); - const BasicBlock *CallBrBB = LandingPadBB->getUniquePredecessor(); - if (!CallBrBB) { + const BasicBlock *PredBB = LandingPadBB->getUniquePredecessor(); + if (!PredBB) { CheckFailed("Intrinsic in block must have 1 unique predecessor", &Call); break; } - const auto *CBR = dyn_cast(CallBrBB->getTerminator()); - if (!CBR) { + if (!isa(PredBB->getTerminator())) { CheckFailed("Intrinsic must have corresponding callbr in predecessor", &Call); break; @@ -5844,8 +5848,6 @@ "Intrinsic's corresponding callbr must have intrinsic's parent basic " "block in indirect destination list", &Call); - Check(!CBR->getType()->isVoidTy(), - "intrinsic's corresponding callbr must return a value", &Call); const Instruction &First = *LandingPadBB->begin(); Check(&First == &Call, "No other instructions may proceed intrinsic", &Call); diff --git a/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll --- a/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll +++ b/llvm/test/CodeGen/AArch64/callbr-asm-outputs-indirect-isel.ll @@ -55,7 +55,7 @@ to label %direct [label %entry.indirect_crit_edge] entry.indirect_crit_edge: ; preds = %entry - %0 = call i32 @llvm.callbr.landingpad.i32() + %0 = call i32 @llvm.callbr.landingpad.i32(i32 %out) br label %indirect direct: ; preds = %entry @@ -63,7 +63,7 @@ to label %direct2 [label %direct.indirect_crit_edge] direct.indirect_crit_edge: ; preds = %direct - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %out2) br label %indirect direct2: ; preds = %direct @@ -127,7 +127,7 @@ ret i32 42 y: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) ret i32 %1 } @@ -220,7 +220,7 @@ to label %x [label %entry.y_crit_edge] entry.y_crit_edge: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %y x: ; preds = %entry @@ -272,7 +272,7 @@ to label %x [label %w.v_crit_edge, label %w.v_crit_edge] w.v_crit_edge: ; preds = %w, %w - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %v x: ; preds = %w @@ -325,7 +325,7 @@ to label %x [label %w.v_crit_edge, label %w.v_crit_edge] w.v_crit_edge: ; preds = %w, %w - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %v x: ; preds = %w @@ -367,7 +367,7 @@ br label %out y: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %out out: ; preds = %y, %x @@ -398,7 +398,7 @@ to label %out [label %y] y: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %out out: ; preds = %y, %entry @@ -434,7 +434,7 @@ to label %y [label %entry.out_crit_edge] entry.out_crit_edge: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %out y: ; preds = %entry @@ -481,7 +481,7 @@ to label %exit [label %loop.loop_crit_edge] loop.loop_crit_edge: ; preds = %loop - %3 = call i32 @llvm.callbr.landingpad.i32() + %3 = call i32 @llvm.callbr.landingpad.i32(i32 %2) br label %loop exit: ; preds = %loop @@ -511,7 +511,7 @@ to label %same [label %entry.same_crit_edge] entry.same_crit_edge: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %same same: ; preds = %entry.same_crit_edge, %entry @@ -542,7 +542,7 @@ to label %same [label %entry.same_crit_edge] entry.same_crit_edge: ; preds = %entry - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %same same: ; preds = %entry.same_crit_edge, %entry @@ -551,9 +551,9 @@ } ; Function Attrs: nounwind -declare i32 @llvm.callbr.landingpad.i32() #0 +declare i32 @llvm.callbr.landingpad.i32(i32) #0 ; Function Attrs: nounwind -declare i64 @llvm.callbr.landingpad.i64() #0 +declare i64 @llvm.callbr.landingpad.i64(i64) #0 attributes #0 = { nounwind } diff --git a/llvm/test/CodeGen/AArch64/callbr-prepare.ll b/llvm/test/CodeGen/AArch64/callbr-prepare.ll --- a/llvm/test/CodeGen/AArch64/callbr-prepare.ll +++ b/llvm/test/CodeGen/AArch64/callbr-prepare.ll @@ -7,13 +7,13 @@ ; CHECK-NEXT: [[OUT:%.*]] = callbr i32 asm "# $0", "=r,!i"() ; CHECK-NEXT: to label [[DIRECT:%.*]] [label %entry.indirect_crit_edge] ; CHECK: entry.indirect_crit_edge: -; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[OUT]]) ; CHECK-NEXT: br label [[INDIRECT:%.*]] ; CHECK: direct: ; CHECK-NEXT: [[OUT2:%.*]] = callbr i32 asm "# $0", "=r,!i"() ; CHECK-NEXT: to label [[DIRECT2:%.*]] [label %direct.indirect_crit_edge] ; CHECK: direct.indirect_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[OUT2]]) ; CHECK-NEXT: br label [[INDIRECT]] ; CHECK: direct2: ; CHECK-NEXT: ret i32 0 @@ -71,7 +71,7 @@ ; CHECK: x: ; CHECK-NEXT: ret i32 42 ; CHECK: y: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: ret i32 [[TMP1]] ; entry: @@ -143,7 +143,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"() ; CHECK-NEXT: to label [[X:%.*]] [label %entry.y_crit_edge] ; CHECK: entry.y_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[Y:%.*]] ; CHECK: x: ; CHECK-NEXT: br label [[Y]] @@ -174,7 +174,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,!i"() ; CHECK-NEXT: to label [[X:%.*]] [label [[W_V_CRIT_EDGE:%.*]], label %w.v_crit_edge] ; CHECK: w.v_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[V]] ; CHECK: x: ; CHECK-NEXT: ret i32 42 @@ -207,7 +207,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i,!i"() ; CHECK-NEXT: to label [[X:%.*]] [label [[W_V_CRIT_EDGE:%.*]], label %w.v_crit_edge] ; CHECK: w.v_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[V]] ; CHECK: x: ; CHECK-NEXT: ret i32 42 @@ -239,7 +239,7 @@ ; CHECK: x: ; CHECK-NEXT: br label [[OUT:%.*]] ; CHECK: y: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: ; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[Y:%.*]] ], [ [[TMP0]], [[X]] ] @@ -266,7 +266,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"() ; CHECK-NEXT: to label [[OUT:%.*]] [label %y] ; CHECK: y: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[OUT]] ; CHECK: out: ; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[Y:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ] @@ -290,7 +290,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"() ; CHECK-NEXT: to label [[Y:%.*]] [label %entry.out_crit_edge] ; CHECK: entry.out_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[OUT:%.*]] ; CHECK: y: ; CHECK-NEXT: br label [[OUT]] @@ -319,7 +319,7 @@ ; CHECK-NEXT: [[TMP2:%.*]] = callbr i32 asm "", "=r,0,!i"(i32 [[TMP1]]) ; CHECK-NEXT: to label [[EXIT:%.*]] [label %loop.loop_crit_edge] ; CHECK: loop.loop_crit_edge: -; CHECK-NEXT: [[TMP3]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP3]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP2]]) ; CHECK-NEXT: br label [[LOOP]] ; CHECK: exit: ; CHECK-NEXT: ret i32 0 @@ -340,7 +340,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"() ; CHECK-NEXT: to label [[SAME:%.*]] [label %entry.same_crit_edge] ; CHECK: entry.same_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[SAME]] ; CHECK: same: ; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[ENTRY_SAME_CRIT_EDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ] @@ -359,7 +359,7 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i32 asm "", "=r,!i"() ; CHECK-NEXT: to label [[SAME:%.*]] [label %entry.same_crit_edge] ; CHECK: entry.same_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: br label [[SAME]] ; CHECK: same: ; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP1]], [[ENTRY_SAME_CRIT_EDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ] @@ -380,13 +380,13 @@ ; CHECK-NEXT: [[TMP0:%.*]] = callbr i64 asm "# $0 $1", "={dx},!i"() ; CHECK-NEXT: to label [[ASM_FALLTHROUGH:%.*]] [label %entry.foo_crit_edge] ; CHECK: entry.foo_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.callbr.landingpad.i64() +; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.callbr.landingpad.i64(i64 [[TMP0]]) ; CHECK-NEXT: br label [[FOO:%.*]] ; CHECK: asm.fallthrough: ; CHECK-NEXT: [[TMP2:%.*]] = callbr i64 asm "# $0 $1", "={bx},!i"() ; CHECK-NEXT: to label [[FOO]] [label %asm.fallthrough.foo_crit_edge] ; CHECK: asm.fallthrough.foo_crit_edge: -; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.callbr.landingpad.i64() +; CHECK-NEXT: [[TMP3:%.*]] = call i64 @llvm.callbr.landingpad.i64(i64 [[TMP2]]) ; CHECK-NEXT: br label [[FOO]] ; CHECK: foo: ; CHECK-NEXT: [[X_0:%.*]] = phi i64 [ [[TMP1]], [[ENTRY_FOO_CRIT_EDGE:%.*]] ], [ [[TMP3]], [[ASM_FALLTHROUGH_FOO_CRIT_EDGE:%.*]] ], [ [[TMP2]], [[ASM_FALLTHROUGH]] ] @@ -415,7 +415,7 @@ ; CHECK: x: ; CHECK-NEXT: ret i32 42 ; CHECK: y: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[TMP0]]) ; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], [[TMP1]] ; CHECK-NEXT: ret i32 [[TMP2]] ; diff --git a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll --- a/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll +++ b/llvm/test/CodeGen/X86/callbr-asm-outputs-indirect-isel.ll @@ -26,7 +26,7 @@ cleanup: ret i32 42 z.split: - %indirect = call i32 @llvm.callbr.landingpad.i32() + %indirect = call i32 @llvm.callbr.landingpad.i32(i32 %direct) ret i32 %indirect } @@ -55,7 +55,7 @@ to label %cleanup [label %z.split] z.split: - %indirect = call i32 @llvm.callbr.landingpad.i32() + %indirect = call i32 @llvm.callbr.landingpad.i32(i32 %direct) br label %cleanup cleanup: @@ -89,7 +89,7 @@ to label %cleanup [label %z.split] z.split: - %indirect = call { i32, i32 } @llvm.callbr.landingpad.sl_i32i32s() + %indirect = call { i32, i32 } @llvm.callbr.landingpad.sl_i32i32s({ i32, i32 } %direct) %asmresult2 = extractvalue { i32, i32 } %indirect, 0 br label %cleanup @@ -126,7 +126,7 @@ to label %cleanup [label %z.split] z.split: - %indirect = call i32 @llvm.callbr.landingpad.i32() + %indirect = call i32 @llvm.callbr.landingpad.i32(i32 %direct) br label %cleanup cleanup: @@ -164,7 +164,7 @@ to label %cleanup [label %z.split] z.split: - %indirect = call { i32, i32 } @llvm.callbr.landingpad.sl_i32i32s() + %indirect = call { i32, i32 } @llvm.callbr.landingpad.sl_i32i32s({ i32, i32 } %direct) %asmresult2 = extractvalue { i32, i32 } %indirect, 0 br label %cleanup @@ -196,7 +196,7 @@ to label %cleanup [label %cleanup] cleanup: - %indirect = call i32 @llvm.callbr.landingpad.i32() + %indirect = call i32 @llvm.callbr.landingpad.i32(i32 %direct) ret i32 %indirect } @@ -253,11 +253,11 @@ ret i64 %x.0 foo.split: - %2 = call i64 @llvm.callbr.landingpad.i64() + %2 = call i64 @llvm.callbr.landingpad.i64(i64 %0) br label %foo foo.split2: - %3 = call i64 @llvm.callbr.landingpad.i64() + %3 = call i64 @llvm.callbr.landingpad.i64(i64 %1) br label %foo } @@ -303,7 +303,7 @@ ret i32 %0 retry.split: - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %0) br label %retry } @@ -327,10 +327,10 @@ to label %cleanup [label %cleanup] cleanup: - %indirect = call i32 @llvm.callbr.landingpad.i32() + %indirect = call i32 @llvm.callbr.landingpad.i32(i32 %direct) ret i32 %indirect } -declare i64 @llvm.callbr.landingpad.i64() -declare i32 @llvm.callbr.landingpad.i32() -declare { i32, i32 } @llvm.callbr.landingpad.sl_i32i32s() +declare i64 @llvm.callbr.landingpad.i64(i64) +declare i32 @llvm.callbr.landingpad.i32(i32) +declare { i32, i32 } @llvm.callbr.landingpad.sl_i32i32s({ i32, i32 }) diff --git a/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll --- a/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll +++ b/llvm/test/Transforms/SimplifyCFG/callbr-destinations.ll @@ -67,13 +67,13 @@ ; CHECK-NEXT: [[OUT:%.*]] = callbr i32 asm "# $0", "=r,!i"() ; CHECK-NEXT: to label [[DIRECT:%.*]] [label %entry.indirect_crit_edge] ; CHECK: entry.indirect_crit_edge: -; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[OUT]]) ; CHECK-NEXT: br label [[COMMON_RET:%.*]] ; CHECK: direct: ; CHECK-NEXT: [[OUT2:%.*]] = callbr i32 asm "# $0", "=r,!i"() ; CHECK-NEXT: to label [[COMMON_RET]] [label %direct.indirect_crit_edge] ; CHECK: direct.indirect_crit_edge: -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.callbr.landingpad.i32(i32 [[OUT2]]) ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: common.ret: ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ 0, [[DIRECT]] ], [ [[TMP0]], [[ENTRY_INDIRECT_CRIT_EDGE:%.*]] ], [ [[TMP1]], [[DIRECT_INDIRECT_CRIT_EDGE:%.*]] ] @@ -84,7 +84,7 @@ to label %direct [label %entry.indirect_crit_edge] entry.indirect_crit_edge: - %0 = call i32 @llvm.callbr.landingpad.i32() + %0 = call i32 @llvm.callbr.landingpad.i32(i32 %out) br label %indirect direct: @@ -92,7 +92,7 @@ to label %direct2 [label %direct.indirect_crit_edge] direct.indirect_crit_edge: - %1 = call i32 @llvm.callbr.landingpad.i32() + %1 = call i32 @llvm.callbr.landingpad.i32(i32 %out2) br label %indirect direct2: @@ -103,4 +103,4 @@ ret i32 %out3 } -declare i32 @llvm.callbr.landingpad.i32() +declare i32 @llvm.callbr.landingpad.i32(i32) diff --git a/llvm/test/Verifier/callbr.ll b/llvm/test/Verifier/callbr.ll --- a/llvm/test/Verifier/callbr.ll +++ b/llvm/test/Verifier/callbr.ll @@ -70,8 +70,7 @@ } ;; Tests of the callbr.landingpad intrinsic function. -; The intrinsic does not accept parameters. -declare i32 @llvm.callbr.landingpad.i64(i64 %x) +declare i32 @llvm.callbr.landingpad.i64(i64) define void @callbrpad_bad_type() { entry: ; CHECK: Intrinsic has incorrect argument type! @@ -80,7 +79,7 @@ ret void } -declare i32 @llvm.callbr.landingpad.i32() +declare i32 @llvm.callbr.landingpad.i32(i32) define i32 @callbrpad_multi_preds() { entry: %foo = callbr i32 asm "", "=r,!i"() to label %direct [label %indirect] @@ -88,42 +87,20 @@ br label %indirect indirect: ; CHECK-NEXT: Intrinsic in block must have 1 unique predecessor -; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32() - %out = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32(i32 %foo) + %out = call i32 @llvm.callbr.landingpad.i32(i32 %foo) ret i32 %out } -define void @callbrpad_no_callbr() { -entry: - br label %foo -foo: -; CHECK-NEXT: Intrinsic must have corresponding callbr in predecessor -; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32() - %out = call i32 @llvm.callbr.landingpad.i32() - ret void -} - define void @callbrpad_wrong_callbr() { entry: %foo = callbr i32 asm "", "=r,!i"() to label %direct [label %indirect] direct: ; CHECK-NEXT: Intrinsic's corresponding callbr must have intrinsic's parent basic block in indirect destination list -; CHECK-NEXT: %x = call i32 @llvm.callbr.landingpad.i32() - %x = call i32 @llvm.callbr.landingpad.i32() - ret void -indirect: - ret void -} - -define void @callbrpad_void_callbr() { -entry: - callbr void asm "", "!i"() to label %direct [label %indirect] -direct: +; CHECK-NEXT: %x = call i32 @llvm.callbr.landingpad.i32(i32 %foo) + %x = call i32 @llvm.callbr.landingpad.i32(i32 %foo) ret void indirect: -; CHECK-NEXT: intrinsic's corresponding callbr must return a value -; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32() - %out = call i32 @llvm.callbr.landingpad.i32() ret void } @@ -139,7 +116,7 @@ landingpad: %foo = call i32 @foo(i32 42) ; CHECK-NEXT: No other instructions may proceed intrinsic -; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32() - %out = call i32 @llvm.callbr.landingpad.i32() +; CHECK-NEXT: %out = call i32 @llvm.callbr.landingpad.i32(i32 %0) + %out = call i32 @llvm.callbr.landingpad.i32(i32 %0) ret i32 %out }