From: David Majnemer Date: Tue, 15 Dec 2015 21:27:27 +0000 (+0000) Subject: [WinEH] Use operand bundles to describe call sites X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b46bb541f5f78520b08c1b50463c3517041d26de;p=oota-llvm.git [WinEH] Use operand bundles to describe call sites SimplifyCFG allows tail merging with code which terminates in unreachable which, in turn, makes it possible for an invoke to end up in a funclet which it was not originally part of. Using operand bundles on invokes allows us to determine whether or not an invoke was part of a funclet in the source program. Furthermore, it allows us to unambiguously answer questions about the legality of inlining into call sites which the personality may have trouble with. Differential Revision: http://reviews.llvm.org/D15517 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255674 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LangRef.rst b/docs/LangRef.rst index 21ca7ec0c30..72c0a319dfa 100644 --- a/docs/LangRef.rst +++ b/docs/LangRef.rst @@ -1571,6 +1571,15 @@ caller's deoptimization state to the callee's deoptimization state is semantically equivalent to composing the caller's deoptimization continuation after the callee's deoptimization continuation. +Funclet Operand Bundles +^^^^^^^^^^^^^^^^^^^^^^^ + +Funclet operand bundles are characterized by the ``"funclet"`` +operand bundle tag. These operand bundles indicate that a call site +is within a particular funclet. There can be at most one +``"funclet"`` operand bundle attached to a call site and it must have +exactly one bundle operand. + .. _moduleasm: Module-Level Inline Assembly diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index 242da30c52f..5091bb40783 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -1219,6 +1219,11 @@ struct OperandBundleUse { return getTagID() == LLVMContext::OB_deopt; } + /// \brief Return true if this is a "funclet" operand bundle. + bool isFuncletOperandBundle() const { + return getTagID() == LLVMContext::OB_funclet; + } + private: /// \brief Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag. StringMapEntry *Tag; @@ -1237,6 +1242,8 @@ template class OperandBundleDefT { public: explicit OperandBundleDefT(std::string Tag, std::vector Inputs) : Tag(std::move(Tag)), Inputs(std::move(Inputs)) {} + explicit OperandBundleDefT(std::string Tag, ArrayRef Inputs) + : Tag(std::move(Tag)), Inputs(Inputs) {} explicit OperandBundleDefT(const OperandBundleUse &OBU) { Tag = OBU.getTagName(); @@ -1430,11 +1437,12 @@ public: /// may write to the heap. bool hasClobberingOperandBundles() const { for (auto &BOI : bundle_op_infos()) { - if (BOI.Tag->second == LLVMContext::OB_deopt) + if (BOI.Tag->second == LLVMContext::OB_deopt || + BOI.Tag->second == LLVMContext::OB_funclet) continue; - // This instruction has an operand bundle that is not a "deopt" operand - // bundle. Assume the worst. + // This instruction has an operand bundle that is not known to us. + // Assume the worst. return true; } diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h index c00e3052b59..e99f02420ef 100644 --- a/include/llvm/IR/LLVMContext.h +++ b/include/llvm/IR/LLVMContext.h @@ -72,7 +72,8 @@ public: /// Additionally, this scheme allows LLVM to efficiently check for specific /// operand bundle tags without comparing strings. enum { - OB_deopt = 0, // "deopt" + OB_deopt = 0, // "deopt" + OB_funclet = 1, // "funclet" }; /// getMDKindID - Return a unique non-zero ID for the specified metadata kind. diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index 81598a3dddf..81b376f0c21 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -288,6 +288,10 @@ bool replaceDbgDeclare(Value *Address, Value *NewAddress, bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, DIBuilder &Builder, bool Deref, int Offset = 0); +/// \brief Insert an unreachable instruction before the specified +/// instruction, making it and the rest of the code in the block dead. +void changeToUnreachable(Instruction *I, bool UseLLVMTrap); + /// Replace 'BB's terminator with one that does not have an unwind successor /// block. Rewrites `invoke` to `call`, etc. Updates any PHIs in unwind /// successor. diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index 3ac5d8a7c3b..3b076b65e69 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -74,7 +74,7 @@ private: void demotePHIsOnFunclets(Function &F); void cloneCommonBlocks(Function &F); - void removeImplausibleTerminators(Function &F); + void removeImplausibleInstructions(Function &F); void cleanupPreparedFunclets(Function &F); void verifyPreparedFunclets(Function &F); @@ -765,19 +765,56 @@ void WinEHPrepare::cloneCommonBlocks(Function &F) { } } -void WinEHPrepare::removeImplausibleTerminators(Function &F) { +void WinEHPrepare::removeImplausibleInstructions(Function &F) { // Remove implausible terminators and replace them with UnreachableInst. for (auto &Funclet : FuncletBlocks) { BasicBlock *FuncletPadBB = Funclet.first; std::vector &BlocksInFunclet = Funclet.second; - Instruction *FuncletPadInst = FuncletPadBB->getFirstNonPHI(); - auto *CatchPad = dyn_cast(FuncletPadInst); - auto *CleanupPad = dyn_cast(FuncletPadInst); + Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI(); + auto *FuncletPad = dyn_cast(FirstNonPHI); + auto *CatchPad = dyn_cast_or_null(FuncletPad); + auto *CleanupPad = dyn_cast_or_null(FuncletPad); for (BasicBlock *BB : BlocksInFunclet) { + for (Instruction &I : *BB) { + CallSite CS(&I); + if (!CS) + continue; + + Value *FuncletBundleOperand = nullptr; + if (auto BU = CS.getOperandBundle(LLVMContext::OB_funclet)) + FuncletBundleOperand = BU->Inputs.front(); + + if (FuncletBundleOperand == FuncletPad) + continue; + + // Skip call sites which are nounwind intrinsics. + auto *CalledFn = + dyn_cast(CS.getCalledValue()->stripPointerCasts()); + if (CalledFn && CalledFn->isIntrinsic() && CS.doesNotThrow()) + continue; + + // This call site was not part of this funclet, remove it. + if (CS.isInvoke()) { + // Remove the unwind edge if it was an invoke. + removeUnwindEdge(BB); + // Get a pointer to the new call. + BasicBlock::iterator CallI = + std::prev(BB->getTerminator()->getIterator()); + auto *CI = cast(&*CallI); + changeToUnreachable(CI, /*UseLLVMTrap=*/false); + } else { + changeToUnreachable(&I, /*UseLLVMTrap=*/false); + } + + // There are no more instructions in the block (except for unreachable), + // we are done. + break; + } + TerminatorInst *TI = BB->getTerminator(); // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst. - bool IsUnreachableRet = isa(TI) && (CatchPad || CleanupPad); + bool IsUnreachableRet = isa(TI) && FuncletPad; // The token consumed by a CatchReturnInst must match the funclet token. bool IsUnreachableCatchret = false; if (auto *CRI = dyn_cast(TI)) @@ -788,19 +825,14 @@ void WinEHPrepare::removeImplausibleTerminators(Function &F) { IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad; if (IsUnreachableRet || IsUnreachableCatchret || IsUnreachableCleanupret) { - // Loop through all of our successors and make sure they know that one - // of their predecessors is going away. - for (BasicBlock *SuccBB : TI->successors()) - SuccBB->removePredecessor(BB); - - new UnreachableInst(BB->getContext(), TI); - TI->eraseFromParent(); + changeToUnreachable(TI, /*UseLLVMTrap=*/false); } else if (isa(TI)) { - // Invokes within a cleanuppad for the MSVC++ personality never - // transfer control to their unwind edge: the personality will - // terminate the program. - if (Personality == EHPersonality::MSVC_CXX && CleanupPad) + if (Personality == EHPersonality::MSVC_CXX && CleanupPad) { + // Invokes within a cleanuppad for the MSVC++ personality never + // transfer control to their unwind edge: the personality will + // terminate the program. removeUnwindEdge(BB); + } } } } @@ -854,7 +886,7 @@ bool WinEHPrepare::prepareExplicitEH(Function &F) { demotePHIsOnFunclets(F); if (!DisableCleanups) { - removeImplausibleTerminators(F); + removeImplausibleInstructions(F); cleanupPreparedFunclets(F); } diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp index af998c86135..8848bcb7147 100644 --- a/lib/IR/LLVMContext.cpp +++ b/lib/IR/LLVMContext.cpp @@ -132,6 +132,11 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { assert(DeoptEntry->second == LLVMContext::OB_deopt && "deopt operand bundle id drifted!"); (void)DeoptEntry; + + auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); + assert(FuncletEntry->second == LLVMContext::OB_funclet && + "funclet operand bundle id drifted!"); + (void)FuncletEntry; } LLVMContext::~LLVMContext() { delete pImpl; } diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 234ab29d8ed..32646cf7999 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -2381,13 +2381,25 @@ void Verifier::VerifyCallSite(CallSite CS) { if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID()) visitIntrinsicCallSite(ID, CS); - // Verify that a callsite has at most one "deopt" operand bundle. - bool FoundDeoptBundle = false; + // Verify that a callsite has at most one "deopt" and one "funclet" operand + // bundle. + bool FoundDeoptBundle = false, FoundFuncletBundle = false; for (unsigned i = 0, e = CS.getNumOperandBundles(); i < e; ++i) { - if (CS.getOperandBundleAt(i).getTagID() == LLVMContext::OB_deopt) { + OperandBundleUse BU = CS.getOperandBundleAt(i); + uint32_t Tag = BU.getTagID(); + if (Tag == LLVMContext::OB_deopt) { Assert(!FoundDeoptBundle, "Multiple deopt operand bundles", I); FoundDeoptBundle = true; } + if (Tag == LLVMContext::OB_funclet) { + Assert(!FoundFuncletBundle, "Multiple funclet operand bundles", I); + FoundFuncletBundle = true; + Assert(BU.Inputs.size() == 1, + "Expected exactly one funclet bundle operand", I); + Assert(isa(BU.Inputs.front()), + "Funclet bundle operands should correspond to a FuncletPadInst", + I); + } } visitInstruction(*I); @@ -3002,6 +3014,8 @@ void Verifier::visitCleanupPadInst(CleanupPadInst &CPI) { UnwindDest = CRI->getUnwindDest(); } else if (isa(U) || isa(U)) { continue; + } else if (CallSite(U)) { + continue; } else { Assert(false, "bogus cleanuppad use", &CPI); } diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index b0d99a8e830..db2cacd4739 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -1035,12 +1035,17 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // The inliner does not know how to inline through calls with operand bundles // in general ... if (CS.hasOperandBundles()) { - // ... but it knows how to inline through "deopt" operand bundles. - bool CanInline = - CS.getNumOperandBundles() == 1 && - CS.getOperandBundleAt(0).getTagID() == LLVMContext::OB_deopt; - if (!CanInline) + for (int i = 0, e = CS.getNumOperandBundles(); i != e; ++i) { + uint32_t Tag = CS.getOperandBundleAt(i).getTagID(); + // ... but it knows how to inline through "deopt" operand bundles ... + if (Tag == LLVMContext::OB_deopt) + continue; + // ... and "funclet" operand bundles. + if (Tag == LLVMContext::OB_funclet) + continue; + return false; + } } // If the call to the callee cannot throw, set the 'nounwind' flag on any @@ -1088,23 +1093,13 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // We need to figure out which funclet the callsite was in so that we may // properly nest the callee. Instruction *CallSiteEHPad = nullptr; - if (CalledPersonality && CallerPersonality) { - EHPersonality Personality = classifyEHPersonality(CalledPersonality); + if (CallerPersonality) { + EHPersonality Personality = classifyEHPersonality(CallerPersonality); if (isFuncletEHPersonality(Personality)) { - DenseMap CallerBlockColors = - colorEHFunclets(*Caller); - ColorVector &CallSiteColors = CallerBlockColors[OrigBB]; - size_t NumColors = CallSiteColors.size(); - // There is no single parent, inlining will not succeed. - if (NumColors > 1) - return false; - if (NumColors == 1) { - BasicBlock *CallSiteFuncletBB = CallSiteColors.front(); - if (CallSiteFuncletBB != Caller->begin()) { - CallSiteEHPad = CallSiteFuncletBB->getFirstNonPHI(); - assert(CallSiteEHPad->isEHPad() && "Expected an EHPad!"); - } - } + Optional ParentFunclet = + CS.getOperandBundle(LLVMContext::OB_funclet); + if (ParentFunclet) + CallSiteEHPad = cast(ParentFunclet->Inputs.front()); // OK, the inlining site is legal. What about the target function? @@ -1116,7 +1111,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Ok, the call site is within a cleanuppad. Let's check the callee // for catchpads. for (const BasicBlock &CalledBB : *CalledFunc) { - if (isa(CalledBB.getFirstNonPHI())) + if (isa(CalledBB.getFirstNonPHI())) return false; } } @@ -1195,11 +1190,9 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, HandleByValArgumentInit(Init.first, Init.second, Caller->getParent(), &*FirstNewBlock, IFI); - if (CS.hasOperandBundles()) { - auto ParentDeopt = CS.getOperandBundleAt(0); - assert(ParentDeopt.getTagID() == LLVMContext::OB_deopt && - "Checked on entry!"); - + Optional ParentDeopt = + CS.getOperandBundle(LLVMContext::OB_deopt); + if (ParentDeopt) { SmallVector OpDefs; for (auto &VH : InlinedFunctionInfo.OperandBundleCallSites) { @@ -1225,12 +1218,12 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, // Prepend the parent's deoptimization continuation to the newly // inlined call's deoptimization continuation. std::vector MergedDeoptArgs; - MergedDeoptArgs.reserve(ParentDeopt.Inputs.size() + + MergedDeoptArgs.reserve(ParentDeopt->Inputs.size() + ChildOB.Inputs.size()); MergedDeoptArgs.insert(MergedDeoptArgs.end(), - ParentDeopt.Inputs.begin(), - ParentDeopt.Inputs.end()); + ParentDeopt->Inputs.begin(), + ParentDeopt->Inputs.end()); MergedDeoptArgs.insert(MergedDeoptArgs.end(), ChildOB.Inputs.begin(), ChildOB.Inputs.end()); @@ -1423,12 +1416,48 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, } } - // Update the lexical scopes of the new funclets. Anything that had 'none' as - // its parent is now nested inside the callsite's EHPad. + // Update the lexical scopes of the new funclets and callsites. + // Anything that had 'none' as its parent is now nested inside the callsite's + // EHPad. + if (CallSiteEHPad) { for (Function::iterator BB = FirstNewBlock->getIterator(), E = Caller->end(); BB != E; ++BB) { + // Add bundle operands to any top-level call sites. + SmallVector OpBundles; + for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E;) { + Instruction *I = &*BBI++; + CallSite CS(I); + if (!CS) + continue; + + // Skip call sites which are nounwind intrinsics. + auto *CalledFn = + dyn_cast(CS.getCalledValue()->stripPointerCasts()); + if (CalledFn && CalledFn->isIntrinsic() && CS.doesNotThrow()) + continue; + + // Skip call sites which already have a "funclet" bundle. + if (CS.getOperandBundle(LLVMContext::OB_funclet)) + continue; + + CS.getOperandBundlesAsDefs(OpBundles); + OpBundles.emplace_back("funclet", CallSiteEHPad); + + Instruction *NewInst; + if (CS.isCall()) + NewInst = CallInst::Create(cast(I), OpBundles, I); + else + NewInst = InvokeInst::Create(cast(I), OpBundles, I); + NewInst->setDebugLoc(I->getDebugLoc()); + NewInst->takeName(I); + I->replaceAllUsesWith(NewInst); + I->eraseFromParent(); + + OpBundles.clear(); + } + Instruction *I = BB->getFirstNonPHI(); if (!I->isEHPad()) continue; diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 24f88179c90..31039816e14 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -1180,9 +1180,7 @@ bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, Deref, Offset); } -/// changeToUnreachable - Insert an unreachable instruction before the specified -/// instruction, making it and the rest of the code in the block dead. -static void changeToUnreachable(Instruction *I, bool UseLLVMTrap) { +void llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap) { BasicBlock *BB = I->getParent(); // Loop over all of the successors, removing BB's entry from any PHI // nodes. diff --git a/test/CodeGen/WinEH/wineh-cloning.ll b/test/CodeGen/WinEH/wineh-cloning.ll index 66a9132980f..c13e0a16364 100644 --- a/test/CodeGen/WinEH/wineh-cloning.ll +++ b/test/CodeGen/WinEH/wineh-cloning.ll @@ -4,25 +4,26 @@ declare i32 @__CxxFrameHandler3(...) declare i32 @__C_specific_handler(...) declare void @f() -declare i32 @g() -declare void @h(i32) -declare i1 @b() +declare void @llvm.foo(i32) nounwind +declare void @llvm.bar() nounwind +declare i32 @llvm.qux() nounwind +declare i1 @llvm.baz() nounwind define void @test1() personality i32 (...)* @__CxxFrameHandler3 { entry: ; %x def colors: {entry} subset of use colors; must spill - %x = call i32 @g() + %x = call i32 @llvm.qux() invoke void @f() to label %noreturn unwind label %catch.switch catch.switch: %cs = catchswitch within none [label %catch] unwind to caller catch: - catchpad within %cs [] + %cp = catchpad within %cs [] br label %noreturn noreturn: ; %x use colors: {entry, cleanup} - call void @h(i32 %x) + call void @llvm.foo(i32 %x) unreachable } ; Need two copies of the call to @h, one under entry and one under catch. @@ -30,16 +31,16 @@ noreturn: ; for the use in entry's copy. ; CHECK-LABEL: define void @test1( ; CHECK: entry: -; CHECK: %x = call i32 @g() +; CHECK: %x = call i32 @llvm.qux() ; CHECK: invoke void @f() ; CHECK: to label %[[EntryCopy:[^ ]+]] unwind label %catch ; CHECK: catch.switch: ; CHECK: %cs = catchswitch within none [label %catch] unwind to caller ; CHECK: catch: ; CHECK: catchpad within %cs [] -; CHECK-NEXT: call void @h(i32 %x) +; CHECK-NEXT: call void @llvm.foo(i32 %x) ; CHECK: [[EntryCopy]]: -; CHECK: call void @h(i32 %x) +; CHECK: call void @llvm.foo(i32 %x) define void @test2() personality i32 (...)* @__CxxFrameHandler3 { @@ -50,7 +51,7 @@ cleanup: cleanuppad within none [] br label %exit exit: - call void @f() + call void @llvm.bar() ret void } ; Need two copies of %exit's call to @f -- the subsequent ret is only @@ -62,10 +63,10 @@ exit: ; CHECK: to label %[[exit:[^ ]+]] unwind label %cleanup ; CHECK: cleanup: ; CHECK: cleanuppad within none [] -; CHECK: call void @f() +; CHECK: call void @llvm.bar() ; CHECK-NEXT: unreachable ; CHECK: [[exit]]: -; CHECK: call void @f() +; CHECK: call void @llvm.bar() ; CHECK-NEXT: ret void @@ -85,7 +86,7 @@ cleanup: cleanuppad within none [] br label %shared shared: - call void @f() + call void @llvm.bar() br label %exit exit: ret void @@ -98,11 +99,11 @@ exit: ; CHECK: to label %[[exit:[^ ]+]] unwind ; CHECK: catch: ; CHECK: catchpad within %cs [] -; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @llvm.bar() ; CHECK-NEXT: unreachable ; CHECK: cleanup: ; CHECK: cleanuppad within none [] -; CHECK: call void @f() +; CHECK: call void @llvm.bar() ; CHECK-NEXT: unreachable ; CHECK: [[exit]]: ; CHECK: ret void @@ -118,26 +119,26 @@ catch: catchpad within %cs [] br label %shared shared: - %x = call i32 @g() - %i = call i32 @g() + %x = call i32 @llvm.qux() + %i = call i32 @llvm.qux() %zero.trip = icmp eq i32 %i, 0 br i1 %zero.trip, label %exit, label %loop loop: %i.loop = phi i32 [ %i, %shared ], [ %i.dec, %loop.tail ] - %b = call i1 @b() + %b = call i1 @llvm.baz() br i1 %b, label %left, label %right left: - %y = call i32 @g() + %y = call i32 @llvm.qux() br label %loop.tail right: - call void @h(i32 %x) + call void @llvm.foo(i32 %x) br label %loop.tail loop.tail: %i.dec = sub i32 %i.loop, 1 %done = icmp eq i32 %i.dec, 0 br i1 %done, label %exit, label %loop exit: - call void @h(i32 %x) + call void @llvm.foo(i32 %x) unreachable } ; Make sure we can clone regions that have internal control @@ -148,34 +149,34 @@ exit: ; CHECK: to label %[[shared_E:[^ ]+]] unwind label %catch.switch ; CHECK: catch: ; CHECK: catchpad within %cs [] -; CHECK: [[x_C:%[^ ]+]] = call i32 @g() -; CHECK: [[i_C:%[^ ]+]] = call i32 @g() +; CHECK: [[x_C:%[^ ]+]] = call i32 @llvm.qux() +; CHECK: [[i_C:%[^ ]+]] = call i32 @llvm.qux() ; CHECK: [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0 ; CHECK: br i1 [[zt_C]], label %[[exit_C:[^ ]+]], label %[[loop_C:[^ ]+]] ; CHECK: [[shared_E]]: -; CHECK: [[x_E:%[^ ]+]] = call i32 @g() -; CHECK: [[i_E:%[^ ]+]] = call i32 @g() +; CHECK: [[x_E:%[^ ]+]] = call i32 @llvm.qux() +; CHECK: [[i_E:%[^ ]+]] = call i32 @llvm.qux() ; CHECK: [[zt_E:%[^ ]+]] = icmp eq i32 [[i_E]], 0 ; CHECK: br i1 [[zt_E]], label %[[exit_E:[^ ]+]], label %[[loop_E:[^ ]+]] ; CHECK: [[loop_C]]: ; CHECK: [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %catch ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ] -; CHECK: [[b_C:%[^ ]+]] = call i1 @b() +; CHECK: [[b_C:%[^ ]+]] = call i1 @llvm.baz() ; CHECK: br i1 [[b_C]], label %[[left_C:[^ ]+]], label %[[right_C:[^ ]+]] ; CHECK: [[loop_E]]: ; CHECK: [[iloop_E:%[^ ]+]] = phi i32 [ [[i_E]], %[[shared_E]] ], [ [[idec_E:%[^ ]+]], %[[looptail_E:[^ ]+]] ] -; CHECK: [[b_E:%[^ ]+]] = call i1 @b() +; CHECK: [[b_E:%[^ ]+]] = call i1 @llvm.baz() ; CHECK: br i1 [[b_E]], label %[[left_E:[^ ]+]], label %[[right_E:[^ ]+]] ; CHECK: [[left_C]]: -; CHECK: [[y_C:%[^ ]+]] = call i32 @g() +; CHECK: [[y_C:%[^ ]+]] = call i32 @llvm.qux() ; CHECK: br label %[[looptail_C]] ; CHECK: [[left_E]]: -; CHECK: [[y_E:%[^ ]+]] = call i32 @g() +; CHECK: [[y_E:%[^ ]+]] = call i32 @llvm.qux() ; CHECK: br label %[[looptail_E]] ; CHECK: [[right_C]]: -; CHECK: call void @h(i32 [[x_C]]) +; CHECK: call void @llvm.foo(i32 [[x_C]]) ; CHECK: br label %[[looptail_C]] ; CHECK: [[right_E]]: -; CHECK: call void @h(i32 [[x_E]]) +; CHECK: call void @llvm.foo(i32 [[x_E]]) ; CHECK: br label %[[looptail_E]] ; CHECK: [[looptail_C]]: ; CHECK: [[idec_C]] = sub i32 [[iloop_C]], 1 @@ -186,10 +187,10 @@ exit: ; CHECK: [[done_E:%[^ ]+]] = icmp eq i32 [[idec_E]], 0 ; CHECK: br i1 [[done_E]], label %[[exit_E]], label %[[loop_E]] ; CHECK: [[exit_C]]: -; CHECK: call void @h(i32 [[x_C]]) +; CHECK: call void @llvm.foo(i32 [[x_C]]) ; CHECK: unreachable ; CHECK: [[exit_E]]: -; CHECK: call void @h(i32 [[x_E]]) +; CHECK: call void @llvm.foo(i32 [[x_E]]) ; CHECK: unreachable @@ -199,8 +200,8 @@ entry: to label %exit unwind label %outer outer: %o = cleanuppad within none [] - %x = call i32 @g() - invoke void @f() + %x = call i32 @llvm.qux() + invoke void @f() [ "funclet"(token %o) ] to label %outer.ret unwind label %catch.switch catch.switch: %cs = catchswitch within %o [label %inner] unwind to caller @@ -208,7 +209,7 @@ inner: %i = catchpad within %cs [] catchret from %i to label %outer.post-inner outer.post-inner: - call void @h(i32 %x) + call void @llvm.foo(i32 %x) br label %outer.ret outer.ret: cleanupret from %o unwind to caller @@ -220,64 +221,17 @@ exit: ; and so don't need to be spilled. ; CHECK-LABEL: define void @test5( ; CHECK: outer: -; CHECK: %x = call i32 @g() +; CHECK: %x = call i32 @llvm.qux() ; CHECK-NEXT: invoke void @f() ; CHECK-NEXT: to label %outer.ret unwind label %catch.switch ; CHECK: inner: ; CHECK-NEXT: %i = catchpad within %cs [] ; CHECK-NEXT: catchret from %i to label %outer.post-inner ; CHECK: outer.post-inner: -; CHECK-NEXT: call void @h(i32 %x) +; CHECK-NEXT: call void @llvm.foo(i32 %x) ; CHECK-NEXT: br label %outer.ret -define void @test6() personality i32 (...)* @__C_specific_handler { -entry: - invoke void @f() - to label %invoke.cont unwind label %left -invoke.cont: - invoke void @f() - to label %exit unwind label %right -left: - cleanuppad within none [] - br label %shared -right: - %cs = catchswitch within none [label %right.catch] unwind to caller -right.catch: - catchpad within %cs [] - br label %shared -shared: - %x = call i32 @g() - invoke void @f() - to label %shared.cont unwind label %inner -shared.cont: - unreachable -inner: - %i = cleanuppad within none [] - call void @h(i32 %x) - cleanupret from %i unwind to caller -exit: - ret void -} -; CHECK-LABEL: define void @test6( -; CHECK: left: -; CHECK: %x.for.left = call i32 @g() -; CHECK: invoke void @f() -; CHECK: to label %shared.cont.for.left unwind label %inner -; CHECK: right.catch: -; CHECK: catchpad -; CHECK: %x = call i32 @g() -; CHECK: to label %shared.cont unwind label %inner -; CHECK: shared.cont: -; CHECK: unreachable -; CHECK: shared.cont.for.left: -; CHECK: unreachable -; CHECK: inner: -; CHECK: %i = cleanuppad within none [] -; CHECK: call void @h(i32 %x1.wineh.reload) -; CHECK: cleanupret from %i unwind to caller - - define void @test9() personality i32 (...)* @__C_specific_handler { entry: invoke void @f() @@ -286,14 +240,14 @@ invoke.cont: invoke void @f() to label %unreachable unwind label %right left: - cleanuppad within none [] - call void @h(i32 1) - invoke void @f() + %cp.left = cleanuppad within none [] + call void @llvm.foo(i32 1) + invoke void @f() [ "funclet"(token %cp.left) ] to label %unreachable unwind label %right right: - cleanuppad within none [] - call void @h(i32 2) - invoke void @f() + %cp.right = cleanuppad within none [] + call void @llvm.foo(i32 2) + invoke void @f() [ "funclet"(token %cp.right) ] to label %unreachable unwind label %left unreachable: unreachable @@ -305,11 +259,11 @@ unreachable: ; CHECK: invoke.cont: ; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]] ; CHECK: [[LEFT]]: -; CHECK: call void @h(i32 1) +; CHECK: call void @llvm.foo(i32 1) ; CHECK: invoke void @f() ; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT]] ; CHECK: [[RIGHT]]: -; CHECK: call void @h(i32 2) +; CHECK: call void @llvm.foo(i32 2) ; CHECK: invoke void @f() ; CHECK: to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT]] ; CHECK: [[UNREACHABLE_RIGHT]]: @@ -361,7 +315,7 @@ entry: to label %exit unwind label %cleanup.outer cleanup.outer: %outer = cleanuppad within none [] - invoke void @f() + invoke void @f() [ "funclet"(token %outer) ] to label %outer.cont unwind label %cleanup.inner outer.cont: br label %merge @@ -369,7 +323,7 @@ cleanup.inner: %inner = cleanuppad within %outer [] br label %merge merge: - call void @f() + call void @llvm.bar() unreachable exit: ret void @@ -379,7 +333,7 @@ exit: ; rewritten to call @f() ; CHECK-LABEL: define void @test11() ; CHECK: %inner = cleanuppad within %outer [] -; CHECK-NEXT: call void @f() +; CHECK-NEXT: call void @llvm.bar() ; CHECK-NEXT: unreachable define void @test12() personality i32 (...)* @__CxxFrameHandler3 !dbg !5 { @@ -398,7 +352,7 @@ right: join: ; This call will get cloned; make sure we can handle cloning ; instructions with debug metadata attached. - call void @f(), !dbg !9 + call void @llvm.bar(), !dbg !9 unreachable exit: ret void diff --git a/test/CodeGen/WinEH/wineh-demotion.ll b/test/CodeGen/WinEH/wineh-demotion.ll index bd239133ea8..411952d84bb 100644 --- a/test/CodeGen/WinEH/wineh-demotion.ll +++ b/test/CodeGen/WinEH/wineh-demotion.ll @@ -10,6 +10,8 @@ declare void @h(i32) declare i1 @i() +declare void @llvm.bar() nounwind + ; CHECK-LABEL: @test1( define void @test1(i1 %B) personality i32 (...)* @__CxxFrameHandler3 { entry: @@ -43,7 +45,7 @@ catch: ; CHECK: catch: ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]] ; CHECK-NEXT: call void @h(i32 [[Reload]]) - call void @h(i32 %phi) + call void @h(i32 %phi) [ "funclet"(token %cp) ] catchret from %cp to label %exit exit: @@ -81,10 +83,10 @@ catch.inner: %cpinner = catchpad within %cs1 [] ; Need just one store here because only %y is affected ; CHECK: catch.inner: - %z = call i32 @g() + %z = call i32 @g() [ "funclet"(token %cpinner) ] ; CHECK: store i32 %z ; CHECK-NEXT: invoke void @f - invoke void @f() + invoke void @f() [ "funclet"(token %cpinner) ] to label %catchret.inner unwind label %merge.outer catchret.inner: @@ -106,8 +108,8 @@ catch.outer: ; CHECK-DAG: load i32, i32* [[Slot1]] ; CHECK-DAG: load i32, i32* [[Slot2]] ; CHECK: catchret from [[CatchPad]] to label - call void @h(i32 %x) - call void @h(i32 %y) + call void @h(i32 %x) [ "funclet"(token %cpouter) ] + call void @h(i32 %y) [ "funclet"(token %cpouter) ] catchret from %cpouter to label %exit exit: @@ -166,7 +168,7 @@ catch.outer: ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]] ; CHECK: call void @h(i32 [[Reload]]) %cp2 = catchpad within %cs2 [] - call void @h(i32 %phi.outer) + call void @h(i32 %phi.outer) [ "funclet"(token %cp2) ] catchret from %cp2 to label %exit exit: ret void @@ -197,19 +199,19 @@ cleanup: ; CHECK: [[CleanupReload:%[^ ]+]] = load i32, i32* [[CleanupSlot]] %phi.cleanup = phi i32 [ 1, %entry ], [ 2, %invoke.cont ] %cp = cleanuppad within none [] - %b = call i1 @i() + %b = call i1 @i() [ "funclet"(token %cp) ] br i1 %b, label %left, label %right left: ; CHECK: left: ; CHECK: call void @h(i32 [[CleanupReload]] - call void @h(i32 %phi.cleanup) + call void @h(i32 %phi.cleanup) [ "funclet"(token %cp) ] br label %merge right: ; CHECK: right: ; CHECK: call void @h(i32 [[CleanupReload]] - call void @h(i32 %phi.cleanup) + call void @h(i32 %phi.cleanup) [ "funclet"(token %cp) ] br label %merge merge: @@ -239,7 +241,7 @@ catch: ; CHECK: [[CatchReload:%[^ ]+]] = load i32, i32* [[CatchSlot]] ; CHECK: call void @h(i32 [[CatchReload]] %cp2 = catchpad within %cs1 [] - call void @h(i32 %phi.catch) + call void @h(i32 %phi.catch) [ "funclet"(token %cp2) ] catchret from %cp2 to label %exit exit: @@ -265,7 +267,7 @@ cleanup: ; CHECK: cleanup: ; CHECK: call void @h(i32 %x) %cp2 = cleanuppad within none [] - call void @h(i32 %x) + call void @h(i32 %x) [ "funclet"(token %cp2) ] cleanupret from %cp2 unwind to caller } @@ -295,7 +297,7 @@ catch: ; CHECK: catch: ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad within %cs1 [] %cp = catchpad within %cs1 [] - %b = call i1 @i() + %b = call i1 @i() [ "funclet"(token %cp) ] br i1 %b, label %left, label %right left: ; Edge from %left to %join needs to be split so that @@ -312,7 +314,7 @@ right: ; CHECK: right: ; CHECK: %y = call i32 @g() ; CHECK: catchret from %[[CatchPad]] to label %join - %y = call i32 @g() + %y = call i32 @g() [ "funclet"(token %cp) ] catchret from %cp to label %join join: ; CHECK: join: @@ -336,19 +338,19 @@ done: cleanup1: ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad within none [] - ; CHECK-NEXT: call void @f() + ; CHECK-NEXT: call void @llvm.bar() ; CHECK-NEXT: cleanupret from [[CleanupPad1]] %cp0 = cleanuppad within none [] br label %cleanupexit cleanup2: ; CHECK: cleanuppad within none [] - ; CHECK-NEXT: call void @f() + ; CHECK-NEXT: call void @llvm.bar() ; CHECK-NEXT: unreachable %cp1 = cleanuppad within none [] br label %cleanupexit cleanupexit: - call void @f() + call void @llvm.bar() cleanupret from %cp0 unwind label %cleanup2 } diff --git a/test/CodeGen/WinEH/wineh-no-demotion.ll b/test/CodeGen/WinEH/wineh-no-demotion.ll index ab094aeebf5..4fb84db8909 100644 --- a/test/CodeGen/WinEH/wineh-no-demotion.ll +++ b/test/CodeGen/WinEH/wineh-no-demotion.ll @@ -1,4 +1,4 @@ -; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare -disable-demotion < %s | FileCheck %s +; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare -disable-demotion -disable-cleanups < %s | FileCheck %s declare i32 @__CxxFrameHandler3(...) @@ -11,22 +11,21 @@ declare i32 @g() declare void @h(i32) ; CHECK-LABEL: @test1( -define void @test1() personality i32 (...)* @__C_specific_handler { +define void @test1(i1 %bool) personality i32 (...)* @__C_specific_handler { entry: invoke void @f() - to label %invoke.cont1 unwind label %left - -invoke.cont1: - invoke void @f() - to label %invoke.cont2 unwind label %right + to label %invoke.cont unwind label %left -invoke.cont2: +invoke.cont: invoke void @f() to label %exit unwind label %inner left: %0 = cleanuppad within none [] - br label %shared + br i1 %bool, label %shared, label %cleanupret + +cleanupret: + cleanupret from %0 unwind label %right right: %1 = cleanuppad within none [] @@ -34,19 +33,19 @@ right: shared: %x = call i32 @g() - invoke void @f() + invoke void @f() [ "funclet"(token %0) ] to label %shared.cont unwind label %inner shared.cont: unreachable inner: - %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont2 ] + %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont ] %i = cleanuppad within none [] call void @h(i32 %phi) unreachable -; CHECK: %phi = phi i32 [ %x, %right ], [ 0, %invoke.cont2 ], [ %x.for.left, %left ] +; CHECK: %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont ], [ %x.for.left, %shared.for.left ] ; CHECK: %i = cleanuppad within none [] ; CHECK: call void @h(i32 %phi) @@ -55,26 +54,25 @@ exit: } ; CHECK-LABEL: @test2( -define void @test2() personality i32 (...)* @__C_specific_handler { +define void @test2(i1 %bool) personality i32 (...)* @__C_specific_handler { entry: invoke void @f() - to label %invoke.cont unwind label %left - -invoke.cont: - invoke void @f() - to label %exit unwind label %right + to label %shared.cont unwind label %left left: - cleanuppad within none [] - br label %shared + %0 = cleanuppad within none [] + br i1 %bool, label %shared, label %cleanupret + +cleanupret: + cleanupret from %0 unwind label %right right: - cleanuppad within none [] + %1 = cleanuppad within none [] br label %shared shared: %x = call i32 @g() - invoke void @f() + invoke void @f() [ "funclet"(token %0) ] to label %shared.cont unwind label %inner shared.cont: @@ -85,9 +83,9 @@ inner: call void @h(i32 %x) unreachable -; CHECK: %x1 = phi i32 [ %x.for.left, %left ], [ %x, %right ] -; CHECK: %i = cleanuppad within none [] -; CHECK: call void @h(i32 %x1) +; CHECK: %x1 = phi i32 [ %x.for.left, %shared.for.left ], [ %x, %shared ] +; CHECK: %i = cleanuppad within none [] +; CHECK: call void @h(i32 %x1) exit: unreachable @@ -119,13 +117,12 @@ shared: call void @h(i32 %phi) unreachable -; CHECK: %0 = cleanuppad within none [] -; CHECK: call void @h(i32 1) - -; CHECK: %1 = cleanuppad within none [] ; CHECK: %phi = phi i32 [ 0, %right ], [ -1, %right.other ] ; CHECK: call void @h(i32 %phi) +; CHECK: %phi.for.left = phi i32 [ 1, %left ] +; CHECK: call void @h(i32 %phi.for.left) + exit: unreachable } diff --git a/test/CodeGen/X86/catchpad-weight.ll b/test/CodeGen/X86/catchpad-weight.ll index 1abcd03ac64..60939bc6b03 100644 --- a/test/CodeGen/X86/catchpad-weight.ll +++ b/test/CodeGen/X86/catchpad-weight.ll @@ -58,7 +58,7 @@ catch: ; preds = %catch.dispatch.2 ehcleanup: ; preds = %catchendblock %4 = cleanuppad within none [] - call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4 + call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4 [ "funclet"(token %4) ] cleanupret from %4 unwind to caller } diff --git a/test/CodeGen/X86/cleanuppad-inalloca.ll b/test/CodeGen/X86/cleanuppad-inalloca.ll index 294ef3abc46..2e34ada52e6 100644 --- a/test/CodeGen/X86/cleanuppad-inalloca.ll +++ b/test/CodeGen/X86/cleanuppad-inalloca.ll @@ -30,7 +30,7 @@ invoke.cont: ; preds = %entry ehcleanup: ; preds = %entry %2 = cleanuppad within none [] - call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %0) + call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %0) [ "funclet"(token %2) ] cleanupret from %2 unwind to caller } diff --git a/test/CodeGen/X86/cleanuppad-large-codemodel.ll b/test/CodeGen/X86/cleanuppad-large-codemodel.ll index e32cdbed73f..8ffb97d8dd6 100644 --- a/test/CodeGen/X86/cleanuppad-large-codemodel.ll +++ b/test/CodeGen/X86/cleanuppad-large-codemodel.ll @@ -10,7 +10,7 @@ entry: to label %exit unwind label %cleanup cleanup: %c = cleanuppad within none [] - call void @bar() + call void @bar() [ "funclet"(token %c) ] cleanupret from %c unwind to caller exit: ret void diff --git a/test/CodeGen/X86/cleanuppad-realign.ll b/test/CodeGen/X86/cleanuppad-realign.ll index d322932da4c..5a565cc1570 100644 --- a/test/CodeGen/X86/cleanuppad-realign.ll +++ b/test/CodeGen/X86/cleanuppad-realign.ll @@ -18,7 +18,7 @@ invoke.cont: ; preds = %entry ehcleanup: ; preds = %entry %0 = cleanuppad within none [] - call void @Dtor(i64* %o) + call void @Dtor(i64* %o) [ "funclet"(token %0) ] cleanupret from %0 unwind to caller } diff --git a/test/CodeGen/X86/funclet-layout.ll b/test/CodeGen/X86/funclet-layout.ll index b5972df43cc..0942645cf5a 100644 --- a/test/CodeGen/X86/funclet-layout.ll +++ b/test/CodeGen/X86/funclet-layout.ll @@ -59,7 +59,7 @@ catch.dispatch: ; preds = %entry catch: ; preds = %catch.dispatch %0 = catchpad within %cs1 [i8* null, i32 64, i8* null] - invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1 + invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1 ["funclet"(token %0)] to label %unreachable unwind label %catch.dispatch.1 catch.dispatch.1: ; preds = %catch @@ -110,7 +110,7 @@ catch.dispatch: ; preds = %entry catch.2: ; preds = %catch.dispatch %0 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] - tail call void @exit(i32 0) #2 + tail call void @exit(i32 0) #2 [ "funclet"(token %0) ] unreachable catch.dispatch.1: ; preds = %catch.dispatch @@ -118,7 +118,7 @@ catch.dispatch.1: ; preds = %catch.dispatch catch: ; preds = %catch.dispatch.1 %1 = catchpad within %cs2 [i8* null, i32 64, i8* null] - tail call void @exit(i32 0) #2 + tail call void @exit(i32 0) #2 [ "funclet"(token %1) ] unreachable try.cont: ; preds = %entry diff --git a/test/CodeGen/X86/seh-catch-all-win32.ll b/test/CodeGen/X86/seh-catch-all-win32.ll index 69afb1b9d9c..e8da7ab971b 100644 --- a/test/CodeGen/X86/seh-catch-all-win32.ll +++ b/test/CodeGen/X86/seh-catch-all-win32.ll @@ -27,7 +27,7 @@ lpad: ; preds = %entry __except: ; preds = %lpad %p = catchpad within %cs1 [i8* bitcast (i32 ()* @"filt$main" to i8*)] %code = load i32, i32* %__exceptioncode, align 4 - %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4 + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4 [ "funclet"(token %p) ] catchret from %p to label %__try.cont __try.cont: ; preds = %entry, %__except diff --git a/test/CodeGen/X86/seh-catch-all.ll b/test/CodeGen/X86/seh-catch-all.ll index 4463485f209..76823bd476b 100644 --- a/test/CodeGen/X86/seh-catch-all.ll +++ b/test/CodeGen/X86/seh-catch-all.ll @@ -21,7 +21,7 @@ lpad: catchall: %p = catchpad within %cs1 [i8* null, i32 64, i8* null] %code = call i32 @llvm.eh.exceptioncode(token %p) - call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %code) + call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %code) [ "funclet"(token %p) ] catchret from %p to label %__try.cont } diff --git a/test/CodeGen/X86/seh-catchpad.ll b/test/CodeGen/X86/seh-catchpad.ll index a8be4ec1450..321d3a70cf8 100644 --- a/test/CodeGen/X86/seh-catchpad.ll +++ b/test/CodeGen/X86/seh-catchpad.ll @@ -69,7 +69,7 @@ __except: ; preds = %catch.dispatch ehcleanup: ; preds = %__except.2 %cp2 = cleanuppad within none [] - invoke fastcc void @"\01?fin$0@0@main@@"() #4 + invoke fastcc void @"\01?fin$0@0@main@@"() #4 [ "funclet"(token %cp2) ] to label %invoke.cont.6 unwind label %catch.dispatch.7 invoke.cont.6: ; preds = %ehcleanup diff --git a/test/CodeGen/X86/seh-except-finally.ll b/test/CodeGen/X86/seh-except-finally.ll index b252b5b1248..c15ecfcd77b 100644 --- a/test/CodeGen/X86/seh-except-finally.ll +++ b/test/CodeGen/X86/seh-except-finally.ll @@ -51,7 +51,7 @@ invoke.cont2: ; preds = %invoke.cont __finally: ; preds = %entry %cleanuppad = cleanuppad within none [] %locals = call i8* @llvm.localaddress() - invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %locals) #5 + invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %locals) #5 [ "funclet"(token %cleanuppad) ] to label %invoke.cont3 unwind label %catch.dispatch invoke.cont3: ; preds = %__finally @@ -62,7 +62,7 @@ catch.dispatch: ; preds = %invoke.cont3, %lpad __except: ; preds = %catch.dispatch %catchpad = catchpad within %cs1 [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)] - %call = call i32 @puts(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08MLCMLGHM@__except?$AA@", i32 0, i32 0)) + %call = call i32 @puts(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08MLCMLGHM@__except?$AA@", i32 0, i32 0)) [ "funclet"(token %catchpad) ] catchret from %catchpad to label %__try.cont __try.cont: ; preds = %__except, %invoke.cont2 diff --git a/test/CodeGen/X86/seh-finally.ll b/test/CodeGen/X86/seh-finally.ll index 67bce81a66a..8405d200776 100644 --- a/test/CodeGen/X86/seh-finally.ll +++ b/test/CodeGen/X86/seh-finally.ll @@ -18,7 +18,7 @@ invoke.cont: ; preds = %entry lpad: ; preds = %entry %p = cleanuppad within none [] - %call2 = call i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0)) + %call2 = call i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0)) [ "funclet"(token %p) ] cleanupret from %p unwind to caller } diff --git a/test/CodeGen/X86/seh-safe-div-win32.ll b/test/CodeGen/X86/seh-safe-div-win32.ll index 3f88696fe60..643af3a472f 100644 --- a/test/CodeGen/X86/seh-safe-div-win32.ll +++ b/test/CodeGen/X86/seh-safe-div-win32.ll @@ -35,7 +35,7 @@ lpad0: handler0: %p0 = catchpad within %cs0 [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)] - call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0)) + call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0)) [ "funclet"(token %p0) ] store i32 -1, i32* %r, align 4 catchret from %p0 to label %__try.cont @@ -44,7 +44,7 @@ lpad1: handler1: %p1 = catchpad within %cs1 [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)] - call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0)) + call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0)) [ "funclet"(token %p1) ] store i32 -2, i32* %r, align 4 catchret from %p1 to label %__try.cont diff --git a/test/CodeGen/X86/seh-safe-div.ll b/test/CodeGen/X86/seh-safe-div.ll index 3eeeab09ffb..dd5752e8a71 100644 --- a/test/CodeGen/X86/seh-safe-div.ll +++ b/test/CodeGen/X86/seh-safe-div.ll @@ -34,7 +34,7 @@ lpad0: handler0: %p0 = catchpad within %cs0 [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)] - call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0)) + call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0)) [ "funclet"(token %p0) ] store i32 -1, i32* %r, align 4 catchret from %p0 to label %__try.cont @@ -43,7 +43,7 @@ lpad1: handler1: %p1 = catchpad within %cs1 [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)] - call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0)) + call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0)) [ "funclet"(token %p1) ] store i32 -2, i32* %r, align 4 catchret from %p1 to label %__try.cont diff --git a/test/CodeGen/X86/seh-stack-realign.ll b/test/CodeGen/X86/seh-stack-realign.ll index 880533b4392..654cad347f6 100644 --- a/test/CodeGen/X86/seh-stack-realign.ll +++ b/test/CodeGen/X86/seh-stack-realign.ll @@ -28,7 +28,7 @@ lpad: ; preds = %entry __except: ; preds = %lpad %p = catchpad within %cs1 [i8* bitcast (i32 ()* @"filt$main" to i8*)] %code = load i32, i32* %__exceptioncode, align 4 - %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4 + %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4 [ "funclet"(token %p) ] catchret from %p to label %__try.cont __try.cont: ; preds = %entry, %__except diff --git a/test/CodeGen/X86/win-catchpad-csrs.ll b/test/CodeGen/X86/win-catchpad-csrs.ll index 9f7a49536ca..327ee45b432 100644 --- a/test/CodeGen/X86/win-catchpad-csrs.ll +++ b/test/CodeGen/X86/win-catchpad-csrs.ll @@ -34,7 +34,7 @@ catch.dispatch: handler1: %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] - call void @f(i32 2) + call void @f(i32 2) [ "funclet"(token %h1) ] catchret from %h1 to label %try.cont } diff --git a/test/CodeGen/X86/win-catchpad-nested-cxx.ll b/test/CodeGen/X86/win-catchpad-nested-cxx.ll index 22ce7e5cd87..ac4598385cd 100644 --- a/test/CodeGen/X86/win-catchpad-nested-cxx.ll +++ b/test/CodeGen/X86/win-catchpad-nested-cxx.ll @@ -31,7 +31,7 @@ catch.dispatch.1: %cs1 = catchswitch within none [label %handler1] unwind to caller handler1: %h1 = catchpad within %cs1 [i8* null, i32 64, i8* null] - invoke void @f(i32 2) + invoke void @f(i32 2) [ "funclet"(token %h1) ] to label %catchret1 unwind label %catch.dispatch.2 catchret1: catchret from %h1 to label %try.cont diff --git a/test/CodeGen/X86/win-catchpad-nested.ll b/test/CodeGen/X86/win-catchpad-nested.ll index d20f9f69a5e..7afcd9cc1f3 100644 --- a/test/CodeGen/X86/win-catchpad-nested.ll +++ b/test/CodeGen/X86/win-catchpad-nested.ll @@ -16,7 +16,7 @@ catch.dispatch.1: outer.catch: %cp1 = catchpad within %cs1 [i32 1] - invoke void @f() + invoke void @f() [ "funclet"(token %cp1) ] to label %outer.ret unwind label %catch.dispatch.2 outer.ret: catchret from %cp1 to label %exit diff --git a/test/CodeGen/X86/win-catchpad.ll b/test/CodeGen/X86/win-catchpad.ll index 5bd25046130..836c53bda8e 100644 --- a/test/CodeGen/X86/win-catchpad.ll +++ b/test/CodeGen/X86/win-catchpad.ll @@ -41,12 +41,12 @@ catch.dispatch: ; preds = %entry handler1: %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e.addr] %e = load i32, i32* %e.addr - call void @f(i32 %e, i32* %local) + call void @f(i32 %e, i32* %local) [ "funclet"(token %h1) ] catchret from %h1 to label %try.cont handler2: %h2 = catchpad within %cs [i8* null, i32 64, i8* null] - call void @f(i32 3, i32* %local) + call void @f(i32 3, i32* %local) [ "funclet"(token %h2) ] catchret from %h2 to label %try.cont try.cont: @@ -229,7 +229,7 @@ catch: br label %loop loop: - %V = call i1 @getbool() + %V = call i1 @getbool() [ "funclet"(token %cp1) ] br i1 %V, label %loop, label %catch.done catch.done: diff --git a/test/CodeGen/X86/win-cleanuppad.ll b/test/CodeGen/X86/win-cleanuppad.ll index 37090c2f6bc..4b0a543a876 100644 --- a/test/CodeGen/X86/win-cleanuppad.ll +++ b/test/CodeGen/X86/win-cleanuppad.ll @@ -15,7 +15,7 @@ invoke.cont: ; preds = %entry ehcleanup: ; preds = %entry %0 = cleanuppad within none [] - call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 + call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2 [ "funclet"(token %0) ] cleanupret from %0 unwind to caller } @@ -78,12 +78,12 @@ invoke.cont.2: ; preds = %invoke.cont.1 cleanup.inner: ; preds = %invoke.cont %0 = cleanuppad within none [] - call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 + call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2 [ "funclet"(token %0) ] cleanupret from %0 unwind label %cleanup.outer cleanup.outer: ; preds = %invoke.cont.1, %cleanup.inner, %entry %1 = cleanuppad within none [] - call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 + call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2 [ "funclet"(token %1) ] cleanupret from %1 unwind to caller } diff --git a/test/CodeGen/X86/win-funclet-cfi.ll b/test/CodeGen/X86/win-funclet-cfi.ll index 95afa75a709..2151cdc7bb4 100644 --- a/test/CodeGen/X86/win-funclet-cfi.ll +++ b/test/CodeGen/X86/win-funclet-cfi.ll @@ -10,7 +10,7 @@ entry: cleanupblock: %cleanp = cleanuppad within none [] - call void @g() + call void @g() [ "funclet"(token %cleanp) ] cleanupret from %cleanp unwind label %catch.dispatch catch.dispatch: @@ -18,7 +18,7 @@ catch.dispatch: catch: %cp = catchpad within %cs1 [i8* null, i32 64, i8* null] - call void @g() + call void @g() [ "funclet"(token %cp) ] catchret from %cp to label %try.cont try.cont: diff --git a/test/CodeGen/X86/win32-eh-states.ll b/test/CodeGen/X86/win32-eh-states.ll index fe3639b97a4..2777d6644e6 100644 --- a/test/CodeGen/X86/win32-eh-states.ll +++ b/test/CodeGen/X86/win32-eh-states.ll @@ -48,7 +48,7 @@ lpad: ; preds = %catch, %entry catch: ; preds = %lpad.1 %p1 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] - invoke void @may_throw(i32 3) + invoke void @may_throw(i32 3) [ "funclet"(token %p1) ] to label %invoke.cont.3 unwind label %lpad.1 invoke.cont.3: ; preds = %catch @@ -59,7 +59,7 @@ lpad.1: ; preds = %invoke.cont catch.7: %p2 = catchpad within %cs2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null] - call void @may_throw(i32 4) + call void @may_throw(i32 4) [ "funclet"(token %p2) ] catchret from %p2 to label %try.cont.9 } @@ -131,19 +131,19 @@ catch.dispatch: ; preds = %entry catch: ; preds = %catch.dispatch %1 = catchpad within %0 [i8* null, i32 64, i8* null] - invoke void @may_throw(i32 0) + invoke void @may_throw(i32 0) [ "funclet"(token %1) ] to label %invoke.cont unwind label %ehcleanup5 invoke.cont: ; preds = %catch - invoke void @may_throw(i32 1) + invoke void @may_throw(i32 1) [ "funclet"(token %1) ] to label %invoke.cont2 unwind label %ehcleanup invoke.cont2: ; preds = %invoke.cont - invoke void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) + invoke void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) [ "funclet"(token %1) ] to label %invoke.cont3 unwind label %ehcleanup5 invoke.cont3: ; preds = %invoke.cont2 - invoke void @may_throw(i32 2) + invoke void @may_throw(i32 2) [ "funclet"(token %1) ] to label %invoke.cont4 unwind label %ehcleanup5 invoke.cont4: ; preds = %invoke.cont3 @@ -155,12 +155,12 @@ try.cont: ; preds = %invoke.cont4 ehcleanup: ; preds = %invoke.cont %2 = cleanuppad within %1 [] - call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) + call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y) [ "funclet"(token %2) ] cleanupret from %2 unwind label %ehcleanup5 ehcleanup5: ; preds = %invoke.cont2, %invoke.cont3, %ehcleanup, %catch, %catch.dispatch %3 = cleanuppad within none [] - call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x) + call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x) [ "funclet"(token %3) ] cleanupret from %3 unwind to caller unreachable: ; preds = %entry diff --git a/test/CodeGen/X86/win32-seh-catchpad.ll b/test/CodeGen/X86/win32-seh-catchpad.ll index 88dea367572..6c25161ec8c 100644 --- a/test/CodeGen/X86/win32-seh-catchpad.ll +++ b/test/CodeGen/X86/win32-seh-catchpad.ll @@ -193,7 +193,7 @@ catch.dispatch: ; preds = %entry __except.ret: ; preds = %catch.dispatch %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] - call void @f(i32 2) + call void @f(i32 2) [ "funclet"(token %0) ] catchret from %0 to label %__except __except: diff --git a/test/CodeGen/X86/win32-seh-nested-finally.ll b/test/CodeGen/X86/win32-seh-nested-finally.ll index c91a14278ec..61bf79a76f8 100644 --- a/test/CodeGen/X86/win32-seh-nested-finally.ll +++ b/test/CodeGen/X86/win32-seh-nested-finally.ll @@ -18,7 +18,7 @@ invoke.cont.1: ; preds = %invoke.cont ehcleanup: ; preds = %entry %0 = cleanuppad within none [] - invoke void @f(i32 2) #3 + invoke void @f(i32 2) #3 [ "funclet"(token %0) ] to label %invoke.cont.2 unwind label %ehcleanup.3 invoke.cont.2: ; preds = %ehcleanup @@ -26,7 +26,7 @@ invoke.cont.2: ; preds = %ehcleanup ehcleanup.3: ; preds = %invoke.cont.2, %ehcleanup.end, %invoke.cont %1 = cleanuppad within none [] - call void @f(i32 3) #3 + call void @f(i32 3) #3 [ "funclet"(token %1) ] cleanupret from %1 unwind to caller } diff --git a/test/CodeGen/X86/wineh-coreclr.ll b/test/CodeGen/X86/wineh-coreclr.ll index 7bbc64ece8e..b61876827ca 100644 --- a/test/CodeGen/X86/wineh-coreclr.ll +++ b/test/CodeGen/X86/wineh-coreclr.ll @@ -65,12 +65,12 @@ catch1.body: ; ^ exception pointer passed in rdx ; CHECK-NEXT: callq g %exn1 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch1) - call void @g(i8 addrspace(1)* %exn1) + call void @g(i8 addrspace(1)* %exn1) [ "funclet"(token %catch1) ] ; CHECK: [[L_before_f3:.+]]: ; CHECK-NEXT: movl $3, %ecx ; CHECK-NEXT: callq f ; CHECK-NEXT: [[L_after_f3:.+]]: - invoke void @f(i32 3) + invoke void @f(i32 3) [ "funclet"(token %catch1) ] to label %catch1.ret unwind label %finally.pad catch1.ret: catchret from %catch1 to label %finally.clone @@ -88,12 +88,12 @@ catch2.body: ; ^ exception pointer passed in rdx ; CHECK-NEXT: callq g %exn2 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch2) - call void @g(i8 addrspace(1)* %exn2) + call void @g(i8 addrspace(1)* %exn2) [ "funclet"(token %catch2) ] ; CHECK: [[L_before_f4:.+]]: ; CHECK-NEXT: movl $4, %ecx ; CHECK-NEXT: callq f ; CHECK-NEXT: [[L_after_f4:.+]]: - invoke void @f(i32 4) + invoke void @f(i32 4) [ "funclet"(token %catch2) ] to label %try_in_catch unwind label %finally.pad try_in_catch: ; CHECK: # %try_in_catch @@ -101,7 +101,7 @@ try_in_catch: ; CHECK-NEXT: movl $5, %ecx ; CHECK-NEXT: callq f ; CHECK-NEXT: [[L_after_f5:.+]]: - invoke void @f(i32 5) + invoke void @f(i32 5) [ "funclet"(token %catch2) ] to label %catch2.ret unwind label %fault.pad fault.pad: ; CHECK: .seh_proc [[L_fault:[^ ]+]] @@ -117,7 +117,7 @@ fault.pad: ; CHECK-NEXT: movl $6, %ecx ; CHECK-NEXT: callq f ; CHECK-NEXT: [[L_after_f6:.+]]: - invoke void @f(i32 6) + invoke void @f(i32 6) [ "funclet"(token %fault) ] to label %fault.ret unwind label %finally.pad fault.ret: cleanupret from %fault unwind label %finally.pad @@ -138,7 +138,7 @@ finally.pad: ; CHECK: .seh_endprologue ; CHECK-NEXT: movl $7, %ecx ; CHECK-NEXT: callq f - call void @f(i32 7) + call void @f(i32 7) [ "funclet"(token %finally) ] cleanupret from %finally unwind to caller tail: call void @f(i32 8) diff --git a/test/CodeGen/X86/wineh-exceptionpointer.ll b/test/CodeGen/X86/wineh-exceptionpointer.ll index 9c1f0aaf3de..f6fd4fe7c52 100644 --- a/test/CodeGen/X86/wineh-exceptionpointer.ll +++ b/test/CodeGen/X86/wineh-exceptionpointer.ll @@ -19,7 +19,7 @@ catch.body: %catch = catchpad within %cs1 [i32 5] %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch) %cast_exn = bitcast i8 addrspace(1)* %exn to i32 addrspace(1)* - call void @g(i32 addrspace(1)* %cast_exn) + call void @g(i32 addrspace(1)* %cast_exn) [ "funclet"(token %catch) ] catchret from %catch to label %exit exit: ret void