r249647 - [WinEH] Remove NewMSEH and enable its behavior by default

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 7 18:13:53 PDT 2015


Author: rnk
Date: Wed Oct  7 20:13:52 2015
New Revision: 249647

URL: http://llvm.org/viewvc/llvm-project?rev=249647&view=rev
Log:
[WinEH] Remove NewMSEH and enable its behavior by default

Testing has shown that it is at least as reliable as the old landingpad
pattern matching code.

Removed:
    cfe/trunk/test/CodeGen/exceptions-seh-leave-new.c
    cfe/trunk/test/CodeGen/exceptions-seh-new.c
Modified:
    cfe/trunk/include/clang/Frontend/CodeGenOptions.def
    cfe/trunk/lib/CodeGen/CGCleanup.cpp
    cfe/trunk/lib/CodeGen/CGCleanup.h
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/test/CodeGen/exceptions-seh-finally.c
    cfe/trunk/test/CodeGen/exceptions-seh-leave.c
    cfe/trunk/test/CodeGen/exceptions-seh.c
    cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
    cfe/trunk/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
    cfe/trunk/test/OpenMP/parallel_codegen.cpp

Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.def?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CodeGenOptions.def (original)
+++ cfe/trunk/include/clang/Frontend/CodeGenOptions.def Wed Oct  7 20:13:52 2015
@@ -33,7 +33,6 @@ CODEGENOPT(CompressDebugSections, 1, 0)
 CODEGENOPT(Autolink          , 1, 1) ///< -fno-autolink
 CODEGENOPT(AsmVerbose        , 1, 0) ///< -dA, -fverbose-asm.
 CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe.
-CODEGENOPT(NewMSEH           , 1, 0) ///< Whether we should use the new IR representation for MS exceptions
 CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
 CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files.
 CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files.

Modified: cfe/trunk/lib/CodeGen/CGCleanup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Wed Oct  7 20:13:52 2015
@@ -933,8 +933,7 @@ void CodeGenFunction::PopCleanupBlock(bo
     EmitBlock(EHEntry);
     llvm::CleanupPadInst *CPI = nullptr;
     llvm::BasicBlock *NextAction = getEHDispatchBlock(EHParent);
-    if (CGM.getCodeGenOpts().NewMSEH &&
-        EHPersonality::get(*this).isMSVCPersonality())
+    if (EHPersonality::get(*this).usesFuncletPads())
       CPI = Builder.CreateCleanupPad({});
 
     // We only actually emit the cleanup code if the cleanup is either

Modified: cfe/trunk/lib/CodeGen/CGCleanup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.h?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.h (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.h Wed Oct  7 20:13:52 2015
@@ -633,6 +633,10 @@ struct EHPersonality {
   static const EHPersonality MSVC_C_specific_handler;
   static const EHPersonality MSVC_CxxFrameHandler3;
 
+  /// Does this personality use landingpads or the family of pad instructions
+  /// designed to form funclets?
+  bool usesFuncletPads() const { return isMSVCPersonality(); }
+
   bool isMSVCPersonality() const {
     return this == &MSVC_except_handler || this == &MSVC_C_specific_handler ||
            this == &MSVC_CxxFrameHandler3;

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Wed Oct  7 20:13:52 2015
@@ -572,8 +572,7 @@ void CodeGenFunction::EnterCXXTryStmt(co
 
 llvm::BasicBlock *
 CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
-  if (CGM.getCodeGenOpts().NewMSEH &&
-      EHPersonality::get(*this).isMSVCPersonality())
+  if (EHPersonality::get(*this).usesFuncletPads())
     return getMSVCDispatchBlock(si);
 
   // The dispatch block for the end of the scope chain is a block that
@@ -705,8 +704,8 @@ llvm::BasicBlock *CodeGenFunction::getIn
   if (!CurFn->hasPersonalityFn())
     CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
 
-  if (CGM.getCodeGenOpts().NewMSEH && Personality.isMSVCPersonality()) {
-    // We don't need separate landing pads in the MSVC model.
+  if (Personality.usesFuncletPads()) {
+    // We don't need separate landing pads in the funclet model.
     LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
   } else {
     // Build the landing pad for this scope.
@@ -870,8 +869,8 @@ llvm::BasicBlock *CodeGenFunction::EmitL
   return lpad;
 }
 
-static llvm::BasicBlock *emitMSVCCatchDispatchBlock(CodeGenFunction &CGF,
-                                                    EHCatchScope &CatchScope) {
+static llvm::BasicBlock *emitCatchPadBlock(CodeGenFunction &CGF,
+                                           EHCatchScope &CatchScope) {
   llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
   assert(DispatchBlock);
 
@@ -922,9 +921,8 @@ static llvm::BasicBlock *emitMSVCCatchDi
 /// block holding the final catchendblock instruction is returned.
 static llvm::BasicBlock *emitCatchDispatchBlock(CodeGenFunction &CGF,
                                                 EHCatchScope &catchScope) {
-  if (CGF.CGM.getCodeGenOpts().NewMSEH &&
-      EHPersonality::get(CGF).isMSVCPersonality())
-    return emitMSVCCatchDispatchBlock(CGF, catchScope);
+  if (EHPersonality::get(CGF).usesFuncletPads())
+    return emitCatchPadBlock(CGF, catchScope);
 
   llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
   assert(dispatchBlock);
@@ -1337,8 +1335,7 @@ llvm::BasicBlock *CodeGenFunction::getTe
   // end of the function by FinishFunction.
   TerminateHandler = createBasicBlock("terminate.handler");
   Builder.SetInsertPoint(TerminateHandler);
-  if (CGM.getCodeGenOpts().NewMSEH &&
-      EHPersonality::get(*this).isMSVCPersonality()) {
+  if (EHPersonality::get(*this).usesFuncletPads()) {
     Builder.CreateTerminatePad(/*UnwindBB=*/nullptr, CGM.getTerminateFn());
   } else {
     llvm::Value *Exn = nullptr;
@@ -1441,8 +1438,8 @@ struct PerformSEHFinally final : EHScope
         CGM.getTypes().arrangeFreeFunctionCall(Args, FPT,
                                                /*chainCall=*/false);
 
-    // If this is the normal cleanup or using the old EH IR, just emit the call.
-    if (!F.isForEHCleanup() || !CGM.getCodeGenOpts().NewMSEH) {
+    // If this is the normal cleanup, just emit the call.
+    if (!F.isForEHCleanup()) {
       CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
       return;
     }
@@ -1888,31 +1885,22 @@ void CodeGenFunction::ExitSEHTryStmt(con
 
   EmitBlockAfterUses(ExceptBB);
 
-  if (CGM.getCodeGenOpts().NewMSEH) {
-    // __except blocks don't get outlined into funclets, so immediately do a
-    // catchret.
-    llvm::BasicBlock *CatchPadBB = ExceptBB->getSinglePredecessor();
-    assert(CatchPadBB && "only ExceptBB pred should be catchpad");
-    llvm::CatchPadInst *CPI =
-        cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
-    ExceptBB = createBasicBlock("__except");
-    Builder.CreateCatchRet(CPI, ExceptBB);
-    EmitBlock(ExceptBB);
-    // On Win64, the exception code is returned in EAX. Copy it into the slot.
-    if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
-      llvm::Function *SEHCodeIntrin =
-          CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
-      llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
-      Builder.CreateStore(Code, SEHCodeSlotStack.back());
-    }
-  } else {
-    // On Win64, the exception pointer is the exception code. Copy it to the slot.
-    if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
-      llvm::Value *Code =
-          Builder.CreatePtrToInt(getExceptionFromSlot(), IntPtrTy);
-      Code = Builder.CreateTrunc(Code, Int32Ty);
-      Builder.CreateStore(Code, SEHCodeSlotStack.back());
-    }
+  // __except blocks don't get outlined into funclets, so immediately do a
+  // catchret.
+  llvm::BasicBlock *CatchPadBB = ExceptBB->getSinglePredecessor();
+  assert(CatchPadBB && "only ExceptBB pred should be catchpad");
+  llvm::CatchPadInst *CPI =
+      cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
+  ExceptBB = createBasicBlock("__except");
+  Builder.CreateCatchRet(CPI, ExceptBB);
+  EmitBlock(ExceptBB);
+
+  // On Win64, the exception code is returned in EAX. Copy it into the slot.
+  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
+    llvm::Function *SEHCodeIntrin =
+        CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
+    llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
+    Builder.CreateStore(Code, SEHCodeSlotStack.back());
   }
 
   // Emit the __except body.

Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Oct  7 20:13:52 2015
@@ -879,20 +879,15 @@ void MicrosoftCXXABI::emitRethrow(CodeGe
 }
 
 namespace {
-struct CallEndCatchMSVC final : EHScopeStack::Cleanup {
+struct CatchRetScope final : EHScopeStack::Cleanup {
   llvm::CatchPadInst *CPI;
 
-  CallEndCatchMSVC(llvm::CatchPadInst *CPI) : CPI(CPI) {}
+  CatchRetScope(llvm::CatchPadInst *CPI) : CPI(CPI) {}
 
   void Emit(CodeGenFunction &CGF, Flags flags) override {
-    if (CGF.CGM.getCodeGenOpts().NewMSEH) {
-      llvm::BasicBlock *BB = CGF.createBasicBlock("catchret.dest");
-      CGF.Builder.CreateCatchRet(CPI, BB);
-      CGF.EmitBlock(BB);
-    } else {
-      CGF.EmitNounwindRuntimeCall(
-          CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_endcatch));
-    }
+    llvm::BasicBlock *BB = CGF.createBasicBlock("catchret.dest");
+    CGF.Builder.CreateCatchRet(CPI, BB);
+    CGF.EmitBlock(BB);
   }
 };
 }
@@ -902,39 +897,21 @@ void MicrosoftCXXABI::emitBeginCatch(Cod
   // In the MS ABI, the runtime handles the copy, and the catch handler is
   // responsible for destruction.
   VarDecl *CatchParam = S->getExceptionDecl();
-  llvm::Value *Exn = nullptr;
-  llvm::Function *BeginCatch = nullptr;
-  llvm::CatchPadInst *CPI = nullptr;
-  bool NewEH = CGF.CGM.getCodeGenOpts().NewMSEH;
-  if (!NewEH) {
-    Exn = CGF.getExceptionFromSlot();
-    BeginCatch = CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_begincatch);
-  } else {
-    llvm::BasicBlock *CatchPadBB =
-        CGF.Builder.GetInsertBlock()->getSinglePredecessor();
-    CPI = cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
-  }
+  llvm::BasicBlock *CatchPadBB =
+      CGF.Builder.GetInsertBlock()->getSinglePredecessor();
+  llvm::CatchPadInst *CPI =
+      cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
+
   // If this is a catch-all or the catch parameter is unnamed, we don't need to
   // emit an alloca to the object.
   if (!CatchParam || !CatchParam->getDeclName()) {
-    if (!NewEH) {
-      llvm::Value *Args[2] = {Exn, llvm::Constant::getNullValue(CGF.Int8PtrTy)};
-      CGF.EmitNounwindRuntimeCall(BeginCatch, Args);
-    }
-    CGF.EHStack.pushCleanup<CallEndCatchMSVC>(NormalCleanup, CPI);
+    CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
     return;
   }
 
   CodeGenFunction::AutoVarEmission var = CGF.EmitAutoVarAlloca(*CatchParam);
-  if (!NewEH) {
-    Address ParamAddr =
-        CGF.Builder.CreateElementBitCast(var.getObjectAddress(CGF), CGF.Int8Ty);
-    llvm::Value *Args[2] = {Exn, ParamAddr.getPointer()};
-    CGF.EmitNounwindRuntimeCall(BeginCatch, Args);
-  } else {
-    CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer());
-  }
-  CGF.EHStack.pushCleanup<CallEndCatchMSVC>(NormalCleanup, CPI);
+  CPI->setArgOperand(2, var.getObjectAddress(CGF).getPointer());
+  CGF.EHStack.pushCleanup<CatchRetScope>(NormalCleanup, CPI);
   CGF.EmitAutoVarCleanups(var);
 }
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Oct  7 20:13:52 2015
@@ -462,7 +462,6 @@ static bool ParseCodeGenArgs(CodeGenOpti
   Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
   Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
   Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
-  Opts.NewMSEH = Args.hasArg(OPT_fnew_ms_eh);
   Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
   Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
   Opts.CodeModel = getCodeModel(Args, Diags);

Modified: cfe/trunk/test/CodeGen/exceptions-seh-finally.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-finally.c?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-finally.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-finally.c Wed Oct  7 20:13:52 2015
@@ -23,11 +23,14 @@ void basic_finally(void) {
 // CHECK-NEXT: ret void
 //
 // CHECK: [[lpad]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
+// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
-// CHECK: resume { i8*, i32 }
+// CHECK: invoke void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK-NEXT: to label %{{.*}} unwind label %[[end:[^ ]*]]
+// CHECK: cleanupret %[[pad]] unwind to caller
+//
+// CHECK: [[end]]
+// CHECK: cleanupendpad %[[pad]] unwind to caller
 
 // CHECK: define internal void @"\01?fin$0 at 0@basic_finally@@"({{.*}})
 // CHECK: call void @cleanup()
@@ -90,11 +93,14 @@ void use_abnormal_termination(void) {
 // CHECK: ret void
 //
 // CHECK: [[lpad]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
+// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
-// CHECK: resume { i8*, i32 }
+// CHECK: invoke void @"\01?fin$0 at 0@use_abnormal_termination@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK-NEXT: to label %{{.*}} unwind label %[[end:[^ ]*]]
+// CHECK: cleanupret %[[pad]] unwind to caller
+//
+// CHECK: [[end]]
+// CHECK: cleanupendpad %[[pad]] unwind to caller
 
 // CHECK: define internal void @"\01?fin$0 at 0@use_abnormal_termination@@"({{i8( zeroext)?}} %[[abnormal:abnormal_termination]], i8* %frame_pointer)
 // CHECK: %[[abnormal_zext:[^ ]*]] = zext i8 %[[abnormal]] to i32
@@ -134,10 +140,13 @@ void noreturn_finally() {
 // CHECK: ret void
 //
 // CHECK: [[lpad]]
-// CHECK: landingpad
-// CHECK-NEXT: cleanup
-// CHECK: call void @"\01?fin$0 at 0@noreturn_finally@@"({{.*}})
-// CHECK: resume { i8*, i32 }
+// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
+// CHECK: invoke void @"\01?fin$0 at 0@noreturn_finally@@"({{.*}})
+// CHECK-NEXT: to label %{{.*}} unwind label %[[end:[^ ]*]]
+// CHECK: cleanupret %[[pad]] unwind to caller
+//
+// CHECK: [[end]]
+// CHECK: cleanupendpad %[[pad]] unwind to caller
 
 // CHECK: define internal void @"\01?fin$0 at 0@noreturn_finally@@"({{.*}})
 // CHECK: call void @abort()
@@ -179,9 +188,13 @@ int nested___finally___finally() {
 // CHECK-NEXT: ret i32 0
 //
 // CHECK: [[lpad]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
-// CHECK: call void @"\01?fin$0 at 0@nested___finally___finally@@"({{.*}})
+// CHECK-NEXT: %[[pad:[^ ]*]] = cleanuppad
+// CHECK: invoke void @"\01?fin$0 at 0@nested___finally___finally@@"({{.*}})
+// CHECK-NEXT: to label %{{.*}} unwind label %[[end:[^ ]*]]
+// CHECK: cleanupret %[[pad]] unwind to caller
+//
+// CHECK: [[end]]
+// CHECK: cleanupendpad %[[pad]] unwind to caller
 
 // CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___finally___finally@@"({{.*}})
 // CHECK: ret void
@@ -189,6 +202,8 @@ int nested___finally___finally() {
 // CHECK-LABEL: define internal void @"\01?fin$1 at 0@nested___finally___finally@@"({{.*}})
 // CHECK: unreachable
 
+// FIXME: Our behavior seems suspiciously different.
+
 int nested___finally___finally_with_eh_edge() {
   __try {
     __try {
@@ -207,23 +222,33 @@ int nested___finally___finally_with_eh_e
 //
 // [[invokecont]]
 // CHECK: invoke void @"\01?fin$1 at 0@nested___finally___finally_with_eh_edge@@"({{.*}})
-// CHECK:          to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
+// CHECK-NEXT:       to label %[[outercont:[^ ]*]] unwind label %[[lpad2:[^ ]*]]
 //
 // CHECK: [[outercont]]
 // CHECK: call void @"\01?fin$0 at 0@nested___finally___finally_with_eh_edge@@"({{.*}})
 // CHECK-NEXT: ret i32 912
 //
 // CHECK: [[lpad1]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
+// CHECK-NEXT: %[[innerpad:[^ ]*]] = cleanuppad
 // CHECK: invoke void @"\01?fin$1 at 0@nested___finally___finally_with_eh_edge@@"({{.*}})
-// CHECK:          to label %[[outercont:[^ ]*]] unwind label %[[lpad2]]
+// CHECK-NEXT:     to label %[[innercleanupretbb:[^ ]*]] unwind label %[[innerend:[^ ]*]]
+//
+// CHECK: [[innercleanupretbb]]
+// CHECK-NEXT: cleanupret %[[innerpad]] unwind label %[[lpad2]]
+//
+// CHECK: [[innerend]]
+// CHECK-NEXT: cleanupendpad %[[innerpad]] unwind label %[[lpad2:[^ ]*]]
 //
 // CHECK: [[lpad2]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
-// CHECK: call void @"\01?fin$0 at 0@nested___finally___finally_with_eh_edge@@"({{.*}})
-// CHECK: resume
+// CHECK-NEXT: %[[outerpad:[^ ]*]] = cleanuppad
+// CHECK: invoke void @"\01?fin$0 at 0@nested___finally___finally_with_eh_edge@@"({{.*}})
+// CHECK-NEXT:     to label %[[outercleanupretbb:[^ ]*]] unwind label %[[outerend:[^ ]*]]
+//
+// CHECK: [[outercleanupretbb]]
+// CHECK-NEXT: cleanupret %[[outerpad]] unwind to caller
+//
+// CHECK: [[outerend]]
+// CHECK-NEXT: cleanupendpad %[[outerpad]] unwind to caller
 
 // CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___finally___finally_with_eh_edge@@"({{.*}})
 // CHECK: ret void

Removed: cfe/trunk/test/CodeGen/exceptions-seh-leave-new.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-leave-new.c?rev=249646&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-leave-new.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-leave-new.c (removed)
@@ -1,347 +0,0 @@
-// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - | opt -instnamer -S | FileCheck %s
-
-void g(void);
-
-//////////////////////////////////////////////////////////////////////////////
-// __leave with __except
-
-// Nothing in the __try block can trap, so __try.cont isn't created.
-int __leave_with___except_simple() {
-  int myres = 0;
-  __try {
-    myres = 15;
-    __leave;
-    myres = 23;
-  } __except (1) {
-    return 0;
-  }
-  return 1;
-}
-// CHECK-LABEL: define i32 @__leave_with___except_simple()
-// CHECK: store i32 15, i32* %myres
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-// CHECK: [[tryleave]]
-// CHECK-NEXT: ret i32 1
-
-
-// The "normal" case.
-int __leave_with___except() {
-  int myres = 0;
-  __try {
-    g();
-    __leave;
-    myres = 23;
-  } __except (1) {
-    return 0;
-  }
-  return 1;
-}
-// CHECK-LABEL: define i32 @__leave_with___except()
-// CHECK: invoke void @g()
-// CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}}
-// For __excepts, instead of an explicit __try.__leave label, we could use
-// use invoke.cont as __leave jump target instead.  However, not doing this
-// keeps the CodeGen code simpler, __leave is very rare, and SimplifyCFG will
-// simplify this anyways.
-// CHECK: [[cont]]
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-// CHECK: [[tryleave]]
-// CHECK-NEXT: br label %
-
-
-//////////////////////////////////////////////////////////////////////////////
-// __leave with __finally
-
-void abort(void) __attribute__((noreturn));
-
-// Nothing in the __try block can trap, so __finally.cont and friends aren't
-// created.
-int __leave_with___finally_simple() {
-  int myres = 0;
-  __try {
-    myres = 15;
-    __leave;
-    myres = 23;
-  } __finally {
-    return 0;
-  }
-  return 1;
-}
-// CHECK-LABEL: define i32 @__leave_with___finally_simple()
-// CHECK: store i32 15, i32* %myres
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-// CHECK: [[tryleave]]
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@__leave_with___finally_simple@@"(i8 0, i8* %[[fp]])
-
-// __finally block doesn't return, __finally.cont doesn't exist.
-int __leave_with___finally_noreturn() {
-  int myres = 0;
-  __try {
-    myres = 15;
-    __leave;
-    myres = 23;
-  } __finally {
-    abort();
-  }
-  return 1;
-}
-// CHECK-LABEL: define i32 @__leave_with___finally_noreturn()
-// CHECK: store i32 15, i32* %myres
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-// CHECK: [[tryleave]]
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@__leave_with___finally_noreturn@@"(i8 0, i8* %[[fp]])
-
-// The "normal" case.
-int __leave_with___finally() {
-  int myres = 0;
-  __try {
-    g();
-    __leave;
-    myres = 23;
-  } __finally {
-    return 0;
-  }
-  return 1;
-}
-// CHECK-LABEL: define i32 @__leave_with___finally()
-// CHECK: invoke void @g()
-// CHECK-NEXT:       to label %[[cont:.*]] unwind label %{{.*}}
-// For __finally, there needs to be an explicit __try.__leave, because
-// abnormal.termination.slot needs to be set there.
-// CHECK: [[cont]]
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-// CHECK: [[tryleave]]
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@__leave_with___finally@@"(i8 0, i8* %[[fp]])
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Mixed, nested cases.
-
-int nested___except___finally() {
-  int myres = 0;
-  __try {
-    __try {
-      g();
-    } __finally {
-      g();
-      __leave;  // Refers to the outer __try, not the __finally!
-      myres = 23;
-      return 0;
-    }
-
-    myres = 51;
-  } __except (1) {
-  }
-  return 1;
-}
-// CHECK-LABEL: define i32 @nested___except___finally()
-
-// CHECK-LABEL: invoke void @g()
-// CHECK-NEXT:       to label %[[g1_cont1:.*]] unwind label %[[g1_lpad:.*]]
-
-// CHECK: [[g1_cont1]]
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___except___finally@@"(i8 0, i8* %[[fp]])
-// CHECK-NEXT:       to label %[[fin_cont:.*]] unwind label %[[g2_lpad:.*]]
-
-// CHECK: [[fin_cont]]
-// CHECK: store i32 51, i32* %
-// CHECK-NEXT: br label %[[trycont:[^ ]*]]
-
-// CHECK: [[g1_lpad]]
-// CHECK-NEXT: cleanuppad
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___except___finally@@"(i8 1, i8* %[[fp]])
-// CHECK-NEXT:       to label %[[g1_resume:.*]] unwind label %[[cleanupend:[^ ]*]]
-// CHECK: cleanupret {{.*}} unwind label %[[g2_lpad]]
-
-// CHECK: [[g2_lpad]]
-// CHECK: catchpad [i8* null]
-// CHECK: catchret
-// CHECK: br label %[[trycont]]
-
-// CHECK: [[trycont]]
-// CHECK-NEXT: ret i32 1
-
-// CHECK: [[cleanupend]]
-// CHECK-NEXT: cleanupendpad {{.*}} unwind label %[[g2_lpad]]
-
-// CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___except___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
-// CHECK: call void @g()
-// CHECK: unreachable
-
-int nested___except___except() {
-  int myres = 0;
-  __try {
-    __try {
-      g();
-      myres = 16;
-    } __except (1) {
-      g();
-      __leave;  // Refers to the outer __try, not the __except we're in!
-      myres = 23;
-      return 0;
-    }
-
-    myres = 51;
-  } __except (1) {
-  }
-  return 1;
-}
-// The order of basic blocks in the below doesn't matter.
-// CHECK-LABEL: define i32 @nested___except___except()
-
-// CHECK-LABEL: invoke void @g()
-// CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
-
-// CHECK: [[g1_lpad]]
-// CHECK: catchpad [i8* null]
-// CHECK: catchret {{.*}} to label %[[except:[^ ]*]]
-// CHECK: [[except]]
-// CHECK: invoke void @g()
-// CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
-
-// CHECK: [[g2_lpad]]
-// CHECK: catchpad [i8* null]
-// CHECK: catchret
-// CHECK: br label %[[trycont4:[^ ]*]]
-
-// CHECK: [[trycont4]]
-// CHECK-NEXT: ret i32 1
-
-// CHECK: [[g2_cont]]
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-
-// CHECK: [[g1_cont]]
-// CHECK: store i32 16, i32* %myres
-// CHECK-NEXT: br label %[[trycont:[^ ]*]]
-
-// CHECK: [[trycont]]
-// CHECK-NEXT: store i32 51, i32* %myres
-// CHECK-NEXT: br label %[[tryleave]]
-
-// CHECK: [[tryleave]]
-// CHECK-NEXT: br label %[[trycont4]]
-
-int nested___finally___except() {
-  int myres = 0;
-  __try {
-    __try {
-      g();
-    } __except (1) {
-      g();
-      __leave;  // Refers to the outer __try, not the __except!
-      myres = 23;
-      return 0;
-    }
-
-    myres = 51;
-  } __finally {
-  }
-  return 1;
-}
-// The order of basic blocks in the below doesn't matter.
-// CHECK-LABEL: define i32 @nested___finally___except()
-
-// CHECK-LABEL: invoke void @g()
-// CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
-
-// CHECK: [[g1_lpad]]
-// CHECK: catchpad
-// CHECK: catchret
-// CHECK: invoke void @g()
-// CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
-
-// CHECK: [[g2_cont]]
-// CHECK: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: 23
-
-// CHECK: [[g1_cont]]
-// CHECK-NEXT: br label %[[trycont:[^ ]*]]
-
-// CHECK: [[trycont]]
-// CHECK: store i32 51, i32* %
-// CHECK-NEXT: br label %[[tryleave]]
-
-// CHECK: [[tryleave]]
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@nested___finally___except@@"(i8 0, i8* %[[fp]])
-// CHECK-NEXT: ret i32 1
-
-// CHECK: [[g2_lpad]]
-// CHECK: cleanuppad
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___finally___except@@"(i8 1, i8* %[[fp]])
-// CHECK: cleanupret {{.*}} unwind to caller
-
-// CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___finally___except@@"(i8 %abnormal_termination, i8* %frame_pointer)
-// CHECK: ret void
-
-int nested___finally___finally() {
-  int myres = 0;
-  __try {
-    __try {
-      g();
-      myres = 16;
-    } __finally {
-      g();
-      __leave;  // Refers to the outer __try, not the __finally we're in!
-      myres = 23;
-      return 0;
-    }
-
-    myres = 51;
-  } __finally {
-  }
-  return 1;
-}
-// The order of basic blocks in the below doesn't matter.
-// CHECK-LABEL: define i32 @nested___finally___finally()
-
-// CHECK: invoke void @g()
-// CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
-
-// CHECK: [[g1_cont]]
-// CHECK: store i32 16, i32* %[[myres:[^ ]*]],
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: invoke void @"\01?fin$1 at 0@nested___finally___finally@@"(i8 0, i8* %[[fp]])
-// CHECK-NEXT:       to label %[[finally_cont:.*]] unwind label %[[g2_lpad:.*]]
-
-// CHECK: [[finally_cont]]
-// CHECK: store i32 51, i32* %[[myres]]
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@nested___finally___finally@@"(i8 0, i8* %[[fp]])
-// CHECK-NEXT: ret i32 1
-
-// CHECK: [[g1_lpad]]
-// CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad []
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: invoke void @"\01?fin$1 at 0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
-// CHECK-NEXT:       to label %[[finally_cont2:.*]] unwind label %[[endcleanup:[^ ]*]]
-// CHECK: [[finally_cont2]]
-// CHECK: cleanupret %[[padtoken]] unwind label %[[g2_lpad]]
-
-// CHECK: [[endcleanup]]
-// CHECK-NEXT: cleanupendpad %[[padtoken]] unwind label %[[g2_lpad]]
-
-// CHECK: [[g2_lpad]]
-// CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad []
-// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
-// CHECK: cleanupret %[[padtoken]] unwind to caller
-
-// CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
-// CHECK: ret void
-
-// CHECK-LABEL: define internal void @"\01?fin$1 at 0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
-// CHECK: call void @g()
-// CHECK: unreachable

Modified: cfe/trunk/test/CodeGen/exceptions-seh-leave.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-leave.c?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-leave.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-leave.c Wed Oct  7 20:13:52 2015
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - | opt -instnamer -S | FileCheck %s
 
 void g(void);
 
@@ -157,18 +157,23 @@ int nested___except___finally() {
 // CHECK-NEXT: br label %[[trycont:[^ ]*]]
 
 // CHECK: [[g1_lpad]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: catch i8* null
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: cleanuppad
+// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
 // CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___except___finally@@"(i8 1, i8* %[[fp]])
-// CHECK-NEXT:       to label %[[g1_resume:.*]] unwind label %[[g2_lpad]]
+// CHECK-NEXT:       to label %[[g1_resume:.*]] unwind label %[[cleanupend:[^ ]*]]
+// CHECK: cleanupret {{.*}} unwind label %[[g2_lpad]]
 
 // CHECK: [[g2_lpad]]
+// CHECK: catchpad [i8* null]
+// CHECK: catchret
 // CHECK: br label %[[trycont]]
 
 // CHECK: [[trycont]]
 // CHECK-NEXT: ret i32 1
 
+// CHECK: [[cleanupend]]
+// CHECK-NEXT: cleanupendpad {{.*}} unwind label %[[g2_lpad]]
+
 // CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___except___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
 // CHECK: call void @g()
 // CHECK: unreachable
@@ -197,30 +202,29 @@ int nested___except___except() {
 // CHECK-LABEL: invoke void @g()
 // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
 
-// CHECK: [[g1_cont]]
-// CHECK: store i32 16, i32* %myres
-// CHECK-NEXT: br label %[[trycont:[^ ]*]]
-
 // CHECK: [[g1_lpad]]
-// CHECK:  br label %[[except:[^ ]*]]
-
+// CHECK: catchpad [i8* null]
+// CHECK: catchret {{.*}} to label %[[except:[^ ]*]]
 // CHECK: [[except]]
 // CHECK: invoke void @g()
 // CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
 
-// CHECK: [[g2_cont]]
-// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
-// CHECK-NOT: store i32 23
-
 // CHECK: [[g2_lpad]]
-// CHECK: br label %[[outerexcept:[^ ]*]]
-
-// CHECK: [[outerexcept]]
+// CHECK: catchpad [i8* null]
+// CHECK: catchret
 // CHECK: br label %[[trycont4:[^ ]*]]
 
 // CHECK: [[trycont4]]
 // CHECK-NEXT: ret i32 1
 
+// CHECK: [[g2_cont]]
+// CHECK-NEXT: br label %[[tryleave:[^ ]*]]
+// CHECK-NOT: store i32 23
+
+// CHECK: [[g1_cont]]
+// CHECK: store i32 16, i32* %myres
+// CHECK-NEXT: br label %[[trycont:[^ ]*]]
+
 // CHECK: [[trycont]]
 // CHECK-NEXT: store i32 51, i32* %myres
 // CHECK-NEXT: br label %[[tryleave]]
@@ -251,13 +255,9 @@ int nested___finally___except() {
 // CHECK-LABEL: invoke void @g()
 // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
 
-// CHECK: [[g1_cont]]
-// CHECK-NEXT: br label %[[trycont:[^ ]*]]
-
 // CHECK: [[g1_lpad]]
-// CHECK:  br label %[[except:[^ ]*]]
-
-// CHECK: [[except]]
+// CHECK: catchpad
+// CHECK: catchret
 // CHECK: invoke void @g()
 // CHECK-NEXT:       to label %[[g2_cont:.*]] unwind label %[[g2_lpad:.*]]
 
@@ -265,10 +265,8 @@ int nested___finally___except() {
 // CHECK: br label %[[tryleave:[^ ]*]]
 // CHECK-NOT: 23
 
-// CHECK: [[g2_lpad]]
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@nested___finally___except@@"(i8 1, i8* %[[fp]])
-// CHECK-NEXT: br label %[[ehresume:[^ ]*]]
+// CHECK: [[g1_cont]]
+// CHECK-NEXT: br label %[[trycont:[^ ]*]]
 
 // CHECK: [[trycont]]
 // CHECK: store i32 51, i32* %
@@ -279,8 +277,11 @@ int nested___finally___except() {
 // CHECK-NEXT: call void @"\01?fin$0 at 0@nested___finally___except@@"(i8 0, i8* %[[fp]])
 // CHECK-NEXT: ret i32 1
 
-// CHECK: [[ehresume]]
-// CHECK: resume
+// CHECK: [[g2_lpad]]
+// CHECK: cleanuppad
+// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___finally___except@@"(i8 1, i8* %[[fp]])
+// CHECK: cleanupret {{.*}} unwind to caller
 
 // CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___finally___except@@"(i8 %abnormal_termination, i8* %frame_pointer)
 // CHECK: ret void
@@ -306,7 +307,7 @@ int nested___finally___finally() {
 // The order of basic blocks in the below doesn't matter.
 // CHECK-LABEL: define i32 @nested___finally___finally()
 
-// CHECK-LABEL: invoke void @g()
+// CHECK: invoke void @g()
 // CHECK-NEXT:       to label %[[g1_cont:.*]] unwind label %[[g1_lpad:.*]]
 
 // CHECK: [[g1_cont]]
@@ -322,24 +323,21 @@ int nested___finally___finally() {
 // CHECK-NEXT: ret i32 1
 
 // CHECK: [[g1_lpad]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad []
+// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
 // CHECK-NEXT: invoke void @"\01?fin$1 at 0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
-// CHECK-NEXT:       to label %[[finally_cont2:.*]] unwind label %[[g2_lpad]]
-
-// CHECK: [[g2_lpad]]
-// CHECK-NEXT: landingpad
-// CHECK-NEXT: cleanup
-// CHECK: br label %[[ehcleanup:.*]]
-
+// CHECK-NEXT:       to label %[[finally_cont2:.*]] unwind label %[[endcleanup:[^ ]*]]
 // CHECK: [[finally_cont2]]
-// CHECK: br label %[[ehcleanup]]
+// CHECK: cleanupret %[[padtoken]] unwind label %[[g2_lpad]]
 
-// CHECK: [[ehcleanup]]
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT: call void @"\01?fin$0 at 0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
-// CHECK: resume
+// CHECK: [[endcleanup]]
+// CHECK-NEXT: cleanupendpad %[[padtoken]] unwind label %[[g2_lpad]]
+
+// CHECK: [[g2_lpad]]
+// CHECK-NEXT: %[[padtoken:[^ ]*]] = cleanuppad []
+// CHECK-NEXT: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
+// CHECK-NEXT: invoke void @"\01?fin$0 at 0@nested___finally___finally@@"(i8 1, i8* %[[fp]])
+// CHECK: cleanupret %[[padtoken]] unwind to caller
 
 // CHECK-LABEL: define internal void @"\01?fin$0 at 0@nested___finally___finally@@"(i8 %abnormal_termination, i8* %frame_pointer)
 // CHECK: ret void

Removed: cfe/trunk/test/CodeGen/exceptions-seh-new.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-new.c?rev=249646&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh-new.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh-new.c (removed)
@@ -1,289 +0,0 @@
-// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - \
-// RUN:         | FileCheck %s --check-prefix=CHECK --check-prefix=X64
-// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - \
-// RUN:         | FileCheck %s --check-prefix=CHECK --check-prefix=X86
-// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -fnew-ms-eh -emit-llvm -o - \
-// RUN:         | FileCheck %s --check-prefix=X86-GNU
-// RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -fnew-ms-eh -emit-llvm -o - \
-// RUN:         | FileCheck %s --check-prefix=X64-GNU
-
-void try_body(int numerator, int denominator, int *myres) {
-  *myres = numerator / denominator;
-}
-// CHECK-LABEL: define void @try_body(i32 %numerator, i32 %denominator, i32* %myres)
-// CHECK: sdiv i32
-// CHECK: store i32 %{{.*}}, i32*
-// CHECK: ret void
-
-int safe_div(int numerator, int denominator, int *res) {
-  int myres = 0;
-  int success = 1;
-  __try {
-    try_body(numerator, denominator, &myres);
-  } __except (1) {
-    success = -42;
-  }
-  *res = myres;
-  return success;
-}
-
-// CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
-// X64-SAME:      personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
-// X86-SAME:      personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
-// CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
-// CHECK:       to label %{{.*}} unwind label %[[catchpad:[^ ]*]]
-//
-// CHECK: [[catchpad]]
-// X64: %[[padtoken:[^ ]*]] = catchpad [i8* null]
-// X86: %[[padtoken:[^ ]*]] = catchpad [i8* bitcast (i32 ()* @"\01?filt$0 at 0@safe_div@@" to i8*)]
-// CHECK-NEXT:    to label %[[exceptret:[^ ]*]] unwind label
-//
-// CHECK: [[exceptret]]
-// CHECK: catchret %[[padtoken]] to label %[[except:[^ ]*]]
-//
-// CHECK: [[except]]
-// CHECK: store i32 -42, i32* %[[success:[^ ]*]]
-//
-// CHECK: %[[res:[^ ]*]] = load i32, i32* %[[success]]
-// CHECK: ret i32 %[[res]]
-
-// 32-bit SEH needs this filter to save the exception code.
-//
-// X86-LABEL: define internal i32 @"\01?filt$0 at 0@safe_div@@"()
-// X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)
-// X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[ebp]])
-// X86: call i8* @llvm.localrecover(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[fp]], i32 0)
-// X86: load i8*, i8**
-// X86: load i32*, i32**
-// X86: load i32, i32*
-// X86: store i32 %{{.*}}, i32*
-// X86: ret i32 1
-
-// Mingw uses msvcrt, so it can also use _except_handler3.
-// X86-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
-// X86-GNU-SAME:      personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
-// X64-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
-// X64-GNU-SAME:      personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
-
-void j(void);
-
-int filter_expr_capture(void) {
-  int r = 42;
-  __try {
-    j();
-  } __except(r = -1) {
-    r = 13;
-  }
-  return r;
-}
-
-// CHECK-LABEL: define i32 @filter_expr_capture()
-// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
-// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
-// X64: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]])
-// X86: call void (...) @llvm.localescape(i32* %[[r:[^ ,]*]], i32* %[[code:[^ ,]*]])
-// CHECK: store i32 42, i32* %[[r]]
-// CHECK: invoke void @j() #[[NOINLINE]]
-//
-// CHECK: catchpad [i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@filter_expr_capture@@" to i8*)]
-// CHECK: store i32 13, i32* %[[r]]
-//
-// CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]]
-// CHECK: ret i32 %[[rv]]
-
-// X64-LABEL: define internal i32 @"\01?filt$0 at 0@filter_expr_capture@@"(i8* %exception_pointers, i8* %frame_pointer)
-// X64: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %frame_pointer, i32 0)
-//
-// X86-LABEL: define internal i32 @"\01?filt$0 at 0@filter_expr_capture@@"()
-// X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)
-// X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[ebp]])
-// X86: call i8* @llvm.localrecover(i8* bitcast (i32 ()* @filter_expr_capture to i8*), i8* %[[fp]], i32 0)
-//
-// CHECK: store i32 -1, i32* %{{.*}}
-// CHECK: ret i32 -1
-
-int nested_try(void) {
-  int r = 42;
-  __try {
-    __try {
-      j();
-      r = 0;
-    } __except(_exception_code() == 123) {
-      r = 123;
-    }
-  } __except(_exception_code() == 456) {
-    r = 456;
-  }
-  return r;
-}
-// CHECK-LABEL: define i32 @nested_try()
-// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
-// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
-// CHECK: store i32 42, i32* %[[r:[^ ,]*]]
-// CHECK: invoke void @j() #[[NOINLINE]]
-// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[cpad_inner:[^ ]*]]
-//
-// CHECK: [[cpad_inner]]
-// CHECK: catchpad [i8* bitcast (i32 ({{.*}})* @"\01?filt$1 at 0@nested_try@@" to i8*)]
-// CHECK-NEXT: to label %[[exceptret_inner:[^ ]*]] unwind label %[[cpad_outer:[^ ]*]]
-//
-// CHECK: [[exceptret_inner]]
-// CHECK: catchret {{.*}} to label %[[except_inner:[^ ]*]]
-//
-// CHECK: [[except_inner]]
-// CHECK: store i32 123, i32* %[[r]]
-// CHECK: br label %[[inner_try_cont:[^ ]*]]
-//
-// CHECK: [[inner_try_cont]]
-// CHECK: br label %[[outer_try_cont:[^ ]*]]
-//
-// CHECK: [[cpad_outer]]
-// CHECK: catchpad [i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@nested_try@@" to i8*)]
-// CHECK-NEXT: to label %[[exceptret_outer:[^ ]*]] unwind label
-//
-// CHECK: [[exceptret_outer]]
-// CHECK: catchret {{.*}} to label %[[except_outer:[^ ]*]]
-//
-// CHECK: [[except_outer]]
-// CHECK: store i32 456, i32* %[[r]]
-// CHECK: br label %[[outer_try_cont]]
-//
-// CHECK: [[outer_try_cont]]
-// CHECK: %[[r_load:[^ ]*]] = load i32, i32* %[[r]]
-// CHECK: ret i32 %[[r_load]]
-//
-// CHECK: [[cont]]
-// CHECK: store i32 0, i32* %[[r]]
-// CHECK: br label %[[inner_try_cont]]
-//
-// CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@nested_try@@"({{.*}})
-// X86: call i8* @llvm.x86.seh.recoverfp({{.*}})
-// CHECK: load i32*, i32**
-// CHECK: load i32, i32*
-// CHECK: icmp eq i32 %{{.*}}, 456
-//
-// CHECK-LABEL: define internal i32 @"\01?filt$1 at 0@nested_try@@"({{.*}})
-// X86: call i8* @llvm.x86.seh.recoverfp({{.*}})
-// CHECK: load i32*, i32**
-// CHECK: load i32, i32*
-// CHECK: icmp eq i32 %{{.*}}, 123
-
-int basic_finally(int g) {
-  __try {
-    j();
-  } __finally {
-    ++g;
-  }
-  return g;
-}
-// CHECK-LABEL: define i32 @basic_finally(i32 %g)
-// X64-SAME: personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
-// X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
-// CHECK: %[[g_addr:[^ ]*]] = alloca i32, align 4
-// CHECK: call void (...) @llvm.localescape(i32* %[[g_addr]])
-// CHECK: store i32 %g, i32* %[[g_addr]]
-//
-// CHECK: invoke void @j()
-// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[cleanuppad:[^ ]*]]
-//
-// CHECK: [[cont]]
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 0, i8* %[[fp]])
-// CHECK: load i32, i32* %[[g_addr]], align 4
-// CHECK: ret i32
-//
-// CHECK: [[cleanuppad]]
-// CHECK: %[[padtoken:[^ ]*]] = cleanuppad []
-// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: invoke void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
-// CHECK:     to label %[[cleanupcont:[^ ]*]] unwind label %[[cleanupend:[^ ]*]]
-// CHECK: [[cleanupcont]]
-// CHECK: cleanupret %[[padtoken]] unwind to caller
-// CHECK: [[cleanupend]]
-// CHECK: cleanupendpad %[[padtoken]] unwind to caller
-
-// CHECK: define internal void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
-// CHECK:   call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)
-// CHECK:   load i32, i32* %{{.*}}, align 4
-// CHECK:   add nsw i32 %{{.*}}, 1
-// CHECK:   store i32 %{{.*}}, i32* %{{.*}}, align 4
-// CHECK:   ret void
-
-int returns_int(void);
-int except_return(void) {
-  __try {
-    return returns_int();
-  } __except(1) {
-    return 42;
-  }
-}
-// CHECK-LABEL: define i32 @except_return()
-// CHECK: %[[tmp:[^ ]*]] = invoke i32 @returns_int()
-// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[catchpad:[^ ]*]]
-//
-// CHECK: [[catchpad]]
-// CHECK: catchpad
-// CHECK: catchret
-// CHECK: store i32 42, i32* %[[rv:[^ ]*]]
-// CHECK: br label %[[retbb:[^ ]*]]
-//
-// CHECK: [[cont]]
-// CHECK: store i32 %[[tmp]], i32* %[[rv]]
-// CHECK: br label %[[retbb]]
-//
-// CHECK: [[retbb]]
-// CHECK: %[[r:[^ ]*]] = load i32, i32* %[[rv]]
-// CHECK: ret i32 %[[r]]
-
-
-// PR 24751: don't assert if a variable is used twice in a __finally block.
-// Also, make sure we don't do redundant work to capture/project it.
-void finally_capture_twice(int x) {
-  __try {
-  } __finally {
-    int y = x;
-    int z = x;
-  }
-}
-//
-// CHECK-LABEL: define void @finally_capture_twice(
-// CHECK:         [[X:%.*]] = alloca i32, align 4
-// CHECK:         call void (...) @llvm.localescape(i32* [[X]])
-// CHECK-NEXT:    store i32 {{.*}}, i32* [[X]], align 4
-// CHECK-NEXT:    [[LOCAL:%.*]] = call i8* @llvm.localaddress()
-// CHECK-NEXT:    call void [[FINALLY:@.*]](i8{{ zeroext | }}0, i8* [[LOCAL]])
-// CHECK:       define internal void [[FINALLY]](
-// CHECK:         [[LOCAL:%.*]] = call i8* @llvm.localrecover(
-// CHECK:         [[X:%.*]] = bitcast i8* [[LOCAL]] to i32*
-// CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
-// CHECK-NEXT:    store i8*
-// CHECK-NEXT:    store i8
-// CHECK-NEXT:    [[T0:%.*]] = load i32, i32* [[X]], align 4
-// CHECK-NEXT:    store i32 [[T0]], i32* [[Y]], align 4
-// CHECK-NEXT:    [[T0:%.*]] = load i32, i32* [[X]], align 4
-// CHECK-NEXT:    store i32 [[T0]], i32* [[Z]], align 4
-// CHECK-NEXT:    ret void
-
-int exception_code_in_except(void) {
-  __try {
-    try_body(0, 0, 0);
-  } __except(1) {
-    return _exception_code();
-  }
-}
-
-// CHECK-LABEL: define i32 @exception_code_in_except()
-// CHECK: %[[ret_slot:[^ ]*]] = alloca i32
-// CHECK: %[[code_slot:[^ ]*]] = alloca i32
-// CHECK: invoke void @try_body(i32 0, i32 0, i32* null)
-// CHECK: %[[pad:[^ ]*]] = catchpad
-// CHECK: catchret %[[pad]]
-// X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]])
-// X64: store i32 %[[code]], i32* %[[code_slot]]
-// CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]]
-// CHECK: store i32 %[[ret1]], i32* %[[ret_slot]]
-// CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]]
-// CHECK: ret i32 %[[ret2]]
-
-// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }

Modified: cfe/trunk/test/CodeGen/exceptions-seh.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh.c?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh.c Wed Oct  7 20:13:52 2015
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - \
 // RUN:         | FileCheck %s --check-prefix=CHECK --check-prefix=X64
-// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -fnew-ms-eh -emit-llvm -o - \
 // RUN:         | FileCheck %s --check-prefix=CHECK --check-prefix=X86
+// RUN: %clang_cc1 %s -triple i686-pc-windows-gnu -fms-extensions -fnew-ms-eh -emit-llvm -o - \
+// RUN:         | FileCheck %s --check-prefix=X86-GNU
+// RUN: %clang_cc1 %s -triple x86_64-pc-windows-gnu -fms-extensions -fnew-ms-eh -emit-llvm -o - \
+// RUN:         | FileCheck %s --check-prefix=X64-GNU
 
 void try_body(int numerator, int denominator, int *myres) {
   *myres = numerator / denominator;
@@ -23,36 +27,28 @@ int safe_div(int numerator, int denomina
   return success;
 }
 
-// X64-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
-// X64: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
-// X64:       to label %{{.*}} unwind label %[[lpad:[^ ]*]]
-//
-// X64: [[lpad]]
-// X64: landingpad { i8*, i32 }
-// X64-NEXT: catch i8* null
-// X64-NOT: br i1
-// X64: br label %[[except:[^ ]*]]
-// X64: [[except]]
-// X64: store i32 -42, i32* %[[success:[^ ]*]]
-//
-// X64: %[[res:[^ ]*]] = load i32, i32* %[[success]]
-// X64: ret i32 %[[res]]
-
-// X86-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res) {{.*}} personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
-// X86: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
-// X86:       to label %{{.*}} unwind label %[[lpad:[^ ]*]]
-//
-// X86: [[lpad]]
-// X86: landingpad { i8*, i32 }
-// X86-NEXT: catch i8* bitcast (i32 ()* @"\01?filt$0 at 0@safe_div@@" to i8*)
-// X86-NOT: br i1
-// X86: br label %[[except:[^ ]*]]
-// X86: [[except]]
-// X86: store i32 -42, i32* %[[success:[^ ]*]]
+// CHECK-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
+// X64-SAME:      personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+// X86-SAME:      personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
+// CHECK: invoke void @try_body(i32 %{{.*}}, i32 %{{.*}}, i32* %{{.*}}) #[[NOINLINE:[0-9]+]]
+// CHECK:       to label %{{.*}} unwind label %[[catchpad:[^ ]*]]
+//
+// CHECK: [[catchpad]]
+// X64: %[[padtoken:[^ ]*]] = catchpad [i8* null]
+// X86: %[[padtoken:[^ ]*]] = catchpad [i8* bitcast (i32 ()* @"\01?filt$0 at 0@safe_div@@" to i8*)]
+// CHECK-NEXT:    to label %[[exceptret:[^ ]*]] unwind label
+//
+// CHECK: [[exceptret]]
+// CHECK: catchret %[[padtoken]] to label %[[except:[^ ]*]]
 //
-// X86: %[[res:[^ ]*]] = load i32, i32* %[[success]]
-// X86: ret i32 %[[res]]
+// CHECK: [[except]]
+// CHECK: store i32 -42, i32* %[[success:[^ ]*]]
+//
+// CHECK: %[[res:[^ ]*]] = load i32, i32* %[[success]]
+// CHECK: ret i32 %[[res]]
 
+// 32-bit SEH needs this filter to save the exception code.
+//
 // X86-LABEL: define internal i32 @"\01?filt$0 at 0@safe_div@@"()
 // X86: %[[ebp:[^ ]*]] = call i8* @llvm.frameaddress(i32 1)
 // X86: %[[fp:[^ ]*]] = call i8* @llvm.x86.seh.recoverfp(i8* bitcast (i32 (i32, i32, i32*)* @safe_div to i8*), i8* %[[ebp]])
@@ -63,6 +59,12 @@ int safe_div(int numerator, int denomina
 // X86: store i32 %{{.*}}, i32*
 // X86: ret i32 1
 
+// Mingw uses msvcrt, so it can also use _except_handler3.
+// X86-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
+// X86-GNU-SAME:      personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
+// X64-GNU-LABEL: define i32 @safe_div(i32 %numerator, i32 %denominator, i32* %res)
+// X64-GNU-SAME:      personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
+
 void j(void);
 
 int filter_expr_capture(void) {
@@ -83,8 +85,7 @@ int filter_expr_capture(void) {
 // CHECK: store i32 42, i32* %[[r]]
 // CHECK: invoke void @j() #[[NOINLINE]]
 //
-// CHECK: landingpad
-// CHECK-NEXT: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@filter_expr_capture@@" to i8*)
+// CHECK: catchpad [i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@filter_expr_capture@@" to i8*)]
 // CHECK: store i32 13, i32* %[[r]]
 //
 // CHECK: %[[rv:[^ ]*]] = load i32, i32* %[[r]]
@@ -120,42 +121,41 @@ int nested_try(void) {
 // X86-SAME: personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
 // CHECK: store i32 42, i32* %[[r:[^ ,]*]]
 // CHECK: invoke void @j() #[[NOINLINE]]
-// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[cpad_inner:[^ ]*]]
 //
-// CHECK: [[cont]]
-// CHECK: store i32 0, i32* %[[r]]
+// CHECK: [[cpad_inner]]
+// CHECK: catchpad [i8* bitcast (i32 ({{.*}})* @"\01?filt$1 at 0@nested_try@@" to i8*)]
+// CHECK-NEXT: to label %[[exceptret_inner:[^ ]*]] unwind label %[[cpad_outer:[^ ]*]]
+//
+// CHECK: [[exceptret_inner]]
+// CHECK: catchret {{.*}} to label %[[except_inner:[^ ]*]]
+//
+// CHECK: [[except_inner]]
+// CHECK: store i32 123, i32* %[[r]]
 // CHECK: br label %[[inner_try_cont:[^ ]*]]
 //
-// CHECK: [[lpad]]
-// CHECK: landingpad { i8*, i32 }
-// CHECK: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$1 at 0@nested_try@@" to i8*)
-// CHECK: catch i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@nested_try@@" to i8*)
-// CHECK: store i8* %{{.*}}, i8** %[[ehptr_slot:[^ ]*]]
-// CHECK: store i32 %{{.*}}, i32* %[[sel_slot:[^ ]*]]
-//
-// CHECK: load i32, i32* %[[sel_slot]]
-// CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ({{.*}})* @"\01?filt$1 at 0@nested_try@@" to i8*))
-// CHECK: icmp eq i32
-// CHECK: br i1
-//
-// CHECK: load i32, i32* %[[sel_slot]]
-// CHECK: call i32 @llvm.eh.typeid.for(i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@nested_try@@" to i8*))
-// CHECK: icmp eq i32
-// CHECK: br i1
+// CHECK: [[inner_try_cont]]
+// CHECK: br label %[[outer_try_cont:[^ ]*]]
+//
+// CHECK: [[cpad_outer]]
+// CHECK: catchpad [i8* bitcast (i32 ({{.*}})* @"\01?filt$0 at 0@nested_try@@" to i8*)]
+// CHECK-NEXT: to label %[[exceptret_outer:[^ ]*]] unwind label
 //
+// CHECK: [[exceptret_outer]]
+// CHECK: catchret {{.*}} to label %[[except_outer:[^ ]*]]
+//
+// CHECK: [[except_outer]]
 // CHECK: store i32 456, i32* %[[r]]
-// CHECK: br label %[[outer_try_cont:[^ ]*]]
+// CHECK: br label %[[outer_try_cont]]
 //
 // CHECK: [[outer_try_cont]]
 // CHECK: %[[r_load:[^ ]*]] = load i32, i32* %[[r]]
 // CHECK: ret i32 %[[r_load]]
 //
-// CHECK: store i32 123, i32* %[[r]]
+// CHECK: [[cont]]
+// CHECK: store i32 0, i32* %[[r]]
 // CHECK: br label %[[inner_try_cont]]
 //
-// CHECK: [[inner_try_cont]]
-// CHECK: br label %[[outer_try_cont]]
-//
 // CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@nested_try@@"({{.*}})
 // X86: call i8* @llvm.x86.seh.recoverfp({{.*}})
 // CHECK: load i32*, i32**
@@ -184,7 +184,7 @@ int basic_finally(int g) {
 // CHECK: store i32 %g, i32* %[[g_addr]]
 //
 // CHECK: invoke void @j()
-// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[cleanuppad:[^ ]*]]
 //
 // CHECK: [[cont]]
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
@@ -192,12 +192,15 @@ int basic_finally(int g) {
 // CHECK: load i32, i32* %[[g_addr]], align 4
 // CHECK: ret i32
 //
-// CHECK: [[lpad]]
-// CHECK: landingpad { i8*, i32 }
-// CHECK-NEXT: cleanup
+// CHECK: [[cleanuppad]]
+// CHECK: %[[padtoken:[^ ]*]] = cleanuppad []
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
-// CHECK: resume
+// CHECK: invoke void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} 1, i8* %[[fp]])
+// CHECK:     to label %[[cleanupcont:[^ ]*]] unwind label %[[cleanupend:[^ ]*]]
+// CHECK: [[cleanupcont]]
+// CHECK: cleanupret %[[padtoken]] unwind to caller
+// CHECK: [[cleanupend]]
+// CHECK: cleanupendpad %[[padtoken]] unwind to caller
 
 // CHECK: define internal void @"\01?fin$0 at 0@basic_finally@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
 // CHECK:   call i8* @llvm.localrecover(i8* bitcast (i32 (i32)* @basic_finally to i8*), i8* %frame_pointer, i32 0)
@@ -216,14 +219,16 @@ int except_return(void) {
 }
 // CHECK-LABEL: define i32 @except_return()
 // CHECK: %[[tmp:[^ ]*]] = invoke i32 @returns_int()
-// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
+// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[catchpad:[^ ]*]]
 //
-// CHECK: [[cont]]
-// CHECK: store i32 %[[tmp]], i32* %[[rv:[^ ]*]]
+// CHECK: [[catchpad]]
+// CHECK: catchpad
+// CHECK: catchret
+// CHECK: store i32 42, i32* %[[rv:[^ ]*]]
 // CHECK: br label %[[retbb:[^ ]*]]
 //
-// CHECK: [[lpad]]
-// CHECK: store i32 42, i32* %[[rv]]
+// CHECK: [[cont]]
+// CHECK: store i32 %[[tmp]], i32* %[[rv]]
 // CHECK: br label %[[retbb]]
 //
 // CHECK: [[retbb]]
@@ -260,4 +265,25 @@ void finally_capture_twice(int x) {
 // CHECK-NEXT:    store i32 [[T0]], i32* [[Z]], align 4
 // CHECK-NEXT:    ret void
 
+int exception_code_in_except(void) {
+  __try {
+    try_body(0, 0, 0);
+  } __except(1) {
+    return _exception_code();
+  }
+}
+
+// CHECK-LABEL: define i32 @exception_code_in_except()
+// CHECK: %[[ret_slot:[^ ]*]] = alloca i32
+// CHECK: %[[code_slot:[^ ]*]] = alloca i32
+// CHECK: invoke void @try_body(i32 0, i32 0, i32* null)
+// CHECK: %[[pad:[^ ]*]] = catchpad
+// CHECK: catchret %[[pad]]
+// X64: %[[code:[^ ]*]] = call i32 @llvm.eh.exceptioncode(token %[[pad]])
+// X64: store i32 %[[code]], i32* %[[code_slot]]
+// CHECK: %[[ret1:[^ ]*]] = load i32, i32* %[[code_slot]]
+// CHECK: store i32 %[[ret1]], i32* %[[ret_slot]]
+// CHECK: %[[ret2:[^ ]*]] = load i32, i32* %[[ret_slot]]
+// CHECK: ret i32 %[[ret2]]
+
 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }

Modified: cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp Wed Oct  7 20:13:52 2015
@@ -32,13 +32,9 @@ extern "C" void use_cxx() {
 // CXXEH: ret void
 //
 // CXXEH: [[lpad]]
-// CXXEH: landingpad { i8*, i32 }
-// CXXEH-NEXT: cleanup
+// CXXEH: cleanuppad
 // CXXEH: call void @"\01??1HasCleanup@@QEAA at XZ"(%struct.HasCleanup* %{{.*}})
-// CXXEH: br label %[[resume:[^ ]*]]
-//
-// CXXEH: [[resume]]
-// CXXEH: resume
+// CXXEH: cleanupret
 
 // NOCXX-LABEL: define void @use_cxx()
 // NOCXX-NOT: invoke
@@ -64,17 +60,18 @@ extern "C" void use_seh() {
 // CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]]
 // CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]
 //
-// CHECK: [[cont]]
-// CHECK: br label %[[ret:[^ ]*]]
-//
 // CHECK: [[lpad]]
-// CHECK: landingpad { i8*, i32 }
-// CHECK-NEXT: catch i8*
+// CHECK-NEXT: catchpad
+// CHECK: catchret {{.*}} label %[[except:[^ ]*]]
 //
-// CHECK: br label %[[ret]]
+// CHECK: [[except]]
+// CHECK: br label %[[ret:[^ ]*]]
 //
 // CHECK: [[ret]]
 // CHECK: ret void
+//
+// CHECK: [[cont]]
+// CHECK: br label %[[ret]]
 
 void use_seh_in_lambda() {
   ([]() {
@@ -89,7 +86,7 @@ void use_seh_in_lambda() {
 
 // CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
 // CXXEH-SAME:  personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
-// CXXEH: landingpad { i8*, i32 }
+// CXXEH: cleanuppad
 
 // NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()
 // NOCXX-NOT: invoke
@@ -98,7 +95,7 @@ void use_seh_in_lambda() {
 // CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ at QEBAXXZ"(%class.anon* %this)
 // CXXEH-SAME:  personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
 // CHECK: invoke void @might_throw() #[[NOINLINE]]
-// CHECK: landingpad { i8*, i32 }
+// CHECK: catchpad
 
 static int my_unique_global;
 
@@ -122,8 +119,7 @@ void use_inline() {
 // CHECK-SAME:  personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
 // CHECK: invoke void @might_throw()
 //
-// CHECK: landingpad { i8*, i32 }
-// CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0 at 0@use_seh_in_inline_func@@" to i8*)
+// CHECK: catchpad [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0 at 0@use_seh_in_inline_func@@" to i8*)]
 //
 // CHECK: invoke void @might_throw()
 //
@@ -131,10 +127,9 @@ void use_inline() {
 // CHECK: call void @"\01?fin$0 at 0@use_seh_in_inline_func@@"(i8 0, i8* %[[fp]])
 // CHECK: ret void
 //
-// CHECK: landingpad { i8*, i32 }
-// CHECK-NEXT: cleanup
+// CHECK: cleanuppad
 // CHECK: %[[fp:[^ ]*]] = call i8* @llvm.localaddress()
-// CHECK: call void @"\01?fin$0 at 0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]])
+// CHECK: invoke void @"\01?fin$0 at 0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]])
 
 // CHECK-LABEL: define internal i32 @"\01?filt$0 at 0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func)
 // CHECK: icmp eq i32 %{{.*}}, 424242

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-arg-order.cpp Wed Oct  7 20:13:52 2015
@@ -52,8 +52,9 @@ void call_foo() {
 // X86: ret void
 //
 //   lpad2:
+// X86: cleanuppad []
 // X86: call x86_thiscallcc void @"\01??1A@@QAE at XZ"(%struct.A* %[[arg2]])
-// X86: br label
+// X86: cleanupret
 //
 //   ehcleanup:
 // X86: call x86_thiscallcc void @"\01??1A@@QAE at XZ"(%struct.A* %[[arg3]])
@@ -67,8 +68,9 @@ void call_foo() {
 // X64: ret void
 //
 //   lpad2:
+// X64: cleanuppad []
 // X64: call void @"\01??1A@@QEAA at XZ"(%struct.A* %[[arg2]])
-// X64: br label
+// X64: cleanupret
 //
 //   ehcleanup:
 // X64: call void @"\01??1A@@QEAA at XZ"(%struct.A* %[[arg3]])

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Wed Oct  7 20:13:52 2015
@@ -148,7 +148,7 @@ C::C() { foo(); }
 // Verify that we don't bother with a vbtable lookup when adjusting the this
 // pointer to call a base destructor from a constructor while unwinding.
 // WIN32-LABEL: define {{.*}} @"\01??0C at crash_on_partial_destroy@@QAE at XZ"{{.*}} {
-// WIN32:      landingpad
+// WIN32:      cleanuppad
 //
 //        We shouldn't do any vbptr loads, just constant GEPs.
 // WIN32-NOT:  load
@@ -185,7 +185,6 @@ void f() {
 // WIN32: call x86_thiscallcc void @"\01??1C at dont_call_terminate@@QAE at XZ"({{.*}})
 //
 // WIN32: [[lpad]]
-// WIN32-NEXT: landingpad
-// WIN32-NEXT: cleanup
+// WIN32-NEXT: cleanuppad
 // WIN32: call x86_thiscallcc void @"\01??1C at dont_call_terminate@@QAE at XZ"({{.*}})
 }

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp Wed Oct  7 20:13:52 2015
@@ -6,10 +6,9 @@ void never_throws() noexcept(true) {
   may_throw();
 }
 
-// CHECK-LABEL: define void @"\01?never_throws@@YAXXZ"
+// CHECK-LABEL: define void @"\01?never_throws@@YAXXZ"()
+// CHECK-SAME:          personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
 // CHECK:      invoke void @"\01?may_throw@@YAXXZ"()
-
-// CHECK:      landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)
-// MSVC2013:   call void @"\01?terminate@@YAXXZ"()
-// MSVC2015:   call void @__std_terminate()
+// MSVC2013:      terminatepad [void ()* @"\01?terminate@@YAXXZ"]
+// MSVC2015:      terminatepad [void ()* @__std_terminate]
 // CHECK-NEXT: unreachable

Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp Wed Oct  7 20:13:52 2015
@@ -39,15 +39,11 @@ extern inline S &f() {
 // CHECK-NEXT:  ret %struct.S* @"\01?s@?1??f@@YAAAUS@@XZ at 4U2@A"
 
 // CHECK:     [[lpad:.*]]:
-// CHECK-NEXT:  landingpad { i8*, i32 }
-// CHECK-NEXT:    cleanup
+// CHECK-NEXT: cleanuppad []
 // CHECK:       %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ at 51"
 // CHECK-NEXT:  %[[mask:.*]] = and i32 %[[guard]], -2
 // CHECK-NEXT:  store i32 %[[mask]], i32* @"\01??__J?1??f@@YAAAUS@@XZ at 51"
-// CHECK-NEXT:  br label %[[eh_resume:.*]]
-//
-// CHECK:     [[eh_resume]]:
-// CHECK:       resume { i8*, i32 }
+// CHECK-NEXT:  cleanupret {{.*}} unwind to caller
   return s;
 }
 
@@ -79,11 +75,9 @@ extern inline S &g() {
 // CHECK-NEXT:  ret %struct.S* @"\01?s@?1??g@@YAAAUS@@XZ at 4U2@A"
 //
 // CHECK:     [[lpad]]:
+// CHECK-NEXT: cleanuppad []
 // CHECK:       call void @_Init_thread_abort(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ")
-// CHECK-NEXT:  br label %[[eh_resume:.*]]
-//
-// CHECK:     [[eh_resume]]:
-// CHECK:       resume { i8*, i32 }
+// CHECK-NEXT:  cleanupret {{.*}} unwind to caller
   return s;
 }
 

Modified: cfe/trunk/test/OpenMP/parallel_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_codegen.cpp?rev=249647&r1=249646&r2=249647&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_codegen.cpp Wed Oct  7 20:13:52 2015
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -o - | FileCheck %s
 // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
 // RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -g -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK-DEBUG %s
 // expected-no-diagnostics




More information about the cfe-commits mailing list