[cfe-commits] r132269 - in /cfe/trunk: lib/CodeGen/CGException.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h test/CXX/except/except.spec/p9-dynamic.cpp test/CodeGenCXX/arm.cpp test/CodeGenCXX/destructors.cpp test/CodeGenCXX/eh.cpp test/CodeGenCXX/exceptions.cpp test/CodeGenCXX/goto.cpp test/CodeGenCXX/nrvo.cpp test/CodeGenCXX/threadsafe-statics-exceptions.cpp test/CodeGenObjC/blocks-2.m test/CodeGenObjC/unwind-fn.m
John McCall
rjmccall at apple.com
Sat May 28 14:13:02 PDT 2011
Author: rjmccall
Date: Sat May 28 16:13:02 2011
New Revision: 132269
URL: http://llvm.org/viewvc/llvm-project?rev=132269&view=rev
Log:
Convert Clang over to resuming from landing pads with llvm.eh.resume.
It's quite likely that this will explode, but I need to know how. :)
Removed:
cfe/trunk/test/CodeGenObjC/unwind-fn.m
Modified:
cfe/trunk/lib/CodeGen/CGException.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/test/CXX/except/except.spec/p9-dynamic.cpp
cfe/trunk/test/CodeGenCXX/arm.cpp
cfe/trunk/test/CodeGenCXX/destructors.cpp
cfe/trunk/test/CodeGenCXX/eh.cpp
cfe/trunk/test/CodeGenCXX/exceptions.cpp
cfe/trunk/test/CodeGenCXX/goto.cpp
cfe/trunk/test/CodeGenCXX/nrvo.cpp
cfe/trunk/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
cfe/trunk/test/CodeGenObjC/blocks-2.m
Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Sat May 28 16:13:02 2011
@@ -112,11 +112,18 @@
return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
}
+llvm::Constant *CodeGenFunction::getUnwindResumeFn() {
+ const llvm::FunctionType *FTy =
+ llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
+
+ if (CGM.getLangOptions().SjLjExceptions)
+ return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
+ return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume");
+}
+
llvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {
- const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
const llvm::FunctionType *FTy =
- llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), Int8PtrTy,
- /*IsVarArgs=*/false);
+ llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
if (CGM.getLangOptions().SjLjExceptions)
return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow");
@@ -354,13 +361,17 @@
}
llvm::Value *CodeGenFunction::getExceptionSlot() {
- if (!ExceptionSlot) {
- const llvm::Type *i8p = llvm::Type::getInt8PtrTy(getLLVMContext());
- ExceptionSlot = CreateTempAlloca(i8p, "exn.slot");
- }
+ if (!ExceptionSlot)
+ ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
return ExceptionSlot;
}
+llvm::Value *CodeGenFunction::getEHSelectorSlot() {
+ if (!EHSelectorSlot)
+ EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
+ return EHSelectorSlot;
+}
+
void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
if (!E->getSubExpr()) {
if (getInvokeDest()) {
@@ -563,47 +574,59 @@
return LP;
}
+// This code contains a hack to work around a design flaw in
+// LLVM's EH IR which breaks semantics after inlining. This same
+// hack is implemented in llvm-gcc.
+//
+// The LLVM EH abstraction is basically a thin veneer over the
+// traditional GCC zero-cost design: for each range of instructions
+// in the function, there is (at most) one "landing pad" with an
+// associated chain of EH actions. A language-specific personality
+// function interprets this chain of actions and (1) decides whether
+// or not to resume execution at the landing pad and (2) if so,
+// provides an integer indicating why it's stopping. In LLVM IR,
+// the association of a landing pad with a range of instructions is
+// achieved via an invoke instruction, the chain of actions becomes
+// the arguments to the @llvm.eh.selector call, and the selector
+// call returns the integer indicator. Other than the required
+// presence of two intrinsic function calls in the landing pad,
+// the IR exactly describes the layout of the output code.
+//
+// A principal advantage of this design is that it is completely
+// language-agnostic; in theory, the LLVM optimizers can treat
+// landing pads neutrally, and targets need only know how to lower
+// the intrinsics to have a functioning exceptions system (assuming
+// that platform exceptions follow something approximately like the
+// GCC design). Unfortunately, landing pads cannot be combined in a
+// language-agnostic way: given selectors A and B, there is no way
+// to make a single landing pad which faithfully represents the
+// semantics of propagating an exception first through A, then
+// through B, without knowing how the personality will interpret the
+// (lowered form of the) selectors. This means that inlining has no
+// choice but to crudely chain invokes (i.e., to ignore invokes in
+// the inlined function, but to turn all unwindable calls into
+// invokes), which is only semantically valid if every unwind stops
+// at every landing pad.
+//
+// Therefore, the invoke-inline hack is to guarantee that every
+// landing pad has a catch-all.
+enum CleanupHackLevel_t {
+ /// A level of hack that requires that all landing pads have
+ /// catch-alls.
+ CHL_MandatoryCatchall,
+
+ /// A level of hack that requires that all landing pads handle
+ /// cleanups.
+ CHL_MandatoryCleanup,
+
+ /// No hacks at all; ideal IR generation.
+ CHL_Ideal
+};
+const CleanupHackLevel_t CleanupHackLevel = CHL_MandatoryCleanup;
+
llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
assert(EHStack.requiresLandingPad());
- // This function contains a hack to work around a design flaw in
- // LLVM's EH IR which breaks semantics after inlining. This same
- // hack is implemented in llvm-gcc.
- //
- // The LLVM EH abstraction is basically a thin veneer over the
- // traditional GCC zero-cost design: for each range of instructions
- // in the function, there is (at most) one "landing pad" with an
- // associated chain of EH actions. A language-specific personality
- // function interprets this chain of actions and (1) decides whether
- // or not to resume execution at the landing pad and (2) if so,
- // provides an integer indicating why it's stopping. In LLVM IR,
- // the association of a landing pad with a range of instructions is
- // achieved via an invoke instruction, the chain of actions becomes
- // the arguments to the @llvm.eh.selector call, and the selector
- // call returns the integer indicator. Other than the required
- // presence of two intrinsic function calls in the landing pad,
- // the IR exactly describes the layout of the output code.
- //
- // A principal advantage of this design is that it is completely
- // language-agnostic; in theory, the LLVM optimizers can treat
- // landing pads neutrally, and targets need only know how to lower
- // the intrinsics to have a functioning exceptions system (assuming
- // that platform exceptions follow something approximately like the
- // GCC design). Unfortunately, landing pads cannot be combined in a
- // language-agnostic way: given selectors A and B, there is no way
- // to make a single landing pad which faithfully represents the
- // semantics of propagating an exception first through A, then
- // through B, without knowing how the personality will interpret the
- // (lowered form of the) selectors. This means that inlining has no
- // choice but to crudely chain invokes (i.e., to ignore invokes in
- // the inlined function, but to turn all unwindable calls into
- // invokes), which is only semantically valid if every unwind stops
- // at every landing pad.
- //
- // Therefore, the invoke-inline hack is to guarantee that every
- // landing pad has a catch-all.
- const bool UseInvokeInlineHack = true;
-
for (EHScopeStack::iterator ir = EHStack.begin(); ; ) {
assert(ir != EHStack.end() &&
"stack requiring landing pad is nothing but non-EH scopes?");
@@ -736,16 +759,23 @@
EHSelector.append(EHFilters.begin(), EHFilters.end());
// Also check whether we need a cleanup.
- if (UseInvokeInlineHack || HasEHCleanup)
- EHSelector.push_back(UseInvokeInlineHack
+ if (CleanupHackLevel == CHL_MandatoryCatchall || HasEHCleanup)
+ EHSelector.push_back(CleanupHackLevel == CHL_MandatoryCatchall
? getCatchAllValue(*this)
: getCleanupValue(*this));
// Otherwise, signal that we at least have cleanups.
- } else if (UseInvokeInlineHack || HasEHCleanup) {
- EHSelector.push_back(UseInvokeInlineHack
+ } else if (CleanupHackLevel == CHL_MandatoryCatchall || HasEHCleanup) {
+ EHSelector.push_back(CleanupHackLevel == CHL_MandatoryCatchall
? getCatchAllValue(*this)
: getCleanupValue(*this));
+
+ // At the MandatoryCleanup hack level, we don't need to actually
+ // spuriously tell the unwinder that we have cleanups, but we do
+ // need to always be prepared to handle cleanups.
+ } else if (CleanupHackLevel == CHL_MandatoryCleanup) {
+ // Just don't decrement LastToEmitInLoop.
+
} else {
assert(LastToEmitInLoop > 2);
LastToEmitInLoop--;
@@ -758,6 +788,10 @@
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
EHSelector.begin(), EHSelector.end(), "eh.selector");
Selection->setDoesNotThrow();
+
+ // Save the selector value in mandatory-cleanup mode.
+ if (CleanupHackLevel == CHL_MandatoryCleanup)
+ Builder.CreateStore(Selection, getEHSelectorSlot());
// Select the right handler.
llvm::Value *llvm_eh_typeid_for =
@@ -833,22 +867,13 @@
// If there was a cleanup, we'll need to actually check whether we
// landed here because the filter triggered.
- if (UseInvokeInlineHack || HasEHCleanup) {
- llvm::BasicBlock *RethrowBB = createBasicBlock("cleanup");
+ if (CleanupHackLevel != CHL_Ideal || HasEHCleanup) {
llvm::BasicBlock *UnexpectedBB = createBasicBlock("ehspec.unexpected");
- llvm::Constant *Zero = llvm::ConstantInt::get(Builder.getInt32Ty(), 0);
+ llvm::Constant *Zero = llvm::ConstantInt::get(Int32Ty, 0);
llvm::Value *FailsFilter =
Builder.CreateICmpSLT(SavedSelection, Zero, "ehspec.fails");
- Builder.CreateCondBr(FailsFilter, UnexpectedBB, RethrowBB);
-
- // The rethrow block is where we land if this was a cleanup.
- // TODO: can this be _Unwind_Resume if the InvokeInlineHack is off?
- EmitBlock(RethrowBB);
- Builder.CreateCall(getUnwindResumeOrRethrowFn(),
- Builder.CreateLoad(getExceptionSlot()))
- ->setDoesNotReturn();
- Builder.CreateUnreachable();
+ Builder.CreateCondBr(FailsFilter, UnexpectedBB, getRethrowDest().getBlock());
EmitBlock(UnexpectedBB);
}
@@ -863,7 +888,7 @@
Builder.CreateUnreachable();
// ...or a normal catch handler...
- } else if (!UseInvokeInlineHack && !HasEHCleanup) {
+ } else if (CleanupHackLevel == CHL_Ideal && !HasEHCleanup) {
llvm::Value *Type = EHSelector.back();
EmitBranchThroughEHCleanup(EHHandlers[Type]);
@@ -1440,14 +1465,39 @@
// This can always be a call because we necessarily didn't find
// anything on the EH stack which needs our help.
llvm::StringRef RethrowName = Personality.getCatchallRethrowFnName();
- llvm::Constant *RethrowFn;
- if (!RethrowName.empty())
- RethrowFn = getCatchallRethrowFn(*this, RethrowName);
- else
- RethrowFn = getUnwindResumeOrRethrowFn();
+ if (!RethrowName.empty()) {
+ Builder.CreateCall(getCatchallRethrowFn(*this, RethrowName),
+ Builder.CreateLoad(getExceptionSlot()))
+ ->setDoesNotReturn();
+ } else {
+ llvm::Value *Exn = Builder.CreateLoad(getExceptionSlot());
+
+ switch (CleanupHackLevel) {
+ case CHL_MandatoryCatchall:
+ // In mandatory-catchall mode, we need to use
+ // _Unwind_Resume_or_Rethrow, or whatever the personality's
+ // equivalent is.
+ Builder.CreateCall(getUnwindResumeOrRethrowFn(), Exn)
+ ->setDoesNotReturn();
+ break;
+ case CHL_MandatoryCleanup: {
+ // In mandatory-cleanup mode, we should use llvm.eh.resume.
+ llvm::Value *Selector = Builder.CreateLoad(getEHSelectorSlot());
+ Builder.CreateCall2(CGM.getIntrinsic(llvm::Intrinsic::eh_resume),
+ Exn, Selector)
+ ->setDoesNotReturn();
+ break;
+ }
+ case CHL_Ideal:
+ // In an idealized mode where we don't have to worry about the
+ // optimizer combining landing pads, we should just use
+ // _Unwind_Resume (or the personality's equivalent).
+ Builder.CreateCall(getUnwindResumeFn(), Exn)
+ ->setDoesNotReturn();
+ break;
+ }
+ }
- Builder.CreateCall(RethrowFn, Builder.CreateLoad(getExceptionSlot()))
- ->setDoesNotReturn();
Builder.CreateUnreachable();
Builder.restoreIP(SavedIP);
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sat May 28 16:13:02 2011
@@ -33,9 +33,9 @@
Target(CGM.getContext().Target), Builder(cgm.getModule().getContext()),
BlockInfo(0), BlockPointer(0),
NormalCleanupDest(0), EHCleanupDest(0), NextCleanupDestIndex(1),
- ExceptionSlot(0), DebugInfo(0), DisableDebugInfo(false), IndirectBranch(0),
- SwitchInsn(0), CaseRangeBlock(0),
- DidCallStackSave(false), UnreachableBlock(0),
+ ExceptionSlot(0), EHSelectorSlot(0),
+ DebugInfo(0), DisableDebugInfo(false), DidCallStackSave(false),
+ IndirectBranch(0), SwitchInsn(0), CaseRangeBlock(0), UnreachableBlock(0),
CXXThisDecl(0), CXXThisValue(0), CXXVTTDecl(0), CXXVTTValue(0),
OutermostConditional(0), TerminateLandingPad(0), TerminateHandler(0),
TrapBB(0) {
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat May 28 16:13:02 2011
@@ -603,6 +603,10 @@
/// exception pointer into this alloca.
llvm::Value *ExceptionSlot;
+ /// The selector slot. Under the MandatoryCleanup model, all
+ /// landing pads write the current selector value into this alloca.
+ llvm::AllocaInst *EHSelectorSlot;
+
/// Emits a landing pad for the current EH stack.
llvm::BasicBlock *EmitLandingPad();
@@ -951,6 +955,10 @@
CGDebugInfo *DebugInfo;
bool DisableDebugInfo;
+ /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
+ /// calling llvm.stacksave for multiple VLAs in the same scope.
+ bool DidCallStackSave;
+
/// IndirectBranch - The first time an indirect goto is seen we create a block
/// with an indirect branch. Every time we see the address of a label taken,
/// we add the label to the indirect goto. Every subsequent indirect goto is
@@ -997,10 +1005,6 @@
// enter/leave scopes.
llvm::DenseMap<const Expr*, llvm::Value*> VLASizeMap;
- /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
- /// calling llvm.stacksave for multiple VLAs in the same scope.
- bool DidCallStackSave;
-
/// A block containing a single 'unreachable' instruction. Created
/// lazily by getUnreachableBlock().
llvm::BasicBlock *UnreachableBlock;
@@ -1050,6 +1054,7 @@
/// Returns a pointer to the function's exception object slot, which
/// is assigned in every landing pad.
llvm::Value *getExceptionSlot();
+ llvm::Value *getEHSelectorSlot();
llvm::Value *getNormalCleanupDestSlot();
llvm::Value *getEHCleanupDestSlot();
@@ -1705,6 +1710,7 @@
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
void EmitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt &S);
+ llvm::Constant *getUnwindResumeFn();
llvm::Constant *getUnwindResumeOrRethrowFn();
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock = false);
Modified: cfe/trunk/test/CXX/except/except.spec/p9-dynamic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/except/except.spec/p9-dynamic.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CXX/except/except.spec/p9-dynamic.cpp (original)
+++ cfe/trunk/test/CXX/except/except.spec/p9-dynamic.cpp Sat May 28 16:13:02 2011
@@ -7,5 +7,5 @@
// CHECK: invoke void @_Z8externalv()
external();
}
-// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* bitcast (i8** @_ZTIi to i8*), i8* null) nounwind
+// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector({{.*}} i8* bitcast (i8** @_ZTIi to i8*)) nounwind
// CHECK: call void @__cxa_call_unexpected
Modified: cfe/trunk/test/CodeGenCXX/arm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/arm.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/arm.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/arm.cpp Sat May 28 16:13:02 2011
@@ -310,7 +310,7 @@
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x)
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
}
}
@@ -349,7 +349,7 @@
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x)
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
}
}
Modified: cfe/trunk/test/CodeGenCXX/destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/destructors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/destructors.cpp Sat May 28 16:13:02 2011
@@ -334,7 +334,7 @@
// CHECK: ret void
// CHECK: call i8* @llvm.eh.exception(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
// Checked at top of file:
// @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
@@ -364,7 +364,7 @@
// CHECK: ret void
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call void @_ZdlPv({{.*}}) nounwind
- // CHECK: call void @_Unwind_Resume_or_Rethrow(
+ // CHECK: call void @llvm.eh.resume(
// CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev(
// CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
Modified: cfe/trunk/test/CodeGenCXX/eh.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/eh.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/eh.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/eh.cpp Sat May 28 16:13:02 2011
@@ -30,7 +30,8 @@
}
// CHECK: define void @_Z5test2v()
-// CHECK: [[EXNSLOTVAR:%.*]] = alloca i8*
+// CHECK: [[EXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32
// CHECK-NEXT: [[CLEANUPDESTVAR:%.*]] = alloca i32
// CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16)
// CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]]
@@ -104,6 +105,7 @@
// CHECK: define i32 @_ZN5test73fooEv()
int foo() {
// CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8*
+// CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32
// CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32
// CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32
try {
@@ -117,7 +119,8 @@
// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
-// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
// CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*))
// CHECK-NEXT: icmp eq
// CHECK-NEXT: br i1
@@ -130,7 +133,8 @@
}
// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception()
// CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]]
-// CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+// CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null)
+// CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]]
// CHECK-NEXT: store i32 1, i32* [[EHCLEANUPDESTVAR]]
// CHECK-NEXT: call void @__cxa_end_catch()
// CHECK-NEXT: br label
@@ -190,7 +194,7 @@
// landing pad from first call to invoke
// CHECK: call i8* @llvm.eh.exception
- // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null)
+ // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
}
// __cxa_end_catch can throw for some kinds of caught exceptions.
@@ -255,6 +259,7 @@
void bar() {
try {
// CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
// CHECK-NEXT: [[P:%.*]] = alloca [[A:%.*]]**,
// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]*
// CHECK-NEXT: invoke void @_ZN6test116opaqueEv()
@@ -403,6 +408,7 @@
// CHECK-NEXT: [[EXN_ACTIVE:%.*]] = alloca i1
// CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]],
// CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
// CHECK-NEXT: [[EHDEST:%.*]] = alloca i32
// CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1
Modified: cfe/trunk/test/CodeGenCXX/exceptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/exceptions.cpp Sat May 28 16:13:02 2011
@@ -273,6 +273,7 @@
// CHECK: define void @_ZN5test54testEv()
// CHECK: [[EXNSLOT:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32
// CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1
// CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1
// CHECK-NEXT: alloca i32
@@ -324,6 +325,7 @@
// CHECK-NEXT: alloca [[A:%.*]],
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: alloca i32
+ // CHECK-NEXT: alloca i32
// CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1
Modified: cfe/trunk/test/CodeGenCXX/goto.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/goto.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/goto.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/goto.cpp Sat May 28 16:13:02 2011
@@ -12,6 +12,7 @@
// CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]],
// CHECK-NEXT: [[Z:%.*]] = alloca [[A]]
// CHECK-NEXT: [[EXN:%.*]] = alloca i8*
+ // CHECK-NEXT: [[SEL:%.*]] = alloca i32
// CHECK-NEXT: alloca i32
// CHECK-NEXT: [[V:%.*]] = alloca [[V:%.*]]*,
// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]]
Modified: cfe/trunk/test/CodeGenCXX/nrvo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nrvo.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/nrvo.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/nrvo.cpp Sat May 28 16:13:02 2011
@@ -95,7 +95,7 @@
// %invoke.cont17: rethrow block for %eh.cleanup.
// This really should be elsewhere in the function.
- // CHECK-EH: call void @_Unwind_Resume_or_Rethrow
+ // CHECK-EH: call void @llvm.eh.resume(
// CHECK-EH-NEXT: unreachable
// %terminate.lpad: terminate landing pad.
Modified: cfe/trunk/test/CodeGenCXX/threadsafe-statics-exceptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/threadsafe-statics-exceptions.cpp?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/threadsafe-statics-exceptions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/threadsafe-statics-exceptions.cpp Sat May 28 16:13:02 2011
@@ -24,6 +24,6 @@
// CHECK: call i8* @llvm.eh.exception()
// CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector
// CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x)
- // CHECK: call void @_Unwind_Resume_or_Rethrow
+ // CHECK: call void @llvm.eh.resume(
// CHECK: unreachable
}
Modified: cfe/trunk/test/CodeGenObjC/blocks-2.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/blocks-2.m?rev=132269&r1=132268&r2=132269&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/blocks-2.m (original)
+++ cfe/trunk/test/CodeGenObjC/blocks-2.m Sat May 28 16:13:02 2011
@@ -33,5 +33,5 @@
// CHECK: call i8* @llvm.eh.exception()
// CHECK: [[T1:%.*]] = bitcast [[N_T]]* [[N]] to i8*
// CHECK-NEXT: call void @_Block_object_dispose(i8* [[T1]], i32 8)
- // CHECK: call void @_Unwind_Resume_or_Rethrow(
+ // CHECK: call void @llvm.eh.resume(
}
Removed: cfe/trunk/test/CodeGenObjC/unwind-fn.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/unwind-fn.m?rev=132268&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenObjC/unwind-fn.m (original)
+++ cfe/trunk/test/CodeGenObjC/unwind-fn.m (removed)
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 -fobjc-nonfragile-abi -emit-llvm -fexceptions -fobjc-exceptions -o - %s | FileCheck --check-prefix=DEFAULT_EH %s
-// RUN: %clang_cc1 -fsjlj-exceptions -fobjc-nonfragile-abi -fexceptions -fobjc-exceptions -emit-llvm -o - %s | FileCheck --check-prefix=SJLJ_EH %s
-
-// DEFAULT_EH: declare void @_Unwind_Resume_or_Rethrow(i8*)
-// SJLJ_EH: declare void @_Unwind_SjLj_Resume_or_Rethrow(i8*)
-
-void f1(), f2();
-void f0() {
- @try {
- f1();
- } @catch (...) {
- f2();
- }
-}
More information about the cfe-commits
mailing list