rnk created this revision. rnk added reviewers: smeenai, majnemer. Herald added a subscriber: eraman.
Fixes PR36247, which is where WinEHPrepare replaces inline asm in funclets with unreachable. Make getBundlesForFunclet return by value to simplify some call sites. https://reviews.llvm.org/D43033 Files: clang/lib/CodeGen/CGCall.cpp clang/lib/CodeGen/CGStmt.cpp clang/lib/CodeGen/CodeGenFunction.h clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp
Index: clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/microsoft-abi-eh-inlineasm.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc \ +// RUN: -fexceptions -fcxx-exceptions | FileCheck %s + +// Make sure calls to inline asm have funclet bundles. + +extern "C" void might_throw(); +extern "C" void foo() { + try { + might_throw(); + } catch (int) { + __asm__("nop"); + } +} + +// CHECK-LABEL: define void @foo() +// CHECK: invoke void @might_throw() +// CHECK: %[[CATCHPAD:[^ ]*]] = catchpad within +// CHECK: call void asm sideeffect "nop", {{.*}} [ "funclet"(token %[[CATCHPAD]]) ] Index: clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- clang/lib/CodeGen/CodeGenFunction.h +++ clang/lib/CodeGen/CodeGenFunction.h @@ -3367,6 +3367,9 @@ ArrayRef<llvm::Value*> args, const Twine &name = ""); + SmallVector<llvm::OperandBundleDef, 1> + getBundlesForFunclet(llvm::Value *Callee); + llvm::CallSite EmitCallOrInvoke(llvm::Value *Callee, ArrayRef<llvm::Value *> Args, const Twine &Name = ""); Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -2133,7 +2133,8 @@ llvm::InlineAsm *IA = llvm::InlineAsm::get(FTy, AsmString, Constraints, HasSideEffect, /* IsAlignStack */ false, AsmDialect); - llvm::CallInst *Result = Builder.CreateCall(IA, Args); + llvm::CallInst *Result = + Builder.CreateCall(IA, Args, getBundlesForFunclet(IA)); Result->addAttribute(llvm::AttributeList::FunctionIndex, llvm::Attribute::NoUnwind); Index: clang/lib/CodeGen/CGCall.cpp =================================================================== --- clang/lib/CodeGen/CGCall.cpp +++ clang/lib/CodeGen/CGCall.cpp @@ -3608,40 +3608,39 @@ // Calls which may throw must have operand bundles indicating which funclet // they are nested within. -static void -getBundlesForFunclet(llvm::Value *Callee, llvm::Instruction *CurrentFuncletPad, - SmallVectorImpl<llvm::OperandBundleDef> &BundleList) { +SmallVector<llvm::OperandBundleDef, 1> +CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) { + SmallVector<llvm::OperandBundleDef, 1> BundleList; // There is no need for a funclet operand bundle if we aren't inside a // funclet. if (!CurrentFuncletPad) - return; + return BundleList; // Skip intrinsics which cannot throw. auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts()); if (CalleeFn && CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) - return; + return BundleList; BundleList.emplace_back("funclet", CurrentFuncletPad); + return BundleList; } /// Emits a simple call (never an invoke) to the given runtime function. llvm::CallInst * CodeGenFunction::EmitRuntimeCall(llvm::Value *callee, ArrayRef<llvm::Value*> args, const llvm::Twine &name) { - SmallVector<llvm::OperandBundleDef, 1> BundleList; - getBundlesForFunclet(callee, CurrentFuncletPad, BundleList); - - llvm::CallInst *call = Builder.CreateCall(callee, args, BundleList, name); + llvm::CallInst *call = + Builder.CreateCall(callee, args, getBundlesForFunclet(callee), name); call->setCallingConv(getRuntimeCC()); return call; } /// Emits a call or invoke to the given noreturn runtime function. void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(llvm::Value *callee, ArrayRef<llvm::Value*> args) { - SmallVector<llvm::OperandBundleDef, 1> BundleList; - getBundlesForFunclet(callee, CurrentFuncletPad, BundleList); + SmallVector<llvm::OperandBundleDef, 1> BundleList = + getBundlesForFunclet(callee); if (getInvokeDest()) { llvm::InvokeInst *invoke = @@ -3684,8 +3683,8 @@ ArrayRef<llvm::Value *> Args, const Twine &Name) { llvm::BasicBlock *InvokeDest = getInvokeDest(); - SmallVector<llvm::OperandBundleDef, 1> BundleList; - getBundlesForFunclet(Callee, CurrentFuncletPad, BundleList); + SmallVector<llvm::OperandBundleDef, 1> BundleList = + getBundlesForFunclet(Callee); llvm::Instruction *Inst; if (!InvokeDest) @@ -4196,8 +4195,8 @@ } llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest(); - SmallVector<llvm::OperandBundleDef, 1> BundleList; - getBundlesForFunclet(CalleePtr, CurrentFuncletPad, BundleList); + SmallVector<llvm::OperandBundleDef, 1> BundleList = + getBundlesForFunclet(CalleePtr); // Emit the actual call/invoke instruction. llvm::CallSite CS;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits