[IR] Reformulate LLVM's EH funclet IR

While we have successfully implemented a funclet-oriented EH scheme on
top of LLVM IR, our scheme has some notable deficiencies:
- catchendpad and cleanupendpad are necessary in the current design
  but they are difficult to explain to others, even to seasoned LLVM
  experts.
- catchendpad and cleanupendpad are optimization barriers.  They cannot
  be split and force all potentially throwing call-sites to be invokes.
  This has a noticable effect on the quality of our code generation.
- catchpad, while similar in some aspects to invoke, is fairly awkward.
  It is unsplittable, starts a funclet, and has control flow to other
  funclets.
- The nesting relationship between funclets is currently a property of
  control flow edges.  Because of this, we are forced to carefully
  analyze the flow graph to see if there might potentially exist illegal
  nesting among funclets.  While we have logic to clone funclets when
  they are illegally nested, it would be nicer if we had a
  representation which forbade them upfront.

Let's clean this up a bit by doing the following:
- Instead, make catchpad more like cleanuppad and landingpad: no control
  flow, just a bunch of simple operands;  catchpad would be splittable.
- Introduce catchswitch, a control flow instruction designed to model
  the constraints of funclet oriented EH.
- Make funclet scoping explicit by having funclet instructions consume
  the token produced by the funclet which contains them.
- Remove catchendpad and cleanupendpad.  Their presence can be inferred
  implicitly using coloring information.

N.B.  The state numbering code for the CLR has been updated but the
veracity of it's output cannot be spoken for.  An expert should take a
look to make sure the results are reasonable.

Reviewers: rnk, JosephTremoulet, andrew.w.kaylor

Differential Revision: http://reviews.llvm.org/D15139

llvm-svn: 255422
diff --git a/llvm/test/CodeGen/WinEH/wineh-cloning.ll b/llvm/test/CodeGen/WinEH/wineh-cloning.ll
index 7d6529d..66a9132 100644
--- a/llvm/test/CodeGen/WinEH/wineh-cloning.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-cloning.ll
@@ -1,6 +1,7 @@
-; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
+; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
 
 declare i32 @__CxxFrameHandler3(...)
+declare i32 @__C_specific_handler(...)
 
 declare void @f()
 declare i32 @g()
@@ -13,16 +14,16 @@
   ; %x def colors: {entry} subset of use colors; must spill
   %x = call i32 @g()
   invoke void @f()
-    to label %noreturn unwind label %catch
+    to label %noreturn unwind label %catch.switch
+catch.switch:
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchpad []
-    to label %noreturn unwind label %endcatch
+  catchpad within %cs []
+  br label %noreturn
 noreturn:
   ; %x use colors: {entry, cleanup}
   call void @h(i32 %x)
   unreachable
-endcatch:
-  catchendpad unwind to caller
 }
 ; Need two copies of the call to @h, one under entry and one under catch.
 ; Currently we generate a load for each, though we shouldn't need one
@@ -32,11 +33,11 @@
 ; CHECK:   %x = call i32 @g()
 ; CHECK:   invoke void @f()
 ; CHECK:     to label %[[EntryCopy:[^ ]+]] unwind label %catch
+; CHECK: catch.switch:
+; CHECK:   %cs = catchswitch within none [label %catch] unwind to caller
 ; CHECK: catch:
-; CHECK:   catchpad []
-; CHECK-NEXT: to label %[[CatchCopy:[^ ]+]] unwind
-; CHECK: [[CatchCopy]]:
-; CHECK:   call void @h(i32 %x)
+; CHECK:   catchpad within %cs []
+; CHECK-NEXT: call void @h(i32 %x)
 ; CHECK: [[EntryCopy]]:
 ; CHECK:   call void @h(i32 %x)
 
@@ -46,7 +47,7 @@
   invoke void @f()
     to label %exit unwind label %cleanup
 cleanup:
-  cleanuppad []
+  cleanuppad within none []
   br label %exit
 exit:
   call void @f()
@@ -60,7 +61,7 @@
 ; CHECK:   invoke void @f()
 ; CHECK:     to label %[[exit:[^ ]+]] unwind label %cleanup
 ; CHECK: cleanup:
-; CHECK:   cleanuppad []
+; CHECK:   cleanuppad within none []
 ; CHECK:   call void @f()
 ; CHECK-NEXT: unreachable
 ; CHECK: [[exit]]:
@@ -71,16 +72,17 @@
 define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   invoke void @f()
-    to label %invoke.cont unwind label %catch
+    to label %invoke.cont unwind label %catch.switch
 invoke.cont:
   invoke void @f()
     to label %exit unwind label %cleanup
+catch.switch:
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchpad [] to label %shared unwind label %endcatch
-endcatch:
-  catchendpad unwind to caller
+  catchpad within %cs []
+  br label %shared
 cleanup:
-  cleanuppad []
+  cleanuppad within none []
   br label %shared
 shared:
   call void @f()
@@ -95,13 +97,11 @@
 ; CHECK:   invoke void @f()
 ; CHECK:     to label %[[exit:[^ ]+]] unwind
 ; CHECK: catch:
-; CHECK:   catchpad []
-; CHECK-NEXT: to label %[[shared:[^ ]+]] unwind
-; CHECK: cleanup:
-; CHECK:   cleanuppad []
-; CHECK:   call void @f()
+; CHECK:   catchpad within %cs []
+; CHECK-NEXT: call void @f()
 ; CHECK-NEXT: unreachable
-; CHECK: [[shared]]:
+; CHECK: cleanup:
+; CHECK:   cleanuppad within none []
 ; CHECK:   call void @f()
 ; CHECK-NEXT: unreachable
 ; CHECK: [[exit]]:
@@ -111,12 +111,12 @@
 define void @test4() personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   invoke void @f()
-    to label %shared unwind label %catch
+    to label %shared unwind label %catch.switch
+catch.switch:
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchpad []
-    to label %shared unwind label %endcatch
-endcatch:
-  catchendpad unwind to caller
+  catchpad within %cs []
+  br label %shared
 shared:
   %x = call i32 @g()
   %i = call i32 @g()
@@ -145,10 +145,9 @@
 ; from %shared to %exit.
 ; CHECK-LABEL: define void @test4(
 ; CHECK:  entry:
-; CHECK:    to label %[[shared_E:[^ ]+]] unwind label %catch
+; CHECK:    to label %[[shared_E:[^ ]+]] unwind label %catch.switch
 ; CHECK:  catch:
-; CHECK:    to label %[[shared_C:[^ ]+]] unwind label %endcatch
-; CHECK:  [[shared_C]]:
+; CHECK:    catchpad within %cs []
 ; CHECK:    [[x_C:%[^ ]+]] = call i32 @g()
 ; CHECK:    [[i_C:%[^ ]+]] = call i32 @g()
 ; CHECK:    [[zt_C:%[^ ]+]] = icmp eq i32 [[i_C]], 0
@@ -159,7 +158,7 @@
 ; CHECK:    [[zt_E:%[^ ]+]] = icmp eq i32 [[i_E]], 0
 ; CHECK:    br i1 [[zt_E]], label %[[exit_E:[^ ]+]], label %[[loop_E:[^ ]+]]
 ; CHECK:  [[loop_C]]:
-; CHECK:    [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %[[shared_C]] ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ]
+; CHECK:    [[iloop_C:%[^ ]+]] = phi i32 [ [[i_C]], %catch ], [ [[idec_C:%[^ ]+]], %[[looptail_C:[^ ]+]] ]
 ; CHECK:    [[b_C:%[^ ]+]] = call i1 @b()
 ; CHECK:    br i1 [[b_C]], label %[[left_C:[^ ]+]], label %[[right_C:[^ ]+]]
 ; CHECK:  [[loop_E]]:
@@ -194,27 +193,25 @@
 ; CHECK:    unreachable
 
 
-define void @test5() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test5() personality i32 (...)* @__C_specific_handler {
 entry:
   invoke void @f()
     to label %exit unwind label %outer
 outer:
-  %o = cleanuppad []
+  %o = cleanuppad within none []
   %x = call i32 @g()
   invoke void @f()
-    to label %outer.ret unwind label %inner
+    to label %outer.ret unwind label %catch.switch
+catch.switch:
+  %cs = catchswitch within %o [label %inner] unwind to caller
 inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.endcatch
-inner.catch:
-  catchret %i to label %outer.post-inner
-inner.endcatch:
-  catchendpad unwind to caller
+  %i = catchpad within %cs []
+  catchret from %i to label %outer.post-inner
 outer.post-inner:
   call void @h(i32 %x)
   br label %outer.ret
 outer.ret:
-  cleanupret %o unwind to caller
+  cleanupret from %o unwind to caller
 exit:
   ret void
 }
@@ -225,17 +222,16 @@
 ; CHECK:      outer:
 ; CHECK:        %x = call i32 @g()
 ; CHECK-NEXT:   invoke void @f()
-; CHECK-NEXT:     to label %outer.ret unwind label %inner
+; CHECK-NEXT:     to label %outer.ret unwind label %catch.switch
 ; CHECK:      inner:
-; CHECK:          to label %inner.catch unwind label %inner.endcatch
-; CHECK:      inner.catch:
-; CHECK-NEXT:   catchret %i to label %outer.post-inner
+; CHECK-NEXT:   %i = catchpad within %cs []
+; CHECK-NEXT:   catchret from %i to label %outer.post-inner
 ; CHECK:      outer.post-inner:
 ; CHECK-NEXT:   call void @h(i32 %x)
 ; CHECK-NEXT:   br label %outer.ret
 
 
-define void @test6() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test6() personality i32 (...)* @__C_specific_handler {
 entry:
   invoke void @f()
     to label %invoke.cont unwind label %left
@@ -243,15 +239,13 @@
   invoke void @f()
     to label %exit unwind label %right
 left:
-  cleanuppad []
+  cleanuppad within none []
   br label %shared
 right:
-  catchpad []
-    to label %right.catch unwind label %right.end
+  %cs = catchswitch within none [label %right.catch] unwind to caller
 right.catch:
+  catchpad within %cs []
   br label %shared
-right.end:
-  catchendpad unwind to caller
 shared:
   %x = call i32 @g()
   invoke void @f()
@@ -259,52 +253,32 @@
 shared.cont:
   unreachable
 inner:
-  %i = cleanuppad []
+  %i = cleanuppad within none []
   call void @h(i32 %x)
-  cleanupret %i unwind label %right.end
+  cleanupret from %i unwind to caller
 exit:
   ret void
 }
-; %inner is a cleanup which appears both as a child of
-; %left and as a child of %right.  Since statically we
-; need each funclet to have a single parent, we need to
-; clone the entire %inner funclet so we can have one
-; copy under each parent.  The cleanupret in %inner
-; unwinds to the catchendpad for %right, so the copy
-; of %inner under %right should include it; the copy
-; of %inner under %left should instead have an
-; `unreachable` inserted there, but the copy under
-; %left still needs to be created because it's possible
-; the dynamic path enters %left, then enters %inner,
-; then calls @h, and that the call to @h doesn't return.
 ; CHECK-LABEL: define void @test6(
 ; CHECK:     left:
 ; CHECK:       %x.for.left = call i32 @g()
 ; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:       catchpad
-; CHECK:           to label %right.catch unwind label %right.end
+; CHECK:           to label %shared.cont.for.left unwind label %inner
 ; CHECK:     right.catch:
+; CHECK:       catchpad
 ; CHECK:       %x = call i32 @g()
-; CHECK:           to label %shared.cont unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
+; CHECK:           to label %shared.cont unwind label %inner
 ; CHECK:     shared.cont:
 ; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
+; CHECK:     shared.cont.for.left:
 ; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_R:\%.+]] = cleanuppad []
-; CHECK:       call void @h(i32 %x)
-; CHECK:       cleanupret [[I_R]] unwind label %right.end
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_L:\%.+]] = cleanuppad []
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
+; CHECK:     inner:
+; CHECK:       %i = cleanuppad within none []
+; CHECK:       call void @h(i32 %x1.wineh.reload)
+; CHECK:       cleanupret from %i unwind to caller
 
 
-define void @test7() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test9() personality i32 (...)* @__C_specific_handler {
 entry:
   invoke void @f()
     to label %invoke.cont unwind label %left
@@ -312,176 +286,32 @@
   invoke void @f()
     to label %unreachable unwind label %right
 left:
-  cleanuppad []
-  invoke void @f() to label %unreachable unwind label %inner
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  invoke void @f() to label %unreachable unwind label %inner
-right.end:
-  catchendpad unwind to caller
-inner:
-  %i = cleanuppad []
-  %x = call i32 @g()
-  call void @h(i32 %x)
-  cleanupret %i unwind label %right.end
-unreachable:
-  unreachable
-}
-; Another case of a two-parent child (like @test6), this time
-; with the join at the entry itself instead of following a
-; non-pad join.
-; CHECK-LABEL: define void @test7(
-; CHECK:     invoke.cont:
-; CHECK:           to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
-; CHECK:     left:
-; CHECK:           to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:           to label %unreachable unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_R:\%.+]] = cleanuppad []
-; CHECK:       [[X_R:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X_R]])
-; CHECK:       cleanupret [[I_R]] unwind label %right.end
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_L:\%.+]] = cleanuppad []
-; CHECK:       [[X_L:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X_L]])
-; CHECK:       unreachable
-; CHECK:     unreachable:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_ENTRY]]:
-; CHECK:       unreachable
-
-
-define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %unreachable unwind label %right
-left:
-  cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-inner:
-  cleanuppad []
-  invoke void @f()
-    to label %unreachable unwind label %inner.child
-inner.child:
-  cleanuppad []
-  %x = call i32 @g()
-  call void @h(i32 %x)
-  unreachable
-unreachable:
-  unreachable
-}
-; %inner is a two-parent child which itself has a child; need
-; to make two copies of both the %inner and %inner.child.
-; CHECK-LABEL: define void @test8(
-; CHECK:     invoke.cont:
-; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
-; CHECK:     left:
-; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:               to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:               to label %[[UNREACHABLE_INNER_RIGHT:.+]] unwind label %[[INNER_CHILD_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:               to label %[[UNREACHABLE_INNER_LEFT:.+]] unwind label %[[INNER_CHILD_LEFT:.+]]
-; CHECK:     [[INNER_CHILD_RIGHT]]:
-; CHECK:       [[TMP:\%.+]] = cleanuppad []
-; CHECK:       [[X:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X]])
-; CHECK:       unreachable
-; CHECK:     [[INNER_CHILD_LEFT]]:
-; CHECK:       [[TMP:\%.+]] = cleanuppad []
-; CHECK:       [[X:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X]])
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_INNER_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_INNER_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_ENTRY]]:
-; CHECK:       unreachable
-
-
-define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %unreachable unwind label %right
-left:
-  cleanuppad []
+  cleanuppad within none []
   call void @h(i32 1)
   invoke void @f()
     to label %unreachable unwind label %right
 right:
-  cleanuppad []
+  cleanuppad within none []
   call void @h(i32 2)
   invoke void @f()
     to label %unreachable unwind label %left
 unreachable:
   unreachable
 }
-; This is an irreducible loop with two funclets that enter each other;
-; need to make two copies of each funclet (one a child of root, the
-; other a child of the opposite funclet), but also make sure not to
-; clone self-descendants (if we tried to do that we'd need to make an
-; infinite number of them).  Presumably if optimizations ever generated
-; such a thing it would mean that one of the two cleanups was originally
-; the parent of the other, but that we'd somehow lost track in the CFG
-; of which was which along the way; generating each possibility lets
-; whichever case was correct execute correctly.
+; This is an irreducible loop with two funclets that enter each other.
 ; CHECK-LABEL: define void @test9(
 ; CHECK:     entry:
 ; CHECK:               to label %invoke.cont unwind label %[[LEFT:.+]]
 ; CHECK:     invoke.cont:
 ; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]]
-; CHECK:     [[LEFT_FROM_RIGHT:.+]]:
-; CHECK:       call void @h(i32 1)
-; CHECK:       call void @f()
-; CHECK:       unreachable
 ; CHECK:     [[LEFT]]:
 ; CHECK:       call void @h(i32 1)
 ; CHECK:       invoke void @f()
-; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT_FROM_LEFT:.+]]
+; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT]]
 ; CHECK:     [[RIGHT]]:
 ; CHECK:       call void @h(i32 2)
 ; CHECK:       invoke void @f()
-; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT_FROM_RIGHT]]
-; CHECK:     [[RIGHT_FROM_LEFT]]:
-; CHECK:       call void @h(i32 2)
-; CHECK:       call void @f()
-; CHECK:       unreachable
+; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT]]
 ; CHECK:     [[UNREACHABLE_RIGHT]]:
 ; CHECK:       unreachable
 ; CHECK:     [[UNREACHABLE_LEFT]]:
@@ -495,16 +325,16 @@
   invoke void @f()
     to label %unreachable unwind label %inner
 inner:
-  %cleanup = cleanuppad []
+  %cleanup = cleanuppad within none []
   ; make sure we don't overlook this cleanupret and try to process
   ; successor %outer as a child of inner.
-  cleanupret %cleanup unwind label %outer
+  cleanupret from %cleanup unwind label %outer
 outer:
-  %catch = catchpad [] to label %catch.body unwind label %endpad
+  %cs = catchswitch within none [label %catch.body] unwind to caller
+
 catch.body:
-  catchret %catch to label %exit
-endpad:
-  catchendpad unwind to caller
+  %catch = catchpad within %cs []
+  catchret from %catch to label %exit
 exit:
   ret void
 unreachable:
@@ -515,46 +345,40 @@
 ; CHECK-NEXT:   invoke
 ; CHECK-NEXT:     to label %unreachable unwind label %inner
 ; CHECK:      inner:
-; CHECK-NEXT:   %cleanup = cleanuppad
-; CHECK-NEXT:   cleanupret %cleanup unwind label %outer
+; CHECK-NEXT:   %cleanup = cleanuppad within none []
+; CHECK-NEXT:   cleanupret from %cleanup unwind label %outer
 ; CHECK:      outer:
-; CHECK-NEXT:   %catch = catchpad []
-; CHECK-NEXT:	      to label %catch.body unwind label %endpad
+; CHECK-NEXT:   %cs = catchswitch within none [label %catch.body] unwind to caller
 ; CHECK:      catch.body:
-; CHECK-NEXT:   catchret %catch to label %exit
-; CHECK:      endpad:
-; CHECK-NEXT:   catchendpad unwind to caller
+; CHECK-NEXT:   %catch = catchpad within %cs []
+; CHECK-NEXT:   catchret from %catch to label %exit
 ; CHECK:      exit:
 ; CHECK-NEXT:   ret void
 
-define void @test11() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test11() personality i32 (...)* @__C_specific_handler {
 entry:
   invoke void @f()
     to label %exit unwind label %cleanup.outer
 cleanup.outer:
-  %outer = cleanuppad []
+  %outer = cleanuppad within none []
   invoke void @f()
     to label %outer.cont unwind label %cleanup.inner
 outer.cont:
   br label %merge
 cleanup.inner:
-  %inner = cleanuppad []
+  %inner = cleanuppad within %outer []
   br label %merge
 merge:
-  invoke void @f()
-    to label %unreachable unwind label %merge.end
-unreachable:
+  call void @f()
   unreachable
-merge.end:
-  cleanupendpad %outer unwind to caller
 exit:
   ret void
 }
 ; merge.end will get cloned for outer and inner, but is implausible
-; from inner, so the invoke @f() in inner's copy of merge should be
+; from inner, so the call @f() in inner's copy of merge should be
 ; rewritten to call @f()
 ; CHECK-LABEL: define void @test11()
-; CHECK:      %inner = cleanuppad []
+; CHECK:      %inner = cleanuppad within %outer []
 ; CHECK-NEXT: call void @f()
 ; CHECK-NEXT: unreachable
 
@@ -566,10 +390,10 @@
   invoke void @f()
     to label %exit unwind label %right
 left:
-  cleanuppad []
+  cleanuppad within none []
   br label %join
 right:
-  cleanuppad []
+  cleanuppad within none []
   br label %join
 join:
   ; This call will get cloned; make sure we can handle cloning
@@ -587,68 +411,10 @@
   ret void
 
 unreachable:
-  cleanuppad []
+  cleanuppad within none []
   unreachable
 }
 
-define void @test14() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %catch1.pad
-catch1.pad:
-  %catch1 = catchpad [i32 1]
-    to label %catch1.body unwind label %catch2.pad
-catch1.body:
-  invoke void @h(i32 1)
-    to label %catch1.body2 unwind label %catch.end
-catch1.body2:
-  invoke void @f()
-    to label %catch1.ret unwind label %cleanup1.pad
-cleanup1.pad:
-  %cleanup1 = cleanuppad []
-  call void @f()
-  cleanupret %cleanup1 unwind label %catch.end
-catch1.ret:
-  catchret %catch1 to label %exit
-catch2.pad:
-  %catch2 = catchpad [i32 2]
-    to label %catch2.body unwind label %catch.end
-catch2.body:
-  invoke void @h(i32 2)
-    to label %catch2.body2 unwind label %catch.end
-catch2.body2:
-  invoke void @f()
-    to label %catch2.ret unwind label %cleanup2.pad
-cleanup2.pad:
-  %cleanup2 = cleanuppad []
-  call void @f()
-  cleanupret %cleanup2 unwind label %catch.end
-catch2.ret:
-  catchret %catch2 to label %exit
-catch.end:
-  catchendpad unwind to caller
-exit:
-  ret void
-}
-; Make sure we don't clone the catchendpad even though the
-; cleanupendpads targeting it would naively imply that it
-; should get their respective parent colors (catch1 and catch2),
-; as well as its properly getting the root function color.  The
-; references from the invokes ensure that if we did make clones
-; for each catch, they'd be reachable, as those invokes would get
-; rewritten
-; CHECK-LABEL: define void @test14()
-; CHECK-NOT:  catchendpad
-; CHECK:      invoke void @h(i32 1)
-; CHECK-NEXT:   unwind label %catch.end
-; CHECK-NOT:  catchendpad
-; CHECK:      invoke void @h(i32 2)
-; CHECK-NEXT:   unwind label %catch.end
-; CHECK-NOT:   catchendpad
-; CHECK:     catch.end:
-; CHECK-NEXT:  catchendpad
-; CHECK-NOT:   catchendpad
-
 ;; Debug info (from test12)
 
 ; Make sure the DISubprogram doesn't get cloned
diff --git a/llvm/test/CodeGen/WinEH/wineh-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-demotion.ll
index 96f33b0..bd23913 100644
--- a/llvm/test/CodeGen/WinEH/wineh-demotion.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-demotion.ll
@@ -1,4 +1,4 @@
-; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
+; RUN: opt -mtriple=x86_64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
 
 declare i32 @__CxxFrameHandler3(...)
 
@@ -36,17 +36,15 @@
   ; CHECK: merge:
   ; CHECK-NOT: = phi
   %phi = phi i32 [ %x, %left ], [ %y, %right ]
-  %cp = catchpad [] to label %catch unwind label %catchend
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:
+  %cp = catchpad within %cs1 []
   ; CHECK: catch:
   ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
   ; CHECK-NEXT: call void @h(i32 [[Reload]])
   call void @h(i32 %phi)
-  catchret %cp to label %exit
-
-catchend:
-  catchendpad unwind to caller
+  catchret from %cp to label %exit
 
 exit:
   ret void
@@ -75,44 +73,42 @@
 merge.inner:
   ; CHECK: merge.inner:
   ; CHECK-NOT: = phi
-  ; CHECK: catchpad []
+  ; CHECK: catchswitch within none
   %x = phi i32 [ 1, %left ], [ 2, %right ]
-  %cpinner = catchpad [] to label %catch.inner unwind label %catchend.inner
+  %cs1 = catchswitch within none [label %catch.inner] unwind label %merge.outer
 
 catch.inner:
+  %cpinner = catchpad within %cs1 []
   ; Need just one store here because only %y is affected
   ; CHECK: catch.inner:
   %z = call i32 @g()
   ; CHECK:   store i32 %z
   ; CHECK-NEXT: invoke void @f
   invoke void @f()
-          to label %catchret.inner unwind label %catchend.inner
+          to label %catchret.inner unwind label %merge.outer
 
 catchret.inner:
-  catchret %cpinner to label %exit
-catchend.inner:
-  ; CHECK-NOT: = phi
-  %y = phi i32 [ %x, %merge.inner ], [ %z, %catch.inner ]
-  catchendpad unwind label %merge.outer
+  catchret from %cpinner to label %exit
 
 merge.outer:
+  %y = phi i32 [ %x, %merge.inner ], [ %z, %catch.inner ]
   ; CHECK: merge.outer:
-  ; CHECK: [[CatchPad:%[^ ]+]] = catchpad []
-  %cpouter = catchpad [] to label %catch.outer unwind label %catchend.outer
-
-catchend.outer:
-  catchendpad unwind to caller
+  ; CHECK-NOT: = phi
+  ; CHECK: catchswitch within none
+  %cs2 = catchswitch within none [label %catch.outer] unwind to caller
 
 catch.outer:
+  %cpouter = catchpad within %cs2 []
+  ; CHECK: catch.outer:
+  ; CHECK: [[CatchPad:%[^ ]+]] = catchpad within %cs2 []
   ; Need to load x and y from two different slots since they're both live
   ; and can have different values (if we came from catch.inner)
-  ; CHECK: catch.outer:
   ; CHECK-DAG: load i32, i32* [[Slot1]]
   ; CHECK-DAG: load i32, i32* [[Slot2]]
-  ; CHECK: catchret [[CatchPad]] to label
+  ; CHECK: catchret from [[CatchPad]] to label
   call void @h(i32 %x)
   call void @h(i32 %y)
-  catchret %cpouter to label %exit
+  catchret from %cpouter to label %exit
 
 exit:
   ret void
@@ -145,13 +141,12 @@
           to label %join unwind label %catchpad.inner
 catchpad.inner:
    ; CHECK: catchpad.inner:
-   ; CHECK-NEXT: catchpad []
+   ; CHECK-NEXT: catchswitch within none
    %phi.inner = phi i32 [ %l, %left ], [ %r, %right ]
-   %cp1 = catchpad [] to label %catch.inner unwind label %catchend.inner
+   %cs1 = catchswitch within none [label %catch.inner] unwind label %catchpad.outer
 catch.inner:
-   catchret %cp1 to label %join
-catchend.inner:
-   catchendpad unwind label  %catchpad.outer
+   %cp1 = catchpad within %cs1 []
+   catchret from %cp1 to label %join
 join:
   ; CHECK: join:
   ; CHECK-NOT: store
@@ -160,19 +155,19 @@
    %j = call i32 @g()
    invoke void @f()
            to label %exit unwind label %catchpad.outer
+
 catchpad.outer:
    ; CHECK: catchpad.outer:
-   ; CHECK-NEXT: catchpad []
-   %phi.outer = phi i32 [ %phi.inner, %catchend.inner ], [ %j, %join ]
-   %cp2 = catchpad [] to label %catch.outer unwind label %catchend.outer
+   ; CHECK-NEXT: catchswitch within none
+   %phi.outer = phi i32 [ %phi.inner, %catchpad.inner ], [ %j, %join ]
+   %cs2 = catchswitch within none [label %catch.outer] unwind to caller
 catch.outer:
    ; CHECK: catch.outer:
    ; CHECK:   [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
    ; CHECK:   call void @h(i32 [[Reload]])
+   %cp2 = catchpad within %cs2 []
    call void @h(i32 %phi.outer)
-   catchret %cp2 to label %exit
-catchend.outer:
-   catchendpad unwind to caller
+   catchret from %cp2 to label %exit
 exit:
    ret void
 }
@@ -198,10 +193,10 @@
 cleanup:
   ; cleanup phi can be loaded at cleanup entry
   ; CHECK: cleanup:
-  ; CHECK-NEXT: cleanuppad []
+  ; CHECK-NEXT: cleanuppad within none []
   ; CHECK: [[CleanupReload:%[^ ]+]] = load i32, i32* [[CleanupSlot]]
   %phi.cleanup = phi i32 [ 1, %entry ], [ 2, %invoke.cont ]
-  %cp = cleanuppad []
+  %cp = cleanuppad within none []
   %b = call i1 @i()
   br i1 %b, label %left, label %right
 
@@ -222,7 +217,7 @@
   ; CHECK:      merge:
   ; CHECK-NEXT:   store i32 [[CleanupReload]], i32* [[CatchSlot:%[^ ]+]]
   ; CHECK-NEXT:   cleanupret
-  cleanupret %cp unwind label %catchpad
+  cleanupret from %cp unwind label %catchswitch
 
 invoke.cont2:
   ; need store for %phi.catch
@@ -230,23 +225,22 @@
   ; CHECK-NEXT:   store i32 3, i32* [[CatchSlot]]
   ; CHECK-NEXT:   invoke void @f
   invoke void @f()
-          to label %exit unwind label %catchpad
+          to label %exit unwind label %catchswitch
 
-catchpad:
-  ; CHECK: catchpad:
-  ; CHECK-NEXT: catchpad []
+catchswitch:
+  ; CHECK: catchswitch:
+  ; CHECK-NEXT: catchswitch within none
   %phi.catch = phi i32 [ %phi.cleanup, %merge ], [ 3, %invoke.cont2 ]
-  %cp2 = catchpad [] to label %catch unwind label %catchend
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:
   ; CHECK: catch:
+  ; CHECK:   catchpad within %cs1
   ; CHECK:   [[CatchReload:%[^ ]+]] = load i32, i32* [[CatchSlot]]
   ; CHECK:   call void @h(i32 [[CatchReload]]
+  %cp2 = catchpad within %cs1 []
   call void @h(i32 %phi.catch)
-  catchret %cp2 to label %exit
-
-catchend:
-  catchendpad unwind to caller
+  catchret from %cp2 to label %exit
 
 exit:
   ret void
@@ -262,17 +256,17 @@
   %x = invoke i32 @g()
           to label %loop unwind label %to_caller
 to_caller:
-  %cp1 = cleanuppad []
-  cleanupret %cp1 unwind to caller
+  %cp1 = cleanuppad within none []
+  cleanupret from %cp1 unwind to caller
 loop:
   invoke void @f()
           to label %loop unwind label %cleanup
 cleanup:
   ; CHECK: cleanup:
   ; CHECK:   call void @h(i32 %x)
-  %cp2 = cleanuppad []
+  %cp2 = cleanuppad within none []
   call void @h(i32 %x)
-  cleanupret %cp2 unwind to caller
+  cleanupret from %cp2 unwind to caller
 }
 
 ; CHECK-LABEL: @test7(
@@ -294,18 +288,21 @@
 catchpad:
   ; %x phi should be eliminated
   ; CHECK: catchpad:
-  ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad []
+  ; CHECK-NEXT: catchswitch within none
   %x = phi i32 [ 1, %entry ], [ 2, %invoke.cont ]
-  %cp = catchpad [] to label %catch unwind label %catchend
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 catch:
+  ; CHECK: catch:
+  ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad within %cs1 []
+  %cp = catchpad within %cs1 []
   %b = call i1 @i()
   br i1 %b, label %left, label %right
 left:
   ; Edge from %left to %join needs to be split so that
   ; the load of %x can be inserted *after* the catchret
   ; CHECK: left:
-  ; CHECK-NEXT: catchret %[[CatchPad]] to label %[[SplitLeft:[^ ]+]]
-  catchret %cp to label %join
+  ; CHECK-NEXT: catchret from %[[CatchPad]] to label %[[SplitLeft:[^ ]+]]
+  catchret from %cp to label %join
   ; CHECK: [[SplitLeft]]:
   ; CHECK:   [[LoadX:%[^ ]+]] = load i32, i32* [[SlotX]]
   ; CHECK:   br label %join
@@ -314,11 +311,9 @@
   ; the load of %y can be inserted *after* the catchret
   ; CHECK: right:
   ; CHECK:   %y = call i32 @g()
-  ; CHECK:   catchret %[[CatchPad]] to label %join
+  ; CHECK:   catchret from %[[CatchPad]] to label %join
   %y = call i32 @g()
-  catchret %cp to label %join
-catchend:
-  catchendpad unwind to caller
+  catchret from %cp to label %join
 join:
   ; CHECK: join:
   ; CHECK:   %phi = phi i32 [ [[LoadX]], %[[SplitLeft]] ], [ %y, %right ]
@@ -340,20 +335,20 @@
   ret void
 
 cleanup1:
-  ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad []
+  ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad within none []
   ; CHECK-NEXT: call void @f()
-  ; CHECK-NEXT: cleanupret [[CleanupPad1]]
-  %cp0 = cleanuppad []
+  ; CHECK-NEXT: cleanupret from [[CleanupPad1]]
+  %cp0 = cleanuppad within none []
   br label %cleanupexit
 
 cleanup2:
-  ; CHECK: cleanuppad []
+  ; CHECK: cleanuppad within none []
   ; CHECK-NEXT: call void @f()
   ; CHECK-NEXT: unreachable
-  %cp1 = cleanuppad []
+  %cp1 = cleanuppad within none []
   br label %cleanupexit
 
 cleanupexit:
   call void @f()
-  cleanupret %cp0 unwind label %cleanup2
+  cleanupret from %cp0 unwind label %cleanup2
 }
diff --git a/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll b/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll
index acdeb79..3658792 100644
--- a/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll
@@ -15,13 +15,12 @@
   invoke void (...) @f(i32 1)
      to label %exit unwind label %catchpad
 catchpad:
-  %catch = catchpad [i32 1] to label %do_catch unwind label %catchend
+  %cs1 = catchswitch within none [label %do_catch] unwind to caller
 do_catch:
+  %catch = catchpad within %cs1 [i32 1]
   %exn = call i8* @llvm.eh.exceptionpointer.p0i8(token %catch)
   call void (...) @f(i8* %exn)
-  catchret %catch to label %exit
-catchend:
-  catchendpad unwind to caller
+  catchret from %catch to label %exit
 exit:
   ret void
 }
@@ -31,13 +30,12 @@
   invoke void (...) @f(i32 1)
      to label %exit unwind label %catchpad
 catchpad:
-  %catch = catchpad [i32 1] to label %do_catch unwind label %catchend
+  %cs1 = catchswitch within none [label %do_catch] unwind to caller
 do_catch:
+  %catch = catchpad within %cs1 [i32 1]
   %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch)
   call void (...) @f(i8 addrspace(1)* %exn)
-  catchret %catch to label %exit
-catchend:
-  catchendpad unwind to caller
+  catchret from %catch to label %exit
 exit:
   ret void
 }
diff --git a/llvm/test/CodeGen/WinEH/wineh-multi-parent-cloning.ll b/llvm/test/CodeGen/WinEH/wineh-multi-parent-cloning.ll
deleted file mode 100644
index 1e9342d..0000000
--- a/llvm/test/CodeGen/WinEH/wineh-multi-parent-cloning.ll
+++ /dev/null
@@ -1,1548 +0,0 @@
-; RUN: opt -mtriple=x86_x64-pc-windows-msvc -S -winehprepare  < %s | FileCheck %s
-
-declare i32 @__CxxFrameHandler3(...)
-
-declare void @f()
-declare i32 @g()
-declare void @h(i32)
-declare i1 @b()
-
-define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  %i = cleanuppad []
-  call void @h(i32 %x)
-  cleanupret %i unwind label %right.end
-exit:
-  ret void
-}
-; %inner is a cleanup which appears both as a child of
-; %left and as a child of %right.  Since statically we
-; need each funclet to have a single parent, we need to
-; clone the entire %inner funclet so we can have one
-; copy under each parent.  The cleanupret in %inner
-; unwinds to the catchendpad for %right, so the copy
-; of %inner under %right should include it; the copy
-; of %inner under %left should instead have an
-; `unreachable` inserted there, but the copy under
-; %left still needs to be created because it's possible
-; the dynamic path enters %left, then enters %inner,
-; then calls @h, and that the call to @h doesn't return.
-; CHECK-LABEL: define void @test1(
-; CHECK:     left:
-; CHECK:       cleanuppad
-; CHECK:       %x.for.left = call i32 @g()
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:       %x = call i32 @g()
-; CHECK:           to label %shared.cont unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     shared.cont:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_R:\%.+]] = cleanuppad []
-; CHECK:       call void @h(i32 %x)
-; CHECK:       cleanupret [[I_R]] unwind label %right.end
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_L:\%.+]] = cleanuppad []
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-
-
-define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %right.end
-exit:
-  ret void
-}
-; In this case left and right are both parents of inner.  This differs from
-; @test1 in that inner is a catchpad rather than a cleanuppad, which makes
-; inner.end a block that gets cloned so that left and right each contain a
-; copy (catchendpad blocks are considered to be part of the parent funclet
-; of the associated catchpad). The catchendpad in %inner.end unwinds to
-; %right.end (which belongs to the entry funclet).
-; CHECK-LABEL: define void @test2(
-; CHECK:     left:
-; CHECK:       cleanuppad
-; CHECK:       %x.for.left = call i32 @g()
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %[[RIGHT_END:.+]]
-; CHECK:     right.catch:
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind label %[[RIGHT_END]]
-
-define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  %l = cleanuppad []
-  br label %shared
-left.end:
-  cleanupendpad %l unwind label %right
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; In this case, %left and %right are siblings with %entry as the parent of both,
-; while %left and %right are both parents of %inner.  The catchendpad in
-; %inner.end unwinds to %left.end.  When %inner is cloned a copy of %inner.end
-; will be made for both %left and %right, but because %left.end is a cleanup pad
-; and %right is a catch pad the unwind edge from the copy of %inner.end for
-; %right must be removed.
-; CHECK-LABEL: define void @test3(
-; CHECK:     left:
-; CHECK:       %l = cleanuppad []
-; CHECK:       %x.for.left = call i32 @g()
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[LEFT_END:left.end.*]]:
-; CHECK:       cleanupendpad %l unwind label %right
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %[[RIGHT_END:.+]]
-; CHECK:     right.catch:
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-
-
-define void @test4() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  catchpad []
-    to label %left.catch unwind label %left.end
-left.catch:
-  br label %shared
-left.end:
-  catchendpad unwind label %right
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This is a variation of @test3 in which both %left and %right are catch pads.
-; In this case, %left and %right are siblings with %entry as the parent of both,
-; while %left and %right are both parents of %inner.  The catchendpad in
-; %inner.end unwinds to %left.end.  When %inner is cloned a copy of %inner.end
-; will be made for both %left and %right, but because the catchpad in %right
-; does not unwind to %left.end the unwind edge from the copy of %inner.end for
-; %right must be removed.
-; CHECK-LABEL: define void @test4(
-; CHECK:     left:
-; CHECK:       catchpad []
-; CHECK:           to label %left.catch unwind label %[[LEFT_END:.+]]
-; CHECK:     left.catch:
-; CHECK:       %x.for.left = call i32 @g()
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind label %right
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %[[RIGHT_END:.+]]
-; CHECK:     right.catch:
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-
-
-define void @test5() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  catchpad []
-    to label %left.catch unwind label %left.end
-left.catch:
-  br label %shared
-left.end:
-  catchendpad unwind label %right
-right:
-  %r = cleanuppad []
-  br label %shared
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; Like @test3, %left and %right are siblings with %entry as the parent of both,
-; while %left and %right are both parents of %inner.  This case makes %left a
-; catch and %right a cleanup so that %inner unwinds to %left.end, which is a
-; block in %entry.  The %inner funclet is cloned for %left and %right, but the
-; copy of %inner.end for %right must have its unwind edge removed because the
-; catchendpad at %left.end is not compatible with %right.
-; CHECK-LABEL: define void @test5(
-; CHECK:     left:
-; CHECK:       catchpad []
-; CHECK:           to label %left.catch unwind label %[[LEFT_END:.+]]
-; CHECK:     left.catch:
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind label %right
-; CHECK:     right:
-; CHECK:       %r = cleanuppad []
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-
-define void @test6() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  catchpad []
-    to label %left.catch unwind label %left.end
-left.catch:
-  br label %shared
-left.end:
-  catchendpad unwind label %middle
-middle:
-  %m = catchpad []
-    to label %middle.catch unwind label %middle.end
-middle.catch:
-  catchret %m to label %exit
-middle.end:
-  catchendpad unwind label %right
-right:
-  %r = cleanuppad []
-  br label %shared
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This is like @test5 but it inserts another sibling between %left and %right.
-; In this case %left, %middle and %right are all siblings, while %left and
-; %right are both parents of %inner.  This checks the proper handling of the
-; catchendpad in %inner.end (which will be cloned so that %left and %right both
-; have copies) unwinding to a catchendpad that unwinds to a sibling.
-; CHECK-LABEL: define void @test6(
-; CHECK:     left:
-; CHECK:       catchpad []
-; CHECK:           to label %left.catch unwind label %[[LEFT_END:.+]]
-; CHECK:     left.catch:
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind label %middle
-; CHECK:     middle:
-; CHECK:       catchpad []
-; CHECK:         to label %middle.catch unwind label %middle.end
-; CHECK:     middle.catch:
-; CHECK:       catchret %m to label %exit
-; CHECK:     middle.end:
-; CHECK:       catchendpad unwind label %right
-; CHECK:     right:
-; CHECK:       %r = cleanuppad []
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-
-
-define void @test7() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  catchpad []
-    to label %left.catch unwind label %left.end
-left.catch:
-  br label %shared
-left.end:
-  catchendpad unwind label %right
-right:
-  %r = cleanuppad []
-  br label %shared
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %inner.sibling
-inner.sibling:
-  %is = cleanuppad []
-  call void @h(i32 0)
-  cleanupret %is unwind label %left.end
-exit:
-  ret void
-}
-; This is like @test5 but instead of unwinding to %left.end, the catchendpad
-; in %inner.end unwinds to a sibling cleanup pad. Both %inner (along with its
-; associated blocks) and %inner.sibling must be cloned for %left and %right.
-; The clones of %inner will be identical, but the copy of %inner.sibling for
-; %right must end with an unreachable instruction, because it cannot unwind to
-; %left.end.
-; CHECK-LABEL: define void @test7(
-; CHECK:     left:
-; CHECK:       catchpad []
-; CHECK:           to label %left.catch unwind label %[[LEFT_END:.+]]
-; CHECK:     left.catch:
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind label %[[RIGHT:.+]]
-; CHECK:     [[RIGHT]]:
-; CHECK:       [[R:\%.+]] = cleanuppad []
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind label %[[INNER_SIBLING_RIGHT:.+]]
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[INNER_SIBLING_LEFT:.+]]
-; CHECK:     [[INNER_SIBLING_RIGHT]]
-; CHECK:       [[IS_R:\%.+]] = cleanuppad []
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_SIBLING_LEFT]]
-; CHECK:       [[IS_L:\%.+]] = cleanuppad []
-; CHECK:       call void @h(i32 0)
-; CHECK:       cleanupret [[IS_L]] unwind label %[[LEFT_END]]
-
-
-define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %unreachable unwind label %right
-left:
-  cleanuppad []
-  invoke void @f() to label %unreachable unwind label %inner
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  invoke void @f() to label %unreachable unwind label %inner
-right.end:
-  catchendpad unwind to caller
-inner:
-  %i = cleanuppad []
-  %x = call i32 @g()
-  call void @h(i32 %x)
-  cleanupret %i unwind label %right.end
-unreachable:
-  unreachable
-}
-; Another case of a two-parent child (like @test1), this time
-; with the join at the entry itself instead of following a
-; non-pad join.
-; CHECK-LABEL: define void @test8(
-; CHECK:     invoke.cont:
-; CHECK:           to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
-; CHECK:     left:
-; CHECK:           to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:           to label %unreachable unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_R:\%.+]] = cleanuppad []
-; CHECK:       [[X_R:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X_R]])
-; CHECK:       cleanupret [[I_R]] unwind label %right.end
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_L:\%.+]] = cleanuppad []
-; CHECK:       [[X_L:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X_L]])
-; CHECK:       unreachable
-; CHECK:     unreachable:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_ENTRY]]:
-; CHECK:       unreachable
-
-
-define void @test9() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %unreachable unwind label %right
-left:
-  cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-inner:
-  cleanuppad []
-  invoke void @f()
-    to label %unreachable unwind label %inner.child
-inner.child:
-  cleanuppad []
-  %x = call i32 @g()
-  call void @h(i32 %x)
-  unreachable
-unreachable:
-  unreachable
-}
-; %inner is a two-parent child which itself has a child; need
-; to make two copies of both the %inner and %inner.child.
-; CHECK-LABEL: define void @test9(
-; CHECK:     invoke.cont:
-; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right
-; CHECK:     left:
-; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:               to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:               to label %[[UNREACHABLE_INNER_RIGHT:.+]] unwind label %[[INNER_CHILD_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:               to label %[[UNREACHABLE_INNER_LEFT:.+]] unwind label %[[INNER_CHILD_LEFT:.+]]
-; CHECK:     [[INNER_CHILD_RIGHT]]:
-; CHECK:       [[TMP:\%.+]] = cleanuppad []
-; CHECK:       [[X:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X]])
-; CHECK:       unreachable
-; CHECK:     [[INNER_CHILD_LEFT]]:
-; CHECK:       [[TMP:\%.+]] = cleanuppad []
-; CHECK:       [[X:\%.+]] = call i32 @g()
-; CHECK:       call void @h(i32 [[X]])
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_INNER_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_INNER_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_ENTRY]]:
-; CHECK:       unreachable
-
-
-define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %unreachable unwind label %right
-left:
-  cleanuppad []
-  call void @h(i32 1)
-  invoke void @f()
-    to label %unreachable unwind label %right
-right:
-  cleanuppad []
-  call void @h(i32 2)
-  invoke void @f()
-    to label %unreachable unwind label %left
-unreachable:
-  unreachable
-}
-; This is an irreducible loop with two funclets that enter each other;
-; need to make two copies of each funclet (one a child of root, the
-; other a child of the opposite funclet), but also make sure not to
-; clone self-descendants (if we tried to do that we'd need to make an
-; infinite number of them).  Presumably if optimizations ever generated
-; such a thing it would mean that one of the two cleanups was originally
-; the parent of the other, but that we'd somehow lost track in the CFG
-; of which was which along the way; generating each possibility lets
-; whichever case was correct execute correctly.
-; CHECK-LABEL: define void @test10(
-; CHECK:     entry:
-; CHECK:               to label %invoke.cont unwind label %[[LEFT:.+]]
-; CHECK:     invoke.cont:
-; CHECK:               to label %[[UNREACHABLE_ENTRY:.+]] unwind label %[[RIGHT:.+]]
-; CHECK:     [[LEFT_FROM_RIGHT:.+]]:
-; CHECK:       call void @h(i32 1)
-; CHECK:       call void @f()
-; CHECK:       unreachable
-; CHECK:     [[LEFT]]:
-; CHECK:       call void @h(i32 1)
-; CHECK:       invoke void @f()
-; CHECK:               to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[RIGHT_FROM_LEFT:.+]]
-; CHECK:     [[RIGHT]]:
-; CHECK:       call void @h(i32 2)
-; CHECK:       invoke void @f()
-; CHECK:               to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[LEFT_FROM_RIGHT]]
-; CHECK:     [[RIGHT_FROM_LEFT]]:
-; CHECK:       call void @h(i32 2)
-; CHECK:       call void @f()
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[UNREACHABLE_ENTRY]]:
-; CHECK:       unreachable
-
-
-define void @test11() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  catchpad []
-    to label %left.catch unwind label %left.sibling
-left.catch:
-  br label %shared
-left.sibling:
-  %ls = catchpad []
-    to label %left.sibling.catch unwind label %left.end
-left.sibling.catch:
-  catchret %ls to label %exit
-left.end:
-  catchendpad unwind label %right
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This is a variation of @test4 in which the shared child funclet unwinds to a
-; catchend pad that is the unwind destination of %left.sibling rather than %left
-; but is still a valid destination for %inner as reach from %left.
-; When %inner is cloned a copy of %inner.end will be made for both %left and
-; %right, but because the catchpad in %right does not unwind to %left.end the
-; unwind edge from the copy of %inner.end for %right must be removed.
-; CHECK-LABEL: define void @test11(
-; CHECK:     left:
-; CHECK:       catchpad []
-; CHECK:           to label %left.catch unwind label %left.sibling
-; CHECK:     left.catch:
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     left.sibling:
-; CHECK:       catchpad []
-; CHECK:           to label %left.sibling.catch unwind label %[[LEFT_END:.+]]
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind label %right
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %[[RIGHT_END:.+]]
-; CHECK:     right.catch:
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-
-
-define void @test12() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  catchpad []
-    to label %left.catch unwind label %right
-left.catch:
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  %x = call i32 @g()
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 %x)
-  unreachable
-inner.end:
-  catchendpad unwind label %right.end
-exit:
-  ret void
-}
-; In this case %left and %right are both parents of %inner, so %inner must be
-; cloned but the catchendpad unwind target in %inner.end is valid for both
-; parents, so the unwind edge should not be removed in either case.
-; CHECK-LABEL: define void @test12(
-; CHECK:     left:
-; CHECK:       catchpad []
-; CHECK:           to label %left.catch unwind label %right
-; CHECK:     left.catch:
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:           to label %right.catch unwind label %[[RIGHT_END:.+]]
-; CHECK:     right.catch:
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 %x)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 %x.for.left)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind label %[[RIGHT_END]]
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[RIGHT_END]]
-
-define void @test13() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  %l = catchpad []
-    to label %left.cont unwind label %left.end
-left.cont:
-  invoke void @f()
-    to label %left.ret unwind label %inner
-left.ret:
-  catchret %l to label %invoke.cont
-left.end:
-  catchendpad unwind to caller
-right:
-  %r = catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  invoke void @f()
-    to label %right.ret unwind label %inner
-right.ret:
-  catchret %r to label %exit
-right.end:
-  catchendpad unwind to caller
-shared:
-  call void @h(i32 0)
-  unreachable
-inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 1)
-  catchret %i to label %shared
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This case tests the scenario where a funclet with multiple parents uses a
-; catchret to return to a block that may exist in either parent funclets.
-; Both %left and %right are parents of %inner.  During common block cloning
-; a clone of %shared will be made so that both %left and %right have a copy,
-; but the copy of %shared for one of the parent funclets will be unreachable
-; until the %inner funclet is cloned.  When the %inner.catch block is cloned
-; during the %inner funclet cloning, the catchret instruction should be updated
-; so that the catchret in the copy %inner.catch for %left returns to the copy of
-; %shared in %left and the catchret in the copy of %inner.catch for %right
-; returns to the copy of %shared for %right.
-; CHECK-LABEL: define void @test13(
-; CHECK:     left:
-; CHECK:       %l = catchpad []
-; CHECK:           to label %left.cont unwind label %left.end
-; CHECK:     left.cont:
-; CHECK:       invoke void @f()
-; CHECK:           to label %left.ret unwind label %[[INNER_LEFT:.+]]
-; CHECK:     left.ret:
-; CHECK:       catchret %l to label %invoke.cont
-; CHECK:     left.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     right:
-; CHECK:       %r = catchpad []
-; CHECK:           to label %right.catch unwind label %right.end
-; CHECK:     right.catch:
-; CHECK:       invoke void @f()
-; CHECK:           to label %right.ret unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     right.ret:
-; CHECK:       catchret %r to label %exit
-; CHECK:     right.end:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_RIGHT:.+]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[SHARED_LEFT:.+]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       %[[I_RIGHT:.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       %[[I_LEFT:.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 1)
-; CHECK:       catchret %[[I_RIGHT]] to label %[[SHARED_RIGHT]]
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 1)
-; CHECK:       catchret %[[I_LEFT]] to label %[[SHARED_LEFT]]
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-
-
-define void @test14() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  %l = catchpad []
-    to label %shared unwind label %left.end
-left.cont:
-  invoke void @f()
-    to label %left.ret unwind label %right
-left.ret: 
-  catchret %l to label %exit
-left.end:
-  catchendpad unwind to caller
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind label %left.end
-shared:
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 0)
-  catchret %i to label %left.cont
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This case tests another scenario where a funclet with multiple parents uses a
-; catchret to return to a block in one of the parent funclets.  Here %right and
-; %left are both parents of %inner and %left is a parent of %right.  The
-; catchret in %inner.catch will cause %left.cont and %left.ret to be cloned for
-; both %left and %right, but the catchret in %left.ret is invalid for %right
-; but the catchret instruction in the copy of %left.ret for %right will be
-; removed as an implausible terminator.
-; CHECK-LABEL: define void @test14(
-; CHECK:     left:
-; CHECK:       %l = catchpad []
-; CHECK:           to label %[[SHARED_LEFT:.+]] unwind label %[[LEFT_END:.+]]
-; CHECK:     [[LEFT_CONT:left.cont.*]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[LEFT_RET:.+]] unwind label %[[RIGHT:.+]]
-; CHECK:     [[LEFT_RET]]:
-; CHECK:       catchret %l to label %exit
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-; CHECK:     [[SHARED_LEFT]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       catchret [[I_LEFT]] to label %[[LEFT_CONT]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-
-define void @test15() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  %l = catchpad []
-    to label %left.catch unwind label %left.end
-left.catch:
-  invoke void @f()
-    to label %shared unwind label %right
-left.ret:
-  catchret %l to label %exit
-left.end:
-  catchendpad unwind to caller
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind label %left.end
-shared:
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 0)
-  catchret %i to label %left.ret
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This case is a variation of test14 but instead of returning to an invoke the
-; catchret in %inner.catch returns to a catchret instruction.
-; CHECK-LABEL: define void @test15(
-; CHECK:     left:
-; CHECK:       %l = catchpad []
-; CHECK:           to label %left.catch unwind label %[[LEFT_END:.+]]
-; CHECK:     left.catch:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_LEFT:.+]] unwind label %[[RIGHT:.+]]
-; CHECK:     [[LEFT_RET_RIGHT:.+]]:
-; CHECK:       unreachable
-; CHECK:     [[LEFT_RET_LEFT:.+]]:
-; CHECK:       catchret %l to label %exit
-; CHECK:     [[LEFT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-; CHECK:     [[SHARED_LEFT]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       catchret [[I_LEFT]] to label %[[LEFT_RET_LEFT]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       catchret [[I_RIGHT]] to label %[[LEFT_RET_RIGHT]]
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END]]
-
-
-define void @test16() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %exit unwind label %left
-left:
-  %l = cleanuppad []
-  br label %shared
-left.cont:
-  cleanupret %l unwind label %right
-left.end:
-  cleanupendpad %l unwind label %right
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %shared.cont unwind label %inner
-shared.cont:
-  unreachable
-inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.end
-inner.catch:
-  call void @h(i32 0)
-  catchret %i to label %left.cont
-inner.end:
-  catchendpad unwind label %left.end
-exit:
-  ret void
-}
-; This case is another variation of test14 but here the catchret in %inner.catch
-; returns to a cleanupret instruction.
-; CHECK-LABEL: define void @test16(
-; CHECK:     left:
-; CHECK:       %l = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     [[LEFT_CONT_RIGHT:.+]]:
-; CHECK:       unreachable
-; CHECK:     [[LEFT_CONT_LEFT:.+]]:
-; CHECK:       cleanupret %l unwind label %[[RIGHT:.+]]
-; CHECK:     [[LEFT_END_LEFT:.+]]:
-; CHECK:       cleanupendpad %l unwind label %[[RIGHT]]
-; CHECK:     [[RIGHT]]:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       catchret [[I_RIGHT]] to label %[[LEFT_CONT_RIGHT]]
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       catchret [[I_LEFT]] to label %[[LEFT_CONT_LEFT]]
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind label %[[LEFT_END_LEFT]]
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind to caller
-
-
-define void @test17() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  %l = cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-unreachable:
-  unreachable
-inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.sibling
-inner.catch:
-  call void @h(i32 0)
-  unreachable
-inner.sibling:
-  %is = catchpad []
-    to label %inner.sibling.catch unwind label %inner.end
-inner.sibling.catch:
-  invoke void @f()
-    to label %unreachable unwind label %inner.end
-inner.end:
-  catchendpad unwind label %right.end
-exit:
-  ret void
-}
-; This case tests the scenario where two catchpads with the same catchendpad
-; have multiple parents.  Both %left and %right are parents of %inner and
-; %inner.sibling so both of the inner funclets must be cloned.  Because
-; the catchendpad in %inner.end unwinds to the catchendpad for %right, the
-; unwind edge should be removed for the copy of %inner.end that is reached
-; from %left.  In addition, the %inner.siblin.catch block contains an invoke
-; that unwinds to the shared inner catchendpad.  The unwind destination for
-; this invoke should be updated to unwind to the correct cloned %inner.end
-; for each path to the funclet.
-; CHECK-LABEL: define void @test17(
-; CHECK:     left:
-; CHECK:       %l = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_SIBLING_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_SIBLING_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_SIBLING_RIGHT]]:
-; CHECK:       [[IS_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_SIBLING_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_SIBLING_LEFT]]:
-; CHECK:       [[IS_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_SIBLING_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_SIBLING_CATCH_RIGHT]]:
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]]
-; CHECK:     [[INNER_SIBLING_CATCH_LEFT]]:
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT]]
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind label %[[RIGHT_END]]
-
-
-define void @test18() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  %l = cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-unreachable:
-  unreachable
-inner:
-  %i = catchpad []
-    to label %inner.catch unwind label %inner.sibling
-inner.catch:
-  invoke void @f()
-    to label %unreachable unwind label %inner.end
-inner.sibling:
-  %is = catchpad []
-    to label %inner.sibling.catch unwind label %inner.end
-inner.sibling.catch:
-  call void @h(i32 0)
-  unreachable
-inner.end:
-  catchendpad unwind label %right.end
-exit:
-  ret void
-}
-; This is like test17 except that the inner invoke is moved from the
-; %inner.sibling funclet to %inner so that it is unwinding to a
-; catchendpad block that has not yet been cloned.  The unwind destination
-; of the invoke should still be updated to reach the correct copy of
-; %inner.end for the path by which it is reached.
-; CHECK-LABEL: define void @test18(
-; CHECK:     left:
-; CHECK:       %l = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_RIGHT:.+]] unwind label %[[INNER_SIBLING_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_CATCH_LEFT:.+]] unwind label %[[INNER_SIBLING_LEFT:.+]]
-; CHECK:     [[INNER_CATCH_RIGHT]]:
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_CATCH_LEFT]]:
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_SIBLING_RIGHT]]:
-; CHECK:       [[IS_RIGHT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_SIBLING_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]]
-; CHECK:     [[INNER_SIBLING_LEFT]]:
-; CHECK:       [[IS_LEFT:\%.+]] = catchpad []
-; CHECK:           to label %[[INNER_SIBLING_CATCH_LEFT:.+]] unwind label %[[INNER_END_LEFT]]
-; CHECK:     [[INNER_SIBLING_CATCH_RIGHT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_SIBLING_CATCH_LEFT]]:
-; CHECK:       call void @h(i32 0)
-; CHECK:       unreachable
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       catchendpad unwind label %[[RIGHT_END]]
-
-
-define void @test19() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  %l = cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-unreachable:
-  unreachable
-inner:
-  %i = cleanuppad []
-  invoke void @f()
-    to label %unreachable unwind label %inner.end
-inner.end:
-  cleanupendpad %i unwind label %right.end
-exit:
-  ret void
-}
-; This case tests the scenario where an invoke in a funclet with multiple
-; parents unwinds to a cleanup end pad for the funclet.  The unwind destination
-; for the invoke should map to the correct copy of the cleanup end pad block.
-; CHECK-LABEL: define void @test19(
-; CHECK:     left:
-; CHECK:       %l = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_END_LEFT:.+]]
-; CHECK:     [[INNER_END_RIGHT]]:
-; CHECK:       cleanupendpad [[I_RIGHT]] unwind label %[[RIGHT_END]]
-; CHECK:     [[INNER_END_LEFT]]:
-; CHECK:       cleanupendpad [[I_LEFT]] unwind to caller
-
-define void @test20() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @f()
-    to label %invoke.cont unwind label %left
-invoke.cont:
-  invoke void @f()
-    to label %exit unwind label %right
-left:
-  %l = cleanuppad []
-  br label %shared
-right:
-  catchpad []
-    to label %right.catch unwind label %right.end
-right.catch:
-  br label %shared
-right.end:
-  catchendpad unwind to caller
-shared:
-  invoke void @f()
-    to label %unreachable unwind label %inner
-unreachable:
-  unreachable
-inner:
-  %i = cleanuppad []
-  invoke void @f()
-    to label %unreachable unwind label %inner.cleanup
-inner.cleanup:
-  cleanuppad []
-  call void @f()
-  unreachable
-exit:
-  ret void
-}
-; This tests the case where a funclet with multiple parents contains an invoke
-; instruction that unwinds to a child funclet.  Here %left and %right are both
-; parents of %inner.  Initially %inner is the only parent of %inner.cleanup but
-; after %inner is cloned, %inner.cleanup has multiple parents and so it must
-; also be cloned.
-; CHECK-LABEL: define void @test20(
-; CHECK:     left:
-; CHECK:       %l = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_LEFT:.+]] unwind label %[[INNER_LEFT:.+]]
-; CHECK:     right:
-; CHECK:       catchpad []
-; CHECK:           to label %[[RIGHT_CATCH:.+]] unwind label %[[RIGHT_END:.+]]
-; CHECK:     [[RIGHT_CATCH]]:
-; CHECK:       invoke void @f()
-; CHECK:           to label %[[SHARED_CONT_RIGHT:.+]] unwind label %[[INNER_RIGHT:.+]]
-; CHECK:     [[RIGHT_END]]:
-; CHECK:       catchendpad unwind to caller
-; CHECK:     [[SHARED_CONT_RIGHT]]:
-; CHECK:       unreachable
-; CHECK:     [[SHARED_CONT_LEFT]]:
-; CHECK:       unreachable
-; CHECK:     [[INNER_RIGHT]]:
-; CHECK:       [[I_RIGHT:\%.+]] = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_CLEANUP_RIGHT:.+]]
-; CHECK:     [[INNER_LEFT]]:
-; CHECK:       [[I_LEFT:\%.+]] = cleanuppad []
-; CHECK:       invoke void @f()
-; CHECK:         to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_CLEANUP_LEFT:.+]]
-; CHECK:     [[INNER_CLEANUP_RIGHT]]:
-; CHECK:       cleanuppad []
-; CHECK:       call void @f()
-; CHECK:       unreachable
-; CHECK:     [[INNER_CLEANUP_LEFT]]:
-; CHECK:       cleanuppad []
-; CHECK:       call void @f()
-; CHECK:       unreachable
-
-
diff --git a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
index 4f02394..7d18238 100644
--- a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll
@@ -2,6 +2,8 @@
 
 declare i32 @__CxxFrameHandler3(...)
 
+declare i32 @__C_specific_handler(...)
+
 declare void @f()
 
 declare i32 @g()
@@ -9,7 +11,7 @@
 declare void @h(i32)
 
 ; CHECK-LABEL: @test1(
-define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test1() personality i32 (...)* @__C_specific_handler {
 entry:
   invoke void @f()
           to label %invoke.cont1 unwind label %left
@@ -23,11 +25,11 @@
           to label %exit unwind label %inner
 
 left:
-  %0 = cleanuppad []
+  %0 = cleanuppad within none []
   br label %shared
 
 right:
-  %1 = cleanuppad []
+  %1 = cleanuppad within none []
   br label %shared
 
 shared:
@@ -40,25 +42,20 @@
 
 inner:
   %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont2 ]
-  %i = cleanuppad []
+  %i = cleanuppad within none []
   call void @h(i32 %phi)
   unreachable
 
-; CHECK [[INNER_INVOKE_CONT2:inner.*]]:
-  ; CHECK: call void @h(i32 0)
-
-; CHECK [[INNER_RIGHT:inner.*]]:
-  ; CHECK: call void @h(i32 %x)
-
-; CHECK [[INNER_LEFT:inner.*]]:
-  ; CHECK: call void @h(i32 %x.for.left)
+; CHECK: %phi = phi i32 [ %x, %right ], [ 0, %invoke.cont2 ], [ %x.for.left, %left ]
+; CHECK: %i = cleanuppad within none []
+; CHECK: call void @h(i32 %phi)
 
 exit:
   unreachable
 }
 
 ; CHECK-LABEL: @test2(
-define void @test2() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test2() personality i32 (...)* @__C_specific_handler {
 entry:
   invoke void @f()
           to label %invoke.cont unwind label %left
@@ -68,11 +65,11 @@
           to label %exit unwind label %right
 
 left:
-  cleanuppad []
+  cleanuppad within none []
   br label %shared
 
 right:
-  cleanuppad []
+  cleanuppad within none []
   br label %shared
 
 shared:
@@ -84,15 +81,13 @@
   unreachable
 
 inner:
-  %i = cleanuppad []
+  %i = cleanuppad within none []
   call void @h(i32 %x)
   unreachable
 
-; CHECK [[INNER_RIGHT:inner.*]]:
-  ; CHECK: call void @h(i32 %x)
-
-; CHECK [[INNER_LEFT:inner.*]]:
-  ; CHECK: call void @h(i32 %x.for.left)
+; CHECK:  %x1 = phi i32 [ %x.for.left, %left ], [ %x, %right ]
+; CHECK:  %i = cleanuppad within none []
+; CHECK:  call void @h(i32 %x1)
 
 exit:
   unreachable
@@ -108,10 +103,47 @@
   ret void
 
 terminate:
-; CHECK:  cleanuppad []
+; CHECK:  cleanuppad within none []
 ; CHECK:  call void @__std_terminate()
 ; CHECK:  unreachable
-  terminatepad [void ()* @__std_terminate] unwind to caller
+  terminatepad within none [void ()* @__std_terminate] unwind to caller
+}
+
+; CHECK-LABEL: @test4(
+define void @test4(i1 %x) personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  invoke void @f()
+          to label %invoke.cont1 unwind label %left
+
+invoke.cont1:
+  invoke void @f()
+          to label %exit unwind label %right
+
+left:
+  %0 = cleanuppad within none []
+  br label %shared
+
+right:
+  %1 = cleanuppad within none []
+  br i1 %x, label %shared, label %right.other
+
+right.other:
+  br label %shared
+
+shared:
+  %phi = phi i32 [ 1, %left ], [ 0, %right ], [ -1, %right.other ]
+  call void @h(i32 %phi)
+  unreachable
+
+; CHECK: %0 = cleanuppad within none []
+; CHECK: call void @h(i32 1)
+
+; CHECK: %1 = cleanuppad within none []
+; CHECK: %phi = phi i32 [ 0, %right ], [ -1, %right.other ]
+; CHECK: call void @h(i32 %phi)
+
+exit:
+  unreachable
 }
 
 declare void @__std_terminate()
diff --git a/llvm/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll b/llvm/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll
index bd1f232..f5889f0 100644
--- a/llvm/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll
@@ -7,38 +7,6 @@
 
 declare void @f(i32)
 
-; CHECK-LABEL: define void @test1(
-;Cxx: define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
-;SEH: define void @test1() personality i32 (...)* @_except_handler3 {
-entry:
-  ; CHECK: entry:
-  ; CHECK:  store i32 0
-  ; CHECK:  invoke void @f(i32 0)
-  invoke void @f(i32 0)
-    to label %exit unwind label %cleanup.pad
-cleanup.pad:
-  ; CHECK: cleanup.pad:
-  ; CHECK:   store i32 1
-  ; CHECK:   invoke void @f(i32 1)
-  %cleanup = cleanuppad []
-  invoke void @f(i32 1)
-    to label %cleanup.ret unwind label %catch.pad
-catch.pad:
-;Cxx: %catch = catchpad [i8* null, i32 u0x40, i8* null]
-;SEH: %catch = catchpad [void ()* @dummy_filter]
-        to label %catch.body unwind label %catch.end
-catch.body:
-  catchret %catch to label %cleanup.ret
-catch.end:
-  catchendpad unwind label %cleanup.end
-cleanup.ret:
-  cleanupret %cleanup unwind to caller
-cleanup.end:
-  cleanupendpad %cleanup unwind to caller
-exit:
-  ret void
-}
-
 ; CHECK-LABEL: define void @test2(
 ;Cxx: define void @test2(i1 %b) personality i32 (...)* @__CxxFrameHandler3 {
 ;SEH: define void @test2(i1 %b) personality i32 (...)* @_except_handler3 {
@@ -49,20 +17,18 @@
   invoke void @f(i32 1)
     to label %exit unwind label %cleanup.pad
 cleanup.pad:
-  %cleanup = cleanuppad []
+  %cleanup = cleanuppad within none []
   br i1 %b, label %left, label %right
 left:
-  cleanupret %cleanup unwind label %catch.pad
+  cleanupret from %cleanup unwind label %catch.pad
 right:
-  cleanupret %cleanup unwind label %catch.pad
+  cleanupret from %cleanup unwind label %catch.pad
 catch.pad:
-;Cxx: %catch = catchpad [i8* null, i32 u0x40, i8* null]
-;SEH: %catch = catchpad [void ()* @dummy_filter]
-        to label %catch.body unwind label %catch.end
+  %cs1 = catchswitch within none [label %catch.body] unwind to caller
 catch.body:
-  catchret %catch to label %exit
-catch.end:
-  catchendpad unwind to caller
+;Cxx: %catch = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
+;SEH: %catch = catchpad within %cs1 [void ()* @dummy_filter]
+  catchret from %catch to label %exit
 exit:
   ret void
 }
@@ -72,29 +38,25 @@
 ;SEH: define void @test3() personality i32 (...)* @_except_handler3 {
 entry:
   ; CHECK: entry:
-  ; CHECK:   store i32 1
+  ; CHECK:   store i32 0
   ; CHECK:   invoke void @f(i32 1)
   invoke void @f(i32 1)
     to label %exit unwind label %cleanup.pad
 cleanup.pad:
   ; CHECK: cleanup.pad:
-  ; CHECK:   store i32 0
+  ; CHECK:   store i32 1
   ; CHECK:   invoke void @f(i32 0)
-  %cleanup = cleanuppad []
+  %cleanup = cleanuppad within none []
   invoke void @f(i32 0)
-    to label %unreachable unwind label %cleanup.end
+    to label %unreachable unwind label %catch.pad
 unreachable:
   unreachable
-cleanup.end:
-  cleanupendpad %cleanup unwind label %catch.pad
 catch.pad:
-;Cxx: %catch = catchpad [i8* null, i32 u0x40, i8* null]
-;SEH: %catch = catchpad [void ()* @dummy_filter]
-        to label %catch.body unwind label %catch.end
+  %cs1 = catchswitch within none [label %catch.body] unwind to caller
 catch.body:
-  catchret %catch to label %exit
-catch.end:
-  catchendpad unwind to caller
+;Cxx: %catch = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
+;SEH: %catch = catchpad within %cs1 [void ()* @dummy_filter]
+  catchret from %catch to label %exit
 exit:
   ret void
 }
diff --git a/llvm/test/CodeGen/WinEH/wineh-statenumbering.ll b/llvm/test/CodeGen/WinEH/wineh-statenumbering.ll
index 2d5f7ca..b7ec843 100644
--- a/llvm/test/CodeGen/WinEH/wineh-statenumbering.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-statenumbering.ll
@@ -37,9 +37,10 @@
           to label %unreachable.for.entry unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %1 = catchpad [i8* null, i32 u0x40, i8* null] to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
+  %1 = catchpad within %cs1 [i8* null, i32 u0x40, i8* null]
   ; CHECK: catch:
   ; CHECK:   store i32 2
   ; CHECK:   invoke void @_CxxThrowException(
@@ -47,34 +48,22 @@
           to label %unreachable unwind label %catch.dispatch.1
 
 catch.dispatch.1:                                 ; preds = %catch
-  %2 = catchpad [i8* null, i32 u0x40, i8* null] to label %catch.3 unwind label %catchendblock.2
-
+  %cs2 = catchswitch within %1 [label %catch.3] unwind to caller
 catch.3:                                          ; preds = %catch.dispatch.1
+  %2 = catchpad within %cs2 [i8* null, i32 u0x40, i8* null]
   ; CHECK: catch.3:
   ; CHECK:   store i32 3
-  ; CHECK:   invoke void @g(i32 1)
-  invoke void @g(i32 1)
-          to label %invoke.cont unwind label %catchendblock.2
+  ; CHECK:   call void @g(i32 1)
+  call void @g(i32 1)
+  catchret from %2 to label %try.cont
 
-invoke.cont:                                      ; preds = %catch.3
-  catchret %2 to label %try.cont
-
-try.cont:                                         ; preds = %invoke.cont
+try.cont:                                         ; preds = %catch.3
   ; CHECK: try.cont:
   ; CHECK:   store i32 1
-  ; CHECK:   invoke void @g(i32 2)
-  invoke void @g(i32 2)
-          to label %invoke.cont.4 unwind label %catchendblock
-
-invoke.cont.4:                                    ; preds = %try.cont
+  ; CHECK:   call void @g(i32 2)
+  call void @g(i32 2)
   unreachable
 
-catchendblock.2:                                  ; preds = %catch.3, %catch.dispatch.1
-  catchendpad unwind label %catchendblock
-
-catchendblock:                                    ; preds = %catchendblock.2, %try.cont, %catch.dispatch
-  catchendpad unwind to caller
-
 unreachable:                                      ; preds = %catch
   unreachable
 
diff --git a/llvm/test/CodeGen/X86/branchfolding-catchpads.ll b/llvm/test/CodeGen/X86/branchfolding-catchpads.ll
index 21c7818..0468b3c 100644
--- a/llvm/test/CodeGen/X86/branchfolding-catchpads.ll
+++ b/llvm/test/CodeGen/X86/branchfolding-catchpads.ll
@@ -19,24 +19,18 @@
           to label %cleanup unwind label %catch.dispatch
 
 catch.dispatch:
-  catchpad [i8* null, i32 8, i8* null]
-          to label %catch unwind label %catch.dispatch.2
+  %cs = catchswitch within none [ label %catch, label %catch.2 ] unwind to caller
 
 catch:
-  invoke void @throw() noreturn
-          to label %unreachable unwind label %catchendblock
-
-catch.dispatch.2:
-  catchpad [i8* null, i32 64, i8* null]
-          to label %catch.2 unwind label %catchendblock
+  catchpad within %cs [i8* null, i32 8, i8* null]
+  call void @throw() noreturn
+  br label %unreachable
 
 catch.2:
+  catchpad within %cs [i8* null, i32 64, i8* null]
   store i8 1, i8* %b
-  invoke void @throw() noreturn
-          to label %unreachable unwind label %catchendblock
-
-catchendblock:
-  catchendpad unwind to caller
+  call void @throw() noreturn
+  br label %unreachable
 
 cleanup:
   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ]
@@ -67,31 +61,22 @@
           to label %cleanup unwind label %catch.dispatch
 
 catch.dispatch:
-  catchpad [i8* null, i32 8, i8* null]
-          to label %catch unwind label %catch.dispatch.2
+  %cs = catchswitch within none [ label %catch, label %catch.2, label %catch.3 ] unwind to caller
 
 catch:
-  invoke void @throw() noreturn
-          to label %unreachable unwind label %catchendblock
-
-catch.dispatch.2:
-  %c2 = catchpad [i8* null, i32 32, i8* null]
-          to label %catch.2 unwind label %catch.dispatch.3
+  catchpad within %cs [i8* null, i32 8, i8* null]
+  call void @throw() noreturn
+  br label %unreachable
 
 catch.2:
+  %c2 = catchpad within %cs [i8* null, i32 32, i8* null]
   store i8 1, i8* %b
-  catchret %c2 to label %cleanup
-
-catch.dispatch.3:
-  %c3 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch.3 unwind label %catchendblock
+  catchret from %c2 to label %cleanup
 
 catch.3:
+  %c3 = catchpad within %cs [i8* null, i32 64, i8* null]
   store i8 2, i8* %b
-  catchret %c3 to label %cleanup
-
-catchendblock:
-  catchendpad unwind to caller
+  catchret from %c3 to label %cleanup
 
 cleanup:
   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ], [ -1, %catch.2 ], [ -1, %catch.3 ]
diff --git a/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll b/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll
index 267c693..1160101 100644
--- a/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll
+++ b/llvm/test/CodeGen/X86/catchpad-realign-savexmm.ll
@@ -14,19 +14,17 @@
   %v1 = fadd double %v, 1.0
   store double %v1, double* @fp_global
   invoke void @g()
-      to label %return unwind label %catch
+      to label %return unwind label %catch.dispatch
 
 return:
   ret void
 
-catch:
-  %p = catchpad [i8* null, i32 64, i8* null]
-      to label %catchit unwind label %endpad
+catch.dispatch:
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
-catchit:
-  catchret %p to label %return
-endpad:
-  catchendpad unwind to caller
+catch:
+  %p = catchpad within %cs1 [i8* null, i32 64, i8* null]
+  catchret from %p to label %return
 }
 
 ; CHECK: f: # @f
diff --git a/llvm/test/CodeGen/X86/catchpad-regmask.ll b/llvm/test/CodeGen/X86/catchpad-regmask.ll
index fe3a238..0d436f6 100644
--- a/llvm/test/CodeGen/X86/catchpad-regmask.ll
+++ b/llvm/test/CodeGen/X86/catchpad-regmask.ll
@@ -41,14 +41,14 @@
           to label %unreachable unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
+  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]
   %idxprom1 = sext i32 %idx2 to i64
   %arrayidx2 = getelementptr inbounds [4 x i32], [4 x i32]* @array, i64 0, i64 %idxprom1
   store i32 222, i32* %arrayidx2, align 4, !tbaa !2
-  catchret %0 to label %try.cont
+  catchret from %0 to label %try.cont
 
 try.cont:                                         ; preds = %catch
   %idxprom3 = sext i32 %idx3 to i64
@@ -56,9 +56,6 @@
   store i32 333, i32* %arrayidx4, align 4, !tbaa !2
   ret void
 
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
-
 unreachable:                                      ; preds = %entry
   unreachable
 }
@@ -98,20 +95,17 @@
           to label %unreachable unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
+  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]
   store i32 222, i32* @imported, align 4, !tbaa !2
-  catchret %0 to label %try.cont
+  catchret from %0 to label %try.cont
 
 try.cont:                                         ; preds = %catch
   store i32 333, i32* @imported, align 4, !tbaa !2
   ret void
 
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
-
 unreachable:                                      ; preds = %entry
   unreachable
 }
diff --git a/llvm/test/CodeGen/X86/catchpad-weight.ll b/llvm/test/CodeGen/X86/catchpad-weight.ll
index e8b4168..1abcd03 100644
--- a/llvm/test/CodeGen/X86/catchpad-weight.ll
+++ b/llvm/test/CodeGen/X86/catchpad-weight.ll
@@ -2,7 +2,7 @@
 
 ; Check if the edge weight to the catchpad is calculated correctly.
 
-; CHECK: Successors according to CFG: BB#3(0x7ffff100 / 0x80000000 = 100.00%) BB#1(0x00000800 / 0x80000000 = 0.00%) BB#4(0x00000400 / 0x80000000 = 0.00%) BB#6(0x00000200 / 0x80000000 = 0.00%) BB#8(0x00000100 / 0x80000000 = 0.00%)
+; CHECK: Successors according to CFG: BB#2(0x7ffff100 / 0x80000000 = 100.00%) BB#1(0x00000800 / 0x80000000 = 0.00%) BB#3(0x00000400 / 0x80000000 = 0.00%) BB#4(0x00000200 / 0x80000000 = 0.00%) BB#5(0x00000100 / 0x80000000 = 0.00%)
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64--windows-msvc18.0.0"
@@ -31,11 +31,11 @@
           to label %try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %1 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8", i32 0, i8* null]
-          to label %catch.5 unwind label %catch.dispatch.1
+  %cs1 = catchswitch within none [label %catch.5] unwind label %catch.dispatch.1
 
 catch.5:                                          ; preds = %catch.dispatch
-  catchret %1 to label %try.cont
+  %1 = catchpad within %cs1 [%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8", i32 0, i8* null]
+  catchret from %1 to label %try.cont
 
 try.cont:                                         ; preds = %entry, %catch, %catch.3, %catch.5
   call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4
@@ -43,26 +43,23 @@
   ret i32 0
 
 catch.dispatch.1:                                 ; preds = %catch.dispatch
-  %2 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8", i32 0, i8* null]
-          to label %catch.3 unwind label %catch.dispatch.2
+  %cs2 = catchswitch within none [label %catch.3] unwind label %catch.dispatch.2
 
 catch.3:                                          ; preds = %catch.dispatch.1
-  catchret %2 to label %try.cont
+  %2 = catchpad within %cs2 [%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8", i32 0, i8* null]
+  catchret from %2 to label %try.cont
 
 catch.dispatch.2:                                 ; preds = %catch.dispatch.1
-  %3 = catchpad [%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8", i32 0, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs3 = catchswitch within none [label %catch] unwind label %ehcleanup
 
 catch:                                            ; preds = %catch.dispatch.2
-  catchret %3 to label %try.cont
-
-catchendblock:                                    ; preds = %catch.dispatch.2
-  catchendpad unwind label %ehcleanup
+  %3 = catchpad within %cs3 [%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8", i32 0, i8* null]
+  catchret from %3 to label %try.cont
 
 ehcleanup:                                        ; preds = %catchendblock
-  %4 = cleanuppad []
+  %4 = cleanuppad within none []
   call void @"\01??1HasDtor@@QEAA@XZ"(%struct.HasDtor* nonnull %o) #4
-  cleanupret %4 unwind to caller
+  cleanupret from %4 unwind to caller
 }
 
 ; Function Attrs: nounwind argmemonly
diff --git a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
index 3b3b3f5..585f7bc 100644
--- a/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
+++ b/llvm/test/CodeGen/X86/catchret-empty-fallthrough.ll
@@ -19,14 +19,11 @@
           to label %fallthrough unwind label %dispatch
 
 dispatch:                                         ; preds = %try
-  %0 = catchpad [i8* null]
-          to label %catch unwind label %catchendblock.i.i
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %dispatch
-  catchret %0 to label %return
-
-catchendblock.i.i:                                ; preds = %dispatch
-  catchendpad unwind to caller
+  %0 = catchpad within %cs1 [i8* null]
+  catchret from %0 to label %return
 
 fallthrough:                                      ; preds = %try
   unreachable
diff --git a/llvm/test/CodeGen/X86/catchret-fallthrough.ll b/llvm/test/CodeGen/X86/catchret-fallthrough.ll
index f732566..6a94b29 100644
--- a/llvm/test/CodeGen/X86/catchret-fallthrough.ll
+++ b/llvm/test/CodeGen/X86/catchret-fallthrough.ll
@@ -18,14 +18,11 @@
           to label %invoke.cont.3 unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
-  catchret %0 to label %nrvo.skipdtor
-
-catchendblock:                                    ; preds = %catch, %catch.dispatch
-  catchendpad unwind to caller
+  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]
+  catchret from %0 to label %nrvo.skipdtor
 
 invoke.cont.3:                                    ; preds = %entry
   store i32 123, i32* @some_global
diff --git a/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll b/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll
index 8858f37..294ef3a 100644
--- a/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll
+++ b/llvm/test/CodeGen/X86/cleanuppad-inalloca.ll
@@ -29,9 +29,9 @@
   ret void
 
 ehcleanup:                                        ; preds = %entry
-  %2 = cleanuppad []
+  %2 = cleanuppad within none []
   call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %0)
-  cleanupret %2 unwind to caller
+  cleanupret from %2 unwind to caller
 }
 
 ; CHECK: _passes_two:
diff --git a/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll b/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll
index df866f9..e32cdbe 100644
--- a/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll
+++ b/llvm/test/CodeGen/X86/cleanuppad-large-codemodel.ll
@@ -9,9 +9,9 @@
   invoke void @bar()
     to label %exit unwind label %cleanup
 cleanup:
-  %c = cleanuppad []
+  %c = cleanuppad within none []
   call void @bar()
-  cleanupret %c unwind to caller
+  cleanupret from %c unwind to caller
 exit:
   ret void
 }
diff --git a/llvm/test/CodeGen/X86/cleanuppad-realign.ll b/llvm/test/CodeGen/X86/cleanuppad-realign.ll
index a19cf26..d322932 100644
--- a/llvm/test/CodeGen/X86/cleanuppad-realign.ll
+++ b/llvm/test/CodeGen/X86/cleanuppad-realign.ll
@@ -17,9 +17,9 @@
   ret void
 
 ehcleanup:                                        ; preds = %entry
-  %0 = cleanuppad []
+  %0 = cleanuppad within none []
   call void @Dtor(i64* %o)
-  cleanupret %0 unwind to caller
+  cleanupret from %0 unwind to caller
 }
 
 ; X86-LABEL: _realigned_cleanup: # @realigned_cleanup
diff --git a/llvm/test/CodeGen/X86/funclet-layout.ll b/llvm/test/CodeGen/X86/funclet-layout.ll
index 053d484..b5972df 100644
--- a/llvm/test/CodeGen/X86/funclet-layout.ll
+++ b/llvm/test/CodeGen/X86/funclet-layout.ll
@@ -15,21 +15,21 @@
           to label %unreachable unwind label %catch.dispatch
 
 catch.dispatch:
-  %cp = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:
-  br i1 %B, label %catchret, label %catch
+  %cp = catchpad within %cs1 [i8* null, i32 64, i8* null]
+  br label %catch.loop
+
+catch.loop:
+  br i1 %B, label %catchret, label %catch.loop
 
 catchret:
-  catchret %cp to label %try.cont
+  catchret from %cp to label %try.cont
 
 try.cont:
   ret void
 
-catchendblock:
-  catchendpad unwind to caller
-
 unreachable:
   unreachable
 }
@@ -55,54 +55,50 @@
           to label %unreachable unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
+  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]
   invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1
           to label %unreachable unwind label %catch.dispatch.1
 
 catch.dispatch.1:                                 ; preds = %catch
-  %1 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch.3 unwind label %catchendblock.2
+  %cs2 = catchswitch within %0 [label %catch.3] unwind to caller
 
 catch.3:                                          ; preds = %catch.dispatch.1
-  catchret %1 to label %try.cont
+  %1 = catchpad within %cs2 [i8* null, i32 64, i8* null]
+  catchret from %1 to label %try.cont
 
 try.cont:                                         ; preds = %catch.3
-  catchret %0 to label %try.cont.5
+  catchret from %0 to label %try.cont.5
 
 try.cont.5:                                       ; preds = %try.cont
   ret i32 0
 
-catchendblock.2:                                  ; preds = %catch.dispatch.1
-  catchendpad unwind label %catchendblock
-
-catchendblock:                                    ; preds = %catchendblock.2, %catch.dispatch
-  catchendpad unwind to caller
-
 unreachable:                                      ; preds = %catch, %entry
   unreachable
-
 }
 
 ; CHECK-LABEL: test2:
 
-; The entry funclet contains %entry and %try.cont.5
+; The parent function contains %entry and %try.cont.5
+; CHECK: .seh_proc
 ; CHECK: # %entry
 ; CHECK: # %try.cont.5
 ; CHECK: retq
 
-; The outer catch funclet contains %catch.dispatch
-; CHECK: # %catch.dispatch{{$}}
+; The inner catch funclet contains %catch.3
+; CHECK: .seh_proc
+; CHECK: # %catch.3{{$}}
+; CHECK: retq
+
+; The outer catch funclet contains %catch
+; CHECK: .seh_proc
+; CHECK: # %catch{{$}}
 ; CHECK: callq _CxxThrowException
 ; CHECK: # %unreachable
 ; CHECK: ud2
 
-; The inner catch funclet contains %catch.dispatch.1
-; CHECK: # %catch.dispatch.1
-; CHECK: retq
-
 
 define void @test3(i1 %V) #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
 entry:
@@ -110,24 +106,21 @@
           to label %try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch.2 unwind label %catch.dispatch.1
+  %cs1 = catchswitch within none [label %catch.2] unwind label %catch.dispatch.1
 
 catch.2:                                          ; preds = %catch.dispatch
+  %0 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
   tail call void @exit(i32 0) #2
   unreachable
 
 catch.dispatch.1:                                 ; preds = %catch.dispatch
-  %1 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs2 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch.1
+  %1 = catchpad within %cs2 [i8* null, i32 64, i8* null]
   tail call void @exit(i32 0) #2
   unreachable
 
-catchendblock:                                    ; preds = %catch.dispatch.1
-  catchendpad unwind to caller
-
 try.cont:                                         ; preds = %entry
   br i1 %V, label %exit_one, label %exit_two
 
@@ -150,13 +143,13 @@
 ; CHECK-NOT: # exit_two
 ; CHECK: ud2
 
-; The catch(...) funclet contains %catch.dispatch
-; CHECK: # %catch.dispatch{{$}}
+; The catch(...) funclet contains %catch.2
+; CHECK: # %catch.2{{$}}
 ; CHECK: callq exit
 ; CHECK: ud2
 
-; The catch(int) funclet contains %catch.dispatch.1
-; CHECK: # %catch.dispatch.1
+; The catch(int) funclet contains %catch
+; CHECK: # %catch{{$}}
 ; CHECK: callq exit
 ; CHECK: ud2
 
diff --git a/llvm/test/CodeGen/X86/late-address-taken.ll b/llvm/test/CodeGen/X86/late-address-taken.ll
index 8f85393..f98c535 100644
--- a/llvm/test/CodeGen/X86/late-address-taken.ll
+++ b/llvm/test/CodeGen/X86/late-address-taken.ll
@@ -22,19 +22,17 @@
   invoke void @f()
           to label %exit unwind label %catch.pad
 catch.pad:
-  %catch = catchpad [i32 33554467]
-          to label %catch.body unwind label %catch.end
+  %cs1 = catchswitch within none [label %catch.body] unwind to caller
 catch.body:
-  catchret %catch to label %exit
-catch.end:
-  catchendpad unwind to caller
+  %catch = catchpad within %cs1 [i32 33554467]
+  catchret from %catch to label %exit
 exit:
   ret void
 }
 ; CHECK-LABEL: catchret:  # @catchret
 ; CHECK: [[Exit:^[^ :]+]]: # Block address taken
 ; CHECK-NEXT:              # %exit
-; CHECK: # %catch.pad
+; CHECK: # %catch.body
 ; CHECK: .seh_endprolog
 ; CHECK: leaq [[Exit]](%rip), %rax
 ; CHECK: retq # CATCHRET
diff --git a/llvm/test/CodeGen/X86/seh-catch-all-win32.ll b/llvm/test/CodeGen/X86/seh-catch-all-win32.ll
index 5d9d503..69afb1b 100644
--- a/llvm/test/CodeGen/X86/seh-catch-all-win32.ll
+++ b/llvm/test/CodeGen/X86/seh-catch-all-win32.ll
@@ -22,16 +22,13 @@
           to label %__try.cont unwind label %lpad
 
 lpad:                                             ; preds = %entry
-  %p = catchpad [i8* bitcast (i32 ()* @"filt$main" to i8*)]
-          to label %__except unwind label %endpad
+  %cs1 = catchswitch within none [label %__except] unwind to caller
 
 __except:                                         ; preds = %lpad
+  %p = catchpad within %cs1 [i8* bitcast (i32 ()* @"filt$main" to i8*)]
   %code = load i32, i32* %__exceptioncode, align 4
   %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4
-  catchret %p to label %__try.cont
-
-endpad:                                        ; preds = %lpad
-  catchendpad unwind to caller
+  catchret from %p to label %__try.cont
 
 __try.cont:                                       ; preds = %entry, %__except
   ret i32 0
@@ -73,7 +70,7 @@
 ; CHECK: popl %edi
 ; CHECK: popl %ebx
 ; CHECK: retl
-; CHECK: LBB0_[[lpbb:[0-9]+]]: # %lpad{{$}}
+; CHECK: LBB0_[[lpbb:[0-9]+]]: # %__except{{$}}
 ;       stackrestore
 ; CHECK: movl -24(%ebp), %esp
 ;       EH state -1
diff --git a/llvm/test/CodeGen/X86/seh-catch-all.ll b/llvm/test/CodeGen/X86/seh-catch-all.ll
index aa1b6e0..4463485 100644
--- a/llvm/test/CodeGen/X86/seh-catch-all.ll
+++ b/llvm/test/CodeGen/X86/seh-catch-all.ll
@@ -16,16 +16,13 @@
   ret i32 0
 
 lpad:
-  %p = catchpad [i8* null, i32 64, i8* null]
-          to label %catchall unwind label %endpad
+  %cs1 = catchswitch within none [label %catchall] unwind to caller
 
 catchall:
+  %p = catchpad within %cs1 [i8* null, i32 64, i8* null]
   %code = call i32 @llvm.eh.exceptioncode(token %p)
   call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i64 0, i64 0), i32 %code)
-  catchret %p to label %__try.cont
-
-endpad:
-  catchendpad unwind to caller
+  catchret from %p to label %__try.cont
 }
 
 ; Check that we can get the exception code from eax to the printf.
@@ -33,7 +30,7 @@
 ; CHECK-LABEL: main:
 ; CHECK: callq crash
 ; CHECK: retq
-; CHECK: .LBB0_2: # %lpad
+; CHECK: .LBB0_2: # %catchall
 ; CHECK: leaq str(%rip), %rcx
 ; CHECK: movl %eax, %edx
 ; CHECK: callq printf
diff --git a/llvm/test/CodeGen/X86/seh-catchpad.ll b/llvm/test/CodeGen/X86/seh-catchpad.ll
index 895dba8..a8be4ec 100644
--- a/llvm/test/CodeGen/X86/seh-catchpad.ll
+++ b/llvm/test/CodeGen/X86/seh-catchpad.ll
@@ -45,13 +45,6 @@
   %call = invoke i32 @do_div(i32 1, i32 0) #4
           to label %__try.cont.12 unwind label %catch.dispatch
 
-catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null]
-          to label %__except unwind label %catchendblock
-
-__except:                                         ; preds = %catch.dispatch
-  catchret %0 to label %__except.2
-
 __except.2:                                       ; preds = %__except
   %call4 = invoke i32 @do_div(i32 1, i32 0) #4
           to label %invoke.cont.3 unwind label %ehcleanup
@@ -60,24 +53,6 @@
   invoke fastcc void @"\01?fin$0@0@main@@"() #4
           to label %__try.cont.12 unwind label %catch.dispatch.7
 
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind label %catch.dispatch.7
-
-ehcleanup:                                        ; preds = %__except.2
-  %1 = cleanuppad []
-  invoke fastcc void @"\01?fin$0@0@main@@"() #4
-          to label %invoke.cont.6 unwind label %ehcleanup.end
-
-invoke.cont.6:                                    ; preds = %ehcleanup
-  cleanupret %1 unwind label %catch.dispatch.7
-
-catch.dispatch.7:                                 ; preds = %invoke.cont.3, %invoke.cont.6, %ehcleanup.end, %catchendblock
-  %2 = catchpad [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@main@@" to i8*)]
-          to label %__except.ret unwind label %catchendblock.8
-
-__except.ret:                                     ; preds = %catch.dispatch.7
-  catchret %2 to label %__except.9
-
 __except.9:                                       ; preds = %__except.ret
   %call11 = tail call i32 @puts(i8* nonnull getelementptr inbounds ([7 x i8], [7 x i8]* @"\01??_C@_06IBDBCMGJ@caught?$AA@", i64 0, i64 0))
   br label %__try.cont.12
@@ -85,11 +60,27 @@
 __try.cont.12:                                    ; preds = %invoke.cont.3, %entry, %__except.9
   ret i32 0
 
-catchendblock.8:                                  ; preds = %catch.dispatch.7
-  catchendpad unwind to caller
+catch.dispatch:                                   ; preds = %entry
+  %cs1 = catchswitch within none [label %__except] unwind label %catch.dispatch.7
 
-ehcleanup.end:                                    ; preds = %ehcleanup
-  cleanupendpad %1 unwind label %catch.dispatch.7
+__except:                                         ; preds = %catch.dispatch
+  %cp1 = catchpad within %cs1 [i8* null]
+  catchret from %cp1 to label %__except.2
+
+ehcleanup:                                        ; preds = %__except.2
+  %cp2 = cleanuppad within none []
+  invoke fastcc void @"\01?fin$0@0@main@@"() #4
+          to label %invoke.cont.6 unwind label %catch.dispatch.7
+
+invoke.cont.6:                                    ; preds = %ehcleanup
+  cleanupret from %cp2 unwind label %catch.dispatch.7
+
+catch.dispatch.7:
+  %cs2 = catchswitch within none [label %__except.ret] unwind to caller
+
+__except.ret:                                     ; preds = %catch.dispatch.7
+  %cp3 = catchpad within %cs2 [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@main@@" to i8*)]
+  catchret from %cp3 to label %__except.9
 }
 
 ; CHECK: main:                                   # @main
@@ -112,7 +103,7 @@
 ; CHECK:         addq    $32, %rsp
 ; CHECK:         popq    %rbp
 ; CHECK:         retq
-; CHECK: .LBB1_[[except1bb:[0-9]+]]:                                # %catch.dispatch
+; CHECK: .LBB1_[[except1bb:[0-9]+]]:                                # %__except
 ; CHECK: .Ltmp2:
 ; CHECK:         movl    $1, %ecx
 ; CHECK:         xorl    %edx, %edx
@@ -120,7 +111,7 @@
 ; CHECK: .Ltmp3:
 ; CHECK:         callq   "?fin$0@0@main@@"
 ; CHECK:         jmp     .LBB1_[[epilogue]]
-; CHECK: .LBB1_[[except2bb:[0-9]+]]:                                # %catch.dispatch.7
+; CHECK: .LBB1_[[except2bb:[0-9]+]]:                                # %__except.ret
 ; CHECK:         leaq    "??_C@_06IBDBCMGJ@caught?$AA@"(%rip), %rcx
 ; CHECK:         callq   puts
 ; CHECK:         jmp     .LBB1_[[epilogue]]
@@ -143,18 +134,18 @@
 ; CHECK-NEXT:         .long   .Ltmp2@IMGREL+1
 ; CHECK-NEXT:         .long   .Ltmp3@IMGREL+1
 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
-; CHECK-NEXT:         .long   .LBB1_5@IMGREL
+; CHECK-NEXT:         .long   .LBB1_3@IMGREL
 ; CHECK-NEXT:         .long   .Ltmp6@IMGREL+1
 ; CHECK-NEXT:         .long   .Ltmp7@IMGREL+1
 ; CHECK-NEXT:         .long   "?filt$0@0@main@@"@IMGREL
-; CHECK-NEXT:         .long   .LBB1_5@IMGREL
+; CHECK-NEXT:         .long   .LBB1_3@IMGREL
 ; CHECK-NEXT: .Llsda_end0:
 
 ; CHECK:         .text
 ; CHECK:         .seh_endproc
 
-; CHECK: "?dtor$3@?0?main@4HA":
-; CHECK: .seh_proc "?dtor$3@?0?main@4HA"
+; CHECK: "?dtor$[[finbb]]@?0?main@4HA":
+; CHECK: .seh_proc "?dtor$[[finbb]]@?0?main@4HA"
 ; CHECK:         .seh_handler __C_specific_handler, @unwind, @except
 ; CHECK: .LBB1_[[finbb]]:                                # %ehcleanup
 ; CHECK:         movq    %rdx, 16(%rsp)
diff --git a/llvm/test/CodeGen/X86/seh-except-finally.ll b/llvm/test/CodeGen/X86/seh-except-finally.ll
index 7acb802..b252b5b 100644
--- a/llvm/test/CodeGen/X86/seh-except-finally.ll
+++ b/llvm/test/CodeGen/X86/seh-except-finally.ll
@@ -49,37 +49,24 @@
   br label %__try.cont
 
 __finally:                                             ; preds = %entry
-  %cleanuppad = cleanuppad []
+  %cleanuppad = cleanuppad within none []
   %locals = call i8* @llvm.localaddress()
   invoke void @"\01?fin$0@0@use_both@@"(i1 zeroext true, i8* %locals) #5
-          to label %invoke.cont3 unwind label %cleanupendpad
+          to label %invoke.cont3 unwind label %catch.dispatch
 
 invoke.cont3:                                     ; preds = %__finally
-  cleanupret %cleanuppad unwind label %catch.dispatch
-
-cleanupendpad:
-  cleanupendpad %cleanuppad unwind label %catch.dispatch
+  cleanupret from %cleanuppad unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %invoke.cont3, %lpad1
-  %catchpad = catchpad [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)]
-          to label %__except unwind label %catchendpad
+  %cs1 = catchswitch within none [label %__except] unwind to caller
 
 __except:                                         ; preds = %catch.dispatch
+  %catchpad = catchpad within %cs1 [i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_both@@" to i8*)]
   %call = call i32 @puts(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @"\01??_C@_08MLCMLGHM@__except?$AA@", i32 0, i32 0))
-  catchret %catchpad to label %__try.cont
-
-catchendpad:
-  catchendpad unwind to caller
+  catchret from %catchpad to label %__try.cont
 
 __try.cont:                                       ; preds = %__except, %invoke.cont2
   ret void
-
-eh.resume:                                        ; preds = %catch.dispatch
-  %exn = load i8*, i8** %exn.slot
-  %sel4 = load i32, i32* %ehselector.slot
-  %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn, 0
-  %lpad.val5 = insertvalue { i8*, i32 } %lpad.val, i32 %sel4, 1
-  resume { i8*, i32 } %lpad.val5
 }
 
 ; CHECK-LABEL: use_both:
diff --git a/llvm/test/CodeGen/X86/seh-exception-code.ll b/llvm/test/CodeGen/X86/seh-exception-code.ll
index e481a8e..20e1544 100644
--- a/llvm/test/CodeGen/X86/seh-exception-code.ll
+++ b/llvm/test/CodeGen/X86/seh-exception-code.ll
@@ -14,11 +14,11 @@
           to label %__try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %pad = catchpad [i8* null]
-          to label %__except unwind label %catchendblock
+  %cs = catchswitch within none [label %__except] unwind to caller
 
 __except:                                         ; preds = %catch.dispatch
-  catchret %pad to label %__except.1
+  %pad = catchpad within %cs [i8* null]
+  catchret from %pad to label %__except.1
 
 __except.1:                                       ; preds = %__except
   %code = call i32 @llvm.eh.exceptioncode(token %pad)
@@ -27,15 +27,12 @@
 
 __try.cont:                                       ; preds = %entry, %__except.1
   ret void
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
 }
 
 ; CHECK-LABEL: ehcode:
 ; CHECK: xorl %ecx, %ecx
 ; CHECK: callq f
 
-; CHECK: # %catch.dispatch
+; CHECK: # %__except
 ; CHECK: movl %eax, %ecx
 ; CHECK-NEXT: callq f
diff --git a/llvm/test/CodeGen/X86/seh-finally.ll b/llvm/test/CodeGen/X86/seh-finally.ll
index 57c2c8c..67bce81 100644
--- a/llvm/test/CodeGen/X86/seh-finally.ll
+++ b/llvm/test/CodeGen/X86/seh-finally.ll
@@ -17,15 +17,9 @@
   ret i32 0
 
 lpad:                                             ; preds = %entry
-  %p = cleanuppad []
-  %call2 = invoke i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0))
-          to label %invoke.cont1 unwind label %endpad
-
-invoke.cont1:                                     ; preds = %lpad
-  cleanupret %p unwind to caller
-
-endpad:                                   ; preds = %lpad
-  cleanupendpad %p unwind to caller
+  %p = cleanuppad within none []
+  %call2 = call i32 @puts(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @str_recovered, i64 0, i64 0))
+  cleanupret from %p unwind to caller
 }
 
 ; X64-LABEL: main:
diff --git a/llvm/test/CodeGen/X86/seh-safe-div-win32.ll b/llvm/test/CodeGen/X86/seh-safe-div-win32.ll
index 7f83b0c..3f88696 100644
--- a/llvm/test/CodeGen/X86/seh-safe-div-win32.ll
+++ b/llvm/test/CodeGen/X86/seh-safe-div-win32.ll
@@ -31,28 +31,22 @@
           to label %__try.cont unwind label %lpad0
 
 lpad0:
-  %p0 = catchpad [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)]
-          to label %handler0 unwind label %endpad0
+  %cs0 = catchswitch within none [label %handler0] unwind label %lpad1
 
 handler0:
+  %p0 = catchpad within %cs0 [i8* bitcast (i32 ()* @safe_div_filt0 to i8*)]
   call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0))
   store i32 -1, i32* %r, align 4
-  catchret %p0 to label %__try.cont
-
-endpad0:
-  catchendpad unwind label %lpad1
+  catchret from %p0 to label %__try.cont
 
 lpad1:
-  %p1 = catchpad [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)]
-          to label %handler1 unwind label %endpad1
+  %cs1 = catchswitch within none [label %handler1] unwind to caller
 
 handler1:
+  %p1 = catchpad within %cs1 [i8* bitcast (i32 ()* @safe_div_filt1 to i8*)]
   call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0))
   store i32 -2, i32* %r, align 4
-  catchret %p1 to label %__try.cont
-
-endpad1:
-  catchendpad unwind to caller
+  catchret from %p1 to label %__try.cont
 
 __try.cont:
   %safe_ret = load i32, i32* %r, align 4
@@ -71,13 +65,13 @@
 
 ; Landing pad code
 
-; CHECK: [[lpad0:LBB0_[0-9]+]]: # %lpad0
+; CHECK: [[handler0:LBB0_[0-9]+]]: # %handler0
 ; 	Restore SP
 ; CHECK: movl {{.*}}(%ebp), %esp
 ; CHECK: calll _puts
 ; CHECK: jmp [[cont_bb]]
 
-; CHECK: [[lpad1:LBB0_[0-9]+]]: # %lpad1
+; CHECK: [[handler1:LBB0_[0-9]+]]: # %handler1
 ; 	Restore SP
 ; CHECK: movl {{.*}}(%ebp), %esp
 ; CHECK: calll _puts
@@ -87,10 +81,10 @@
 ; CHECK: L__ehtable$safe_div:
 ; CHECK-NEXT: .long -1
 ; CHECK-NEXT: .long _safe_div_filt1
-; CHECK-NEXT: .long [[lpad1]]
+; CHECK-NEXT: .long [[handler1]]
 ; CHECK-NEXT: .long 0
 ; CHECK-NEXT: .long _safe_div_filt0
-; CHECK-NEXT: .long [[lpad0]]
+; CHECK-NEXT: .long [[handler0]]
 
 define void @try_body(i32* %r, i32* %n, i32* %d) {
 entry:
diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll
index 1c7318b..3eeeab0 100644
--- a/llvm/test/CodeGen/X86/seh-safe-div.ll
+++ b/llvm/test/CodeGen/X86/seh-safe-div.ll
@@ -30,28 +30,22 @@
           to label %__try.cont unwind label %lpad0
 
 lpad0:
-  %p0 = catchpad [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)]
-          to label %handler0 unwind label %endpad0
+  %cs0 = catchswitch within none [label %handler0] unwind label %lpad1
 
 handler0:
+  %p0 = catchpad within %cs0 [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt0 to i8*)]
   call void @puts(i8* getelementptr ([27 x i8], [27 x i8]* @str1, i32 0, i32 0))
   store i32 -1, i32* %r, align 4
-  catchret %p0 to label %__try.cont
-
-endpad0:
-  catchendpad unwind label %lpad1
+  catchret from %p0 to label %__try.cont
 
 lpad1:
-  %p1 = catchpad [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)]
-          to label %handler1 unwind label %endpad1
+  %cs1 = catchswitch within none [label %handler1] unwind to caller
 
 handler1:
+  %p1 = catchpad within %cs1 [i8* bitcast (i32 (i8*, i8*)* @safe_div_filt1 to i8*)]
   call void @puts(i8* getelementptr ([29 x i8], [29 x i8]* @str2, i32 0, i32 0))
   store i32 -2, i32* %r, align 4
-  catchret %p1 to label %__try.cont
-
-endpad1:
-  catchendpad unwind to caller
+  catchret from %p1 to label %__try.cont
 
 __try.cont:
   %safe_ret = load i32, i32* %r, align 4
@@ -73,12 +67,12 @@
 
 ; Landing pad code
 
-; CHECK: [[lpad0:\.LBB0_[0-9]+]]: # %lpad0
+; CHECK: [[handler0:\.LBB0_[0-9]+]]: # %handler0
 ; CHECK: callq puts
 ; CHECK: movl $-1, [[rloc]]
 ; CHECK: jmp [[cont_bb]]
 
-; CHECK: [[lpad1:\.LBB0_[0-9]+]]: # %lpad1
+; CHECK: [[handler1:\.LBB0_[0-9]+]]: # %handler1
 ; CHECK: callq puts
 ; CHECK: movl $-2, [[rloc]]
 ; CHECK: jmp [[cont_bb]]
@@ -89,11 +83,11 @@
 ; CHECK-NEXT: .long .Ltmp0@IMGREL+1
 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1
 ; CHECK-NEXT: .long safe_div_filt0@IMGREL
-; CHECK-NEXT: .long [[lpad0]]@IMGREL
+; CHECK-NEXT: .long [[handler0]]@IMGREL
 ; CHECK-NEXT: .long .Ltmp0@IMGREL+1
 ; CHECK-NEXT: .long .Ltmp1@IMGREL+1
 ; CHECK-NEXT: .long safe_div_filt1@IMGREL
-; CHECK-NEXT: .long [[lpad1]]@IMGREL
+; CHECK-NEXT: .long [[handler1]]@IMGREL
 ; CHECK-NEXT: .Llsda_end0:
 ; CHECK: .text
 ; CHECK: .seh_endproc
diff --git a/llvm/test/CodeGen/X86/seh-stack-realign.ll b/llvm/test/CodeGen/X86/seh-stack-realign.ll
index 8494cad..880533b 100644
--- a/llvm/test/CodeGen/X86/seh-stack-realign.ll
+++ b/llvm/test/CodeGen/X86/seh-stack-realign.ll
@@ -23,16 +23,13 @@
           to label %__try.cont unwind label %lpad
 
 lpad:                                             ; preds = %entry
-  %p = catchpad [i8* bitcast (i32 ()* @"filt$main" to i8*)]
-          to label %__except unwind label %endpad
+  %cs1 = catchswitch within none [label %__except] unwind to caller
 
 __except:                                         ; preds = %lpad
+  %p = catchpad within %cs1 [i8* bitcast (i32 ()* @"filt$main" to i8*)]
   %code = load i32, i32* %__exceptioncode, align 4
   %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @str, i32 0, i32 0), i32 %code) #4
-  catchret %p to label %__try.cont
-
-endpad:
-  catchendpad unwind to caller
+  catchret from %p to label %__try.cont
 
 __try.cont:                                       ; preds = %entry, %__except
   ret i32 0
@@ -63,7 +60,7 @@
 ; CHECK: movl $0, 40(%esi)
 ; CHECK: calll _crash
 ; CHECK: retl
-; CHECK: LBB0_[[lpbb:[0-9]+]]: # %lpad
+; CHECK: LBB0_[[lpbb:[0-9]+]]: # %__except
 ;       Restore ESP
 ; CHECK: movl -24(%ebp), %esp
 ;       Restore ESI
diff --git a/llvm/test/CodeGen/X86/tail-dup-catchret.ll b/llvm/test/CodeGen/X86/tail-dup-catchret.ll
index 18682fb..3eeb24d 100644
--- a/llvm/test/CodeGen/X86/tail-dup-catchret.ll
+++ b/llvm/test/CodeGen/X86/tail-dup-catchret.ll
@@ -8,19 +8,16 @@
           to label %try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
-  catchret %0 to label %try.cont
+  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]
+  catchret from %0 to label %try.cont
 
 try.cont:                                         ; preds = %entry, %catch
   %b.0 = phi i1 [ false, %catch ], [ true, %entry ]
   tail call void @h(i1 zeroext %b.0)
   ret void
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
 }
 
 ; CHECK-LABEL: _f:
diff --git a/llvm/test/CodeGen/X86/tail-merge-wineh.ll b/llvm/test/CodeGen/X86/tail-merge-wineh.ll
index d0f6b72..69c2fda 100644
--- a/llvm/test/CodeGen/X86/tail-merge-wineh.ll
+++ b/llvm/test/CodeGen/X86/tail-merge-wineh.ll
@@ -54,11 +54,11 @@
           to label %unreachable unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %1 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind label %catch.dispatch.7
 
 catch:                                            ; preds = %catch.dispatch
-  catchret %1 to label %catchret.dest
+  %1 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  catchret from %1 to label %catchret.dest
 
 catchret.dest:                                    ; preds = %catch
   br label %try.cont
@@ -70,11 +70,11 @@
           to label %unreachable unwind label %catch.dispatch.2
 
 catch.dispatch.2:                                 ; preds = %try.cont
-  %3 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch.4 unwind label %catchendblock.3
+  %cs2 = catchswitch within none [label %catch.4] unwind label %catch.dispatch.7
 
 catch.4:                                          ; preds = %catch.dispatch.2
-  catchret %3 to label %catchret.dest.5
+  %3 = catchpad within %cs2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  catchret from %3 to label %catchret.dest.5
 
 catchret.dest.5:                                  ; preds = %catch.4
   br label %try.cont.6
@@ -82,15 +82,12 @@
 try.cont.6:                                       ; preds = %catchret.dest.5
   br label %try.cont.11
 
-catchendblock.3:                                  ; preds = %catch.dispatch.2
-  catchendpad unwind label %catch.dispatch.7
-
-catch.dispatch.7:                                 ; preds = %catchendblock.3, %catchendblock
-  %4 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch.9 unwind label %catchendblock.8
+catch.dispatch.7:
+  %cs3 = catchswitch within none [label %catch.9] unwind to caller
 
 catch.9:                                          ; preds = %catch.dispatch.7
-  catchret %4 to label %catchret.dest.10
+  %4 = catchpad within %cs3 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  catchret from %4 to label %catchret.dest.10
 
 catchret.dest.10:                                 ; preds = %catch.9
   br label %try.cont.11
@@ -98,12 +95,6 @@
 try.cont.11:                                      ; preds = %catchret.dest.10, %try.cont.6
   ret void
 
-catchendblock.8:                                  ; preds = %catch.dispatch.7
-  catchendpad unwind to caller
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind label %catch.dispatch.7
-
 unreachable:                                      ; preds = %try.cont, %entry
   unreachable
 }
diff --git a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
index b6b4a93..9f7a495 100644
--- a/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad-csrs.ll
@@ -16,7 +16,7 @@
 declare void @f(i32 %p)
 declare i32 @__CxxFrameHandler3(...)
 
-define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+define i32 @try_catch_catch() personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   %a = call i32 @getint()
   %b = call i32 @getint()
@@ -26,22 +26,16 @@
   invoke void @f(i32 1)
           to label %try.cont unwind label %catch.dispatch
 
-catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch unwind label %catchendblock
-
-catch:
-  invoke void @f(i32 2)
-          to label %invoke.cont.2 unwind label %catchendblock
-
-invoke.cont.2:                                    ; preds = %catch
-  catchret %0 to label %try.cont
-
-try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3
+try.cont:
   ret i32 0
 
-catchendblock:                                    ; preds = %catch,
-  catchendpad unwind to caller
+catch.dispatch:
+  %cs = catchswitch within none [label %handler1] unwind to caller
+
+handler1:
+  %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  call void @f(i32 2)
+  catchret from %h1 to label %try.cont
 }
 
 ; X86-LABEL: _try_catch_catch:
@@ -71,7 +65,7 @@
 ; X86: jmp [[contbb]]
 
 ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
-; X86: LBB0_[[catch1bb]]: # %catch.dispatch{{$}}
+; X86: LBB0_[[catch1bb]]: # %handler1{{$}}
 ; X86: pushl %ebp
 ; X86-NOT: pushl
 ; X86: subl $16, %esp
@@ -120,7 +114,7 @@
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
-; X64: LBB0_[[catch1bb]]: # %catch.dispatch{{$}}
+; X64: LBB0_[[catch1bb]]: # %handler1{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
@@ -159,18 +153,15 @@
   invoke void @f(i32 1)
           to label %try.cont unwind label %catch.dispatch
 
-catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch unwind label %catchendblock
+catch.dispatch:
+  %cs = catchswitch within none [label %handler1] unwind to caller
 
-catch:
-  catchret %0 to label %try.cont
+handler1:
+  %0 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  catchret from %0 to label %try.cont
 
-try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3
+try.cont:
   ret i32 0
-
-catchendblock:                                    ; preds = %catch,
-  catchendpad unwind to caller
 }
 
 ; X64-LABEL: try_one_csr:
@@ -198,7 +189,7 @@
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_one_csr@4HA":
-; X64: LBB1_[[catch1bb]]: # %catch.dispatch{{$}}
+; X64: LBB1_[[catch1bb]]: # %handler1{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
@@ -226,18 +217,15 @@
   invoke void @f(i32 1)
           to label %try.cont unwind label %catch.dispatch
 
-catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-          to label %catch unwind label %catchendblock
+catch.dispatch:
+  %cs = catchswitch within none [label %handler1] unwind to caller
 
-catch:
-  catchret %0 to label %try.cont
+handler1:
+  %cp1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  catchret from %cp1 to label %try.cont
 
-try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3
+try.cont:
   ret i32 0
-
-catchendblock:                                    ; preds = %catch,
-  catchendpad unwind to caller
 }
 
 ; X64-LABEL: try_no_csr:
@@ -259,7 +247,7 @@
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_no_csr@4HA":
-; X64: LBB2_[[catch1bb]]: # %catch.dispatch{{$}}
+; X64: LBB2_[[catch1bb]]: # %handler1{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
diff --git a/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll b/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll
new file mode 100644
index 0000000..22ce7e5
--- /dev/null
+++ b/llvm/test/CodeGen/X86/win-catchpad-nested-cxx.ll
@@ -0,0 +1,105 @@
+; RUN: llc -verify-machineinstrs -mtriple=i686-pc-windows-msvc < %s \
+; RUN:     | FileCheck --check-prefix=CHECK --check-prefix=X86 %s
+; RUN: llc -verify-machineinstrs -mtriple=x86_64-pc-windows-msvc < %s \
+; RUN:     | FileCheck --check-prefix=CHECK --check-prefix=X64 %s
+
+; Loosely based on IR for this C++ source code:
+;   void f(int p);
+;   void try_in_catch() {
+;     try {
+;       f(1);
+;     } catch (...) {
+;       try {
+;         f(2);
+;       } catch (...) {
+;         f(3);
+;       }
+;     }
+;   }
+
+declare void @f(i32 %p)
+declare i32 @__CxxFrameHandler3(...)
+
+define i32 @try_in_catch() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  invoke void @f(i32 1)
+          to label %try.cont unwind label %catch.dispatch.1
+try.cont:
+  ret i32 0
+
+catch.dispatch.1:
+  %cs1 = catchswitch within none [label %handler1] unwind to caller
+handler1:
+  %h1 = catchpad within %cs1 [i8* null, i32 64, i8* null]
+  invoke void @f(i32 2)
+          to label %catchret1 unwind label %catch.dispatch.2
+catchret1:
+  catchret from %h1 to label %try.cont
+
+catch.dispatch.2:
+  %cs2 = catchswitch within %h1 [label %handler2] unwind to caller
+handler2:
+  %h2 = catchpad within %cs2 [i8* null, i32 64, i8* null]
+  call void @f(i32 3)
+  catchret from %h2 to label %catchret1
+}
+
+; X86-LABEL: L__ehtable$try_in_catch:
+; X64-LABEL: $cppxdata$try_in_catch:
+; CHECK-NEXT: .long   429065506
+; CHECK-NEXT: .long   4
+; CHECK-NEXT: .long   ($stateUnwindMap$try_in_catch)
+; CHECK-NEXT: .long   2
+; CHECK-NEXT: .long   ($tryMap$try_in_catch)
+; ip2state num + ptr
+; X86-NEXT: .long   0
+; X86-NEXT: .long   0
+; X64-NEXT: .long   7
+; X64-NEXT: .long   ($ip2state$try_in_catch)
+; unwindhelp offset
+; X64-NEXT: .long   40
+; CHECK-NEXT: .long   0
+; EHFlags
+; CHECK-NEXT: .long   1
+
+; CHECK: $tryMap$try_in_catch:
+; CHECK-NEXT: .long   2
+; CHECK-NEXT: .long   2
+; CHECK-NEXT: .long   3
+; CHECK-NEXT: .long   1
+; CHECK-NEXT: .long   ($handlerMap$0$try_in_catch)
+; CHECK-NEXT: .long   0
+; CHECK-NEXT: .long   0
+; CHECK-NEXT: .long   3
+; CHECK-NEXT: .long   1
+; CHECK-NEXT: .long   ($handlerMap$1$try_in_catch)
+
+; CHECK: $handlerMap$0$try_in_catch:
+; CHECK-NEXT:   .long   64
+; CHECK-NEXT:   .long   0
+; CHECK-NEXT:   .long   0
+; CHECK-NEXT:   .long   "?catch${{[0-9]+}}@?0?try_in_catch@4HA"
+; X64-NEXT:   .long   56
+
+; CHECK: $handlerMap$1$try_in_catch:
+; CHECK-NEXT:   .long   64
+; CHECK-NEXT:   .long   0
+; CHECK-NEXT:   .long   0
+; CHECK-NEXT:   .long   "?catch${{[0-9]+}}@?0?try_in_catch@4HA"
+; X64-NEXT:   .long   56
+
+; X64: $ip2state$try_in_catch:
+; X64-NEXT: .long   .Lfunc_begin0@IMGREL
+; X64-NEXT: .long   -1
+; X64-NEXT: .long   .Ltmp0@IMGREL+1
+; X64-NEXT: .long   0
+; X64-NEXT: .long   .Ltmp1@IMGREL+1
+; X64-NEXT: .long   -1
+; X64-NEXT: .long   "?catch$2@?0?try_in_catch@4HA"@IMGREL
+; X64-NEXT: .long   1
+; X64-NEXT: .long   .Ltmp2@IMGREL+1
+; X64-NEXT: .long   2
+; X64-NEXT: .long   .Ltmp3@IMGREL+1
+; X64-NEXT: .long   1
+; X64-NEXT: .long   "?catch$4@?0?try_in_catch@4HA"@IMGREL
+; X64-NEXT: .long   3
diff --git a/llvm/test/CodeGen/X86/win-catchpad-nested.ll b/llvm/test/CodeGen/X86/win-catchpad-nested.ll
index 25adfdf..d20f9f6 100644
--- a/llvm/test/CodeGen/X86/win-catchpad-nested.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad-nested.ll
@@ -7,26 +7,25 @@
 define void @test1() personality void ()* @ProcessCLRException {
 entry:
   invoke void @f()
-          to label %exit unwind label %outer.pad
-outer.pad:
-  %outer = catchpad [i32 1]
-          to label %outer.catch unwind label %outer.end
-outer.catch:
-  invoke void @f()
-          to label %outer.ret unwind label %inner.pad
-inner.pad:
-  %inner = catchpad [i32 2]
-          to label %inner.ret unwind label %inner.end
-inner.ret:
-  catchret %inner to label %outer.ret
-inner.end:
-  catchendpad unwind label %outer.end
-outer.ret:
-  catchret %outer to label %exit
-outer.end:
-  catchendpad unwind to caller
+          to label %exit unwind label %catch.dispatch.1
 exit:
   ret void
+
+catch.dispatch.1:
+  %cs1 = catchswitch within none [label %outer.catch] unwind to caller
+
+outer.catch:
+  %cp1 = catchpad within %cs1 [i32 1]
+  invoke void @f()
+          to label %outer.ret unwind label %catch.dispatch.2
+outer.ret:
+  catchret from %cp1 to label %exit
+
+catch.dispatch.2:
+  %cs2 = catchswitch within %cp1 [label %inner.catch] unwind to caller
+inner.catch:
+  %cp2 = catchpad within %cs2 [i32 2]
+  catchret from %cp2 to label %outer.ret
 }
 
 ; Check the catchret targets
@@ -37,7 +36,7 @@
 ; CHECK-NEXT:                  # %outer.ret
 ; CHECK-NEXT: leaq [[Exit]](%rip), %rax
 ; CHECK:      retq   # CATCHRET
-; CHECK: {{^[^: ]+}}: # %inner.pad
+; CHECK: {{^[^: ]+}}: # %inner.catch
 ; CHECK: .seh_endprolog
 ; CHECK-NEXT: leaq [[OuterRet]](%rip), %rax
 ; CHECK:      retq   # CATCHRET
diff --git a/llvm/test/CodeGen/X86/win-catchpad-varargs.ll b/llvm/test/CodeGen/X86/win-catchpad-varargs.ll
index a2988a3..6508f3b 100644
--- a/llvm/test/CodeGen/X86/win-catchpad-varargs.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad-varargs.ll
@@ -13,20 +13,17 @@
           to label %return unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:                                            ; preds = %catch.dispatch
+  %0 = catchpad within %cs1 [i8* null, i32 64, i8* null]
   %ap1 = bitcast i8** %ap to i8*
   call void @llvm.va_start(i8* %ap1)
   %argp.cur = load i8*, i8** %ap
   %1 = bitcast i8* %argp.cur to i32*
   %arg2 = load i32, i32* %1
   call void @llvm.va_end(i8* %ap1)
-  catchret %0 to label %return
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
+  catchret from %0 to label %return
 
 return:                                           ; preds = %entry, %catch
   %retval.0 = phi i32 [ %arg2, %catch ], [ -1, %entry ]
diff --git a/llvm/test/CodeGen/X86/win-catchpad.ll b/llvm/test/CodeGen/X86/win-catchpad.ll
index d9c8307..5bd2504 100644
--- a/llvm/test/CodeGen/X86/win-catchpad.ll
+++ b/llvm/test/CodeGen/X86/win-catchpad.ll
@@ -28,7 +28,7 @@
 declare i1 @getbool()
 declare i32 @__CxxFrameHandler3(...)
 
-define i32 @try_catch_catch() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+define i32 @try_catch_catch() personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   %e.addr = alloca i32
   %local = alloca i32
@@ -36,33 +36,21 @@
           to label %try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e.addr]
-          to label %catch unwind label %catch.dispatch.2
+  %cs = catchswitch within none [label %handler1, label %handler2] unwind to caller
 
-catch:                                            ; preds = %catch.dispatch
+handler1:
+  %h1 = catchpad within %cs [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e.addr]
   %e = load i32, i32* %e.addr
-  invoke void @f(i32 %e, i32* %local)
-          to label %invoke.cont.2 unwind label %catchendblock
+  call void @f(i32 %e, i32* %local)
+  catchret from %h1 to label %try.cont
 
-invoke.cont.2:                                    ; preds = %catch
-  catchret %0 to label %try.cont
+handler2:
+  %h2 = catchpad within %cs [i8* null, i32 64, i8* null]
+  call void @f(i32 3, i32* %local)
+  catchret from %h2 to label %try.cont
 
-catch.dispatch.2:                                   ; preds = %catch.dispatch
-  %1 = catchpad [i8* null, i32 u0x40, i8* null]
-          to label %catch.2 unwind label %catchendblock
-
-catch.2:                                            ; preds = %catch.dispatch.2
-  invoke void @f(i32 3, i32* %local)
-          to label %invoke.cont.3 unwind label %catchendblock
-
-invoke.cont.3:                                    ; preds = %catch.2
-  catchret %1 to label %try.cont
-
-try.cont:                                         ; preds = %entry, %invoke.cont.2, %invoke.cont.3
+try.cont:
   ret i32 0
-
-catchendblock:                                    ; preds = %catch, %catch.2, %catch.dispatch.2
-  catchendpad unwind to caller
 }
 
 ; X86-LABEL: _try_catch_catch:
@@ -76,25 +64,25 @@
 ; X86: retl
 
 ; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken
-; X86-NEXT:                        # %invoke.cont.2
+; X86-NEXT:                        # %handler1
 ; X86-NEXT: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
 ; FIXME: These should be de-duplicated.
 ; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken
-; X86-NEXT:                        # %invoke.cont.3
+; X86-NEXT:                        # %handler2
 ; X86-NEXT: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
 ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
-; X86: LBB0_[[catch1bb]]: # %catch.dispatch{{$}}
+; X86: LBB0_[[catch1bb]]: # %handler1{{$}}
 ; X86: pushl %ebp
 ; X86: subl $8, %esp
 ; X86: addl $12, %ebp
 ; X86: movl %esp, -[[sp_offset]](%ebp)
-; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
-; X86: movl -32(%ebp), %[[e_reg:[a-z]+]]
-; X86: movl $1, -{{[0-9]+}}(%ebp)
+; X86-DAG: movl -32(%ebp), %[[e_reg:[a-z]+]]
+; X86-DAG: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
+; X86-DAG: movl $1, -{{[0-9]+}}(%ebp)
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)
 ; X86-DAG: movl %[[e_reg]], (%esp)
 ; X86: calll _f
@@ -104,13 +92,13 @@
 ; X86-NEXT: retl
 
 ; X86: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA":
-; X86: LBB0_[[catch2bb]]: # %catch.dispatch.2{{$}}
+; X86: LBB0_[[catch2bb]]: # %handler2{{$}}
 ; X86: pushl %ebp
 ; X86: subl $8, %esp
 ; X86: addl $12, %ebp
 ; X86: movl %esp, -[[sp_offset]](%ebp)
-; X86: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
-; X86: movl $1, -{{[0-9]+}}(%ebp)
+; X86-DAG: leal -[[local_offs]](%ebp), %[[addr_reg:[a-z]+]]
+; X86-DAG: movl $1, -{{[0-9]+}}(%ebp)
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)
 ; X86-DAG: movl $3, (%esp)
 ; X86: calll _f
@@ -151,7 +139,7 @@
 ; X64: retq
 
 ; X64: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA":
-; X64: LBB0_[[catch1bb]]: # %catch.dispatch{{$}}
+; X64: LBB0_[[catch1bb]]: # %handler1{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
@@ -159,7 +147,6 @@
 ; X64: .seh_stackalloc 32
 ; X64: leaq 48(%rdx), %rbp
 ; X64: .seh_endprologue
-; X64-DAG: .Ltmp4
 ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
 ; X64-DAG: movl -12(%rbp), %ecx
 ; X64: callq f
@@ -169,7 +156,7 @@
 ; X64-NEXT: retq
 
 ; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch@4HA":
-; X64: LBB0_[[catch2bb]]: # %catch.dispatch.2{{$}}
+; X64: LBB0_[[catch2bb]]: # %handler2{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
@@ -180,7 +167,6 @@
 ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
 ; X64-DAG: movl $3, %ecx
 ; X64: callq f
-; X64: .Ltmp3
 ; X64: leaq [[contbb]](%rip), %rax
 ; X64-NEXT: addq $32, %rsp
 ; X64-NEXT: popq %rbp
@@ -192,7 +178,7 @@
 ; X64-NEXT: .long   ($stateUnwindMap$try_catch_catch)@IMGREL
 ; X64-NEXT: .long   1
 ; X64-NEXT: .long   ($tryMap$try_catch_catch)@IMGREL
-; X64-NEXT: .long   4
+; X64-NEXT: .long   5
 ; X64-NEXT: .long   ($ip2state$try_catch_catch)@IMGREL
 ; X64-NEXT: .long   40
 ; X64-NEXT: .long   0
@@ -222,33 +208,35 @@
 ; X64-NEXT: .long   -1
 ; X64-NEXT: .long   .Ltmp0@IMGREL+1
 ; X64-NEXT: .long   0
-; X64-NEXT: .long   .Ltmp4@IMGREL+1
-; X64-NEXT: .long   1
-; X64-NEXT: .long   .Ltmp3@IMGREL+1
+; X64-NEXT: .long   .Ltmp1@IMGREL+1
 ; X64-NEXT: .long   -1
+; X64-NEXT: .long   "?catch$[[catch1bb]]@?0?try_catch_catch@4HA"@IMGREL
+; X64-NEXT: .long   1
+; X64-NEXT: .long   "?catch$[[catch2bb]]@?0?try_catch_catch@4HA"@IMGREL
+; X64-NEXT: .long   1
 
 
-define i32 @branch_to_normal_dest() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
+define i32 @branch_to_normal_dest() personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   invoke void @f(i32 1, i32* null)
           to label %try.cont unwind label %catch.dispatch
 
 catch.dispatch:
-  %0 = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:
+  %cp1 = catchpad within %cs1 [i8* null, i32 64, i8* null]
+  br label %loop
+
+loop:
   %V = call i1 @getbool()
-  br i1 %V, label %catch, label %catch.done
+  br i1 %V, label %loop, label %catch.done
 
 catch.done:
-  catchret %0 to label %try.cont
+  catchret from %cp1 to label %try.cont
 
 try.cont:
   ret i32 0
-
-catchendblock:
-  catchendpad unwind to caller
 }
 
 ; X86-LABEL: _branch_to_normal_dest:
@@ -262,17 +250,16 @@
 ; X86-NEXT: addl $12, %ebp
 ; X86: jmp [[contbb]]
 
-; X86: "?catch$[[catchdispbb:[0-9]+]]@?0?branch_to_normal_dest@4HA":
-; X86: LBB1_[[catchdispbb]]: # %catch.dispatch{{$}}
+; X86: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest@4HA":
+; X86: LBB1_[[catchbb]]: # %catch{{$}}
 ; X86: pushl %ebp
 ; X86: subl $8, %esp
 ; X86: addl $12, %ebp
-
-; X86: LBB1_[[catchbb:[0-9]+]]: # %catch
-; X86: movl    $-1, -16(%ebp)
+; X86: LBB1_[[loopbb:[0-9]+]]: # %loop
+; X86: movl    $1, -16(%ebp)
 ; X86: calll   _getbool
 ; X86: testb   $1, %al
-; X86: jne LBB1_[[catchbb]]
+; X86: jne LBB1_[[loopbb]]
 ; X86: # %catch.done
 ; X86-NEXT: movl $[[restorebb]], %eax
 ; X86-NEXT: addl $8, %esp
@@ -284,7 +271,7 @@
 ; X86-NEXT:   .long   64
 ; X86-NEXT:   .long   0
 ; X86-NEXT:   .long   0
-; X86-NEXT:   .long   "?catch$[[catchdispbb]]@?0?branch_to_normal_dest@4HA"
+; X86-NEXT:   .long   "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"
 
 ; X64-LABEL: branch_to_normal_dest:
 ; X64: # %entry
@@ -305,7 +292,7 @@
 ; X64: retq
 
 ; X64: "?catch$[[catchbb:[0-9]+]]@?0?branch_to_normal_dest@4HA":
-; X64: LBB1_[[catchbb]]: # %catch.dispatch{{$}}
+; X64: LBB1_[[catchbb]]: # %catch{{$}}
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
@@ -313,7 +300,7 @@
 ; X64: .seh_stackalloc 32
 ; X64: leaq 48(%rdx), %rbp
 ; X64: .seh_endprologue
-; X64: .LBB1_[[normal_dest_bb:[0-9]+]]: # %catch
+; X64: .LBB1_[[normal_dest_bb:[0-9]+]]: # %loop
 ; X64: callq   getbool
 ; X64: testb   $1, %al
 ; X64: jne     .LBB1_[[normal_dest_bb]]
@@ -329,7 +316,7 @@
 ; X64-NEXT: .long   ($stateUnwindMap$branch_to_normal_dest)@IMGREL
 ; X64-NEXT: .long   1
 ; X64-NEXT: .long   ($tryMap$branch_to_normal_dest)@IMGREL
-; X64-NEXT: .long   3
+; X64-NEXT: .long   4
 ; X64-NEXT: .long   ($ip2state$branch_to_normal_dest)@IMGREL
 ; X64-NEXT: .long   40
 ; X64-NEXT: .long   0
@@ -362,3 +349,5 @@
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   .Ltmp[[after_call]]@IMGREL+1
 ; X64-NEXT: .long   -1
+; X64-NEXT: .long   "?catch$[[catchbb]]@?0?branch_to_normal_dest@4HA"@IMGREL
+; X64-NEXT: .long   1
diff --git a/llvm/test/CodeGen/X86/win-cleanuppad.ll b/llvm/test/CodeGen/X86/win-cleanuppad.ll
index 27bb6e2..37090c2 100644
--- a/llvm/test/CodeGen/X86/win-cleanuppad.ll
+++ b/llvm/test/CodeGen/X86/win-cleanuppad.ll
@@ -14,9 +14,9 @@
   ret void
 
 ehcleanup:                                        ; preds = %entry
-  %0 = cleanuppad []
+  %0 = cleanuppad within none []
   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o) #2
-  cleanupret %0 unwind to caller
+  cleanupret from %0 unwind to caller
 }
 
 ; CHECK: simple_cleanup:                         # @simple_cleanup
@@ -77,14 +77,14 @@
   ret void
 
 cleanup.inner:                                        ; preds = %invoke.cont
-  %0 = cleanuppad []
+  %0 = cleanuppad within none []
   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o2) #2
-  cleanupret %0 unwind label %cleanup.outer
+  cleanupret from %0 unwind label %cleanup.outer
 
 cleanup.outer:                                      ; preds = %invoke.cont.1, %cleanup.inner, %entry
-  %1 = cleanuppad []
+  %1 = cleanuppad within none []
   call x86_thiscallcc void @"\01??1Dtor@@QAE@XZ"(%struct.Dtor* %o1) #2
-  cleanupret %1 unwind to caller
+  cleanupret from %1 unwind to caller
 }
 
 ; X86-LABEL: _nested_cleanup:
diff --git a/llvm/test/CodeGen/X86/win-funclet-cfi.ll b/llvm/test/CodeGen/X86/win-funclet-cfi.ll
index 52589ee..95afa75 100644
--- a/llvm/test/CodeGen/X86/win-funclet-cfi.ll
+++ b/llvm/test/CodeGen/X86/win-funclet-cfi.ll
@@ -9,24 +9,21 @@
           to label %unreachable unwind label %cleanupblock
 
 cleanupblock:
-  %cleanp = cleanuppad []
+  %cleanp = cleanuppad within none []
   call void @g()
-  cleanupret %cleanp unwind label %catch.dispatch
+  cleanupret from %cleanp unwind label %catch.dispatch
 
 catch.dispatch:
-  %cp = catchpad [i8* null, i32 64, i8* null]
-          to label %catch unwind label %catchendblock
+  %cs1 = catchswitch within none [label %catch] unwind to caller
 
 catch:
+  %cp = catchpad within %cs1 [i8* null, i32 64, i8* null]
   call void @g()
-  catchret %cp to label %try.cont
+  catchret from %cp to label %try.cont
 
 try.cont:
   ret void
 
-catchendblock:
-  catchendpad unwind to caller
-
 unreachable:
   unreachable
 }
@@ -70,7 +67,7 @@
 ; CHECK: "?catch$[[catch:[0-9]+]]@?0??f@@YAXXZ@4HA":
 ; CHECK: .seh_proc "?catch$[[catch]]@?0??f@@YAXXZ@4HA"
 ; CHECK-NEXT: .seh_handler __CxxFrameHandler3, @unwind, @except
-; CHECK: LBB0_[[catch]]: # %catch.dispatch{{$}}
+; CHECK: LBB0_[[catch]]: # %catch{{$}}
 
 ; Emit CFI for pushing RBP.
 ; CHECK: movq    %rdx, 16(%rsp)
diff --git a/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll b/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll
index 9b69165..f7b6d07 100644
--- a/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll
+++ b/llvm/test/CodeGen/X86/win-mixed-ehpersonality.ll
@@ -18,12 +18,10 @@
   ret i32 0
 
 lpad:
-  %p = catchpad [i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*)]
-      to label %catch unwind label %endpad
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchret %p to label %ret1
-endpad:
-  catchendpad unwind to caller
+  %p = catchpad within %cs [i8* bitcast (i32 (i8*, i8*)* @filt_g to i8*)]
+  catchret from %p to label %ret1
 
 ret1:
   ret i32 1
@@ -39,7 +37,7 @@
 ; CHECK: xorl %eax, %eax
 ; CHECK: .LBB0_[[epilogue:[0-9]+]]
 ; CHECK: retq
-; CHECK: # %lpad
+; CHECK: # %catch{{$}}
 ; CHECK: movl $1, %eax
 ; CHECK: jmp .LBB0_[[epilogue]]
 
diff --git a/llvm/test/CodeGen/X86/win32-eh-states.ll b/llvm/test/CodeGen/X86/win32-eh-states.ll
index cb7b053..fe3639b 100644
--- a/llvm/test/CodeGen/X86/win32-eh-states.ll
+++ b/llvm/test/CodeGen/X86/win32-eh-states.ll
@@ -1,4 +1,5 @@
-; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck %s
+; RUN: llc -mtriple=i686-pc-windows-msvc   < %s | FileCheck %s --check-prefix=X86
+; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s --check-prefix=X64
 
 ; Based on this source:
 ; extern "C" void may_throw(int);
@@ -40,59 +41,167 @@
           to label %try.cont.9 unwind label %lpad
 
 try.cont.9:                                       ; preds = %invoke.cont.3, %invoke.cont, %catch.7
-  ; FIXME: Something about our CFG breaks TailDuplication. This empy asm blocks
-  ; it so we can focus on testing the state numbering.
-  call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"()
   ret void
 
 lpad:                                             ; preds = %catch, %entry
-  %p1 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-      to label %catch unwind label %end.inner.catch
+  %cs1 = catchswitch within none [label %catch] unwind label %lpad.1
 
 catch:                                            ; preds = %lpad.1
+  %p1 = catchpad within %cs1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
   invoke void @may_throw(i32 3)
-          to label %invoke.cont.3 unwind label %end.inner.catch
+          to label %invoke.cont.3 unwind label %lpad.1
 
 invoke.cont.3:                                    ; preds = %catch
-  catchret %p1 to label %try.cont.9
-
-
-end.inner.catch:
-  catchendpad unwind label %lpad.1
+  catchret from %p1 to label %try.cont.9
 
 lpad.1:                                           ; preds = %invoke.cont
-  %p2 = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
-      to label %catch.7 unwind label %eh.resume
+  %cs2 = catchswitch within none [label %catch.7] unwind to caller
 
 catch.7:
-  invoke void @may_throw(i32 4)
-          to label %invoke.cont.10 unwind label %eh.resume
-
-invoke.cont.10:
-  catchret %p2 to label %try.cont.9
-
-eh.resume:                                        ; preds = %catch.dispatch.4
-  catchendpad unwind to caller
+  %p2 = catchpad within %cs2 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i8* null]
+  call void @may_throw(i32 4)
+  catchret from %p2 to label %try.cont.9
 }
 
-; CHECK-LABEL: _f:
-; CHECK: movl $-1, [[state:[-0-9]+]](%ebp)
-; CHECK: movl $___ehhandler$f, {{.*}}
+; X86-LABEL: _f:
+; X86: movl $-1, [[state:[-0-9]+]](%ebp)
+; X86: movl $___ehhandler$f, {{.*}}
 ;
-; CHECK: movl $0, [[state]](%ebp)
-; CHECK: movl $1, (%esp)
-; CHECK: calll _may_throw
+; X86: movl $0, [[state]](%ebp)
+; X86: movl $1, (%esp)
+; X86: calll _may_throw
 ;
-; CHECK: movl $1, [[state]](%ebp)
-; CHECK: movl $2, (%esp)
-; CHECK: calll _may_throw
+; X86: movl $1, [[state]](%ebp)
+; X86: movl $2, (%esp)
+; X86: calll _may_throw
 ;
-; CHECK: movl $2, [[state]](%ebp)
-; CHECK: movl $3, (%esp)
-; CHECK: calll _may_throw
+; X86: movl $2, [[state]](%ebp)
+; X86: movl $3, (%esp)
+; X86: calll _may_throw
 ;
-; CHECK: movl $3, [[state]](%ebp)
-; CHECK: movl $4, (%esp)
-; CHECK: calll _may_throw
+; X86: movl $3, [[state]](%ebp)
+; X86: movl $4, (%esp)
+; X86: calll _may_throw
 
-; CHECK: .safeseh ___ehhandler$f
+
+; X64-LABEL: f:
+; X64-LABEL: $ip2state$f:
+; X64-NEXT:   .long .Lfunc_begin0@IMGREL
+; X64-NEXT:   .long -1
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long 0
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long 1
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long -1
+; X64-NEXT:   .long "?catch${{.*}}@?0?f@4HA"@IMGREL
+; X64-NEXT:   .long 2
+; X64-NEXT:   .long "?catch${{.*}}@?0?f@4HA"@IMGREL
+; X64-NEXT:   .long 3
+
+; Based on this source:
+; extern "C" void may_throw(int);
+; struct S { ~S(); };
+; void g() {
+;   S x;
+;   try {
+;     may_throw(-1);
+;   } catch (...) {
+;     may_throw(0);
+;     {
+;       S y;
+;       may_throw(1);
+;     }
+;     may_throw(2);
+;   }
+; }
+
+%struct.S = type { i8 }
+declare void @"\01??1S@@QEAA@XZ"(%struct.S*)
+
+define void @g() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  %x = alloca %struct.S, align 1
+  %y = alloca %struct.S, align 1
+  invoke void @may_throw(i32 -1)
+          to label %unreachable unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %catch] unwind label %ehcleanup5
+
+catch:                                            ; preds = %catch.dispatch
+  %1 = catchpad within %0 [i8* null, i32 64, i8* null]
+  invoke void @may_throw(i32 0)
+          to label %invoke.cont unwind label %ehcleanup5
+
+invoke.cont:                                      ; preds = %catch
+  invoke void @may_throw(i32 1)
+          to label %invoke.cont2 unwind label %ehcleanup
+
+invoke.cont2:                                     ; preds = %invoke.cont
+  invoke void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y)
+          to label %invoke.cont3 unwind label %ehcleanup5
+
+invoke.cont3:                                     ; preds = %invoke.cont2
+  invoke void @may_throw(i32 2)
+          to label %invoke.cont4 unwind label %ehcleanup5
+
+invoke.cont4:                                     ; preds = %invoke.cont3
+  catchret from %1 to label %try.cont
+
+try.cont:                                         ; preds = %invoke.cont4
+  call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x)
+  ret void
+
+ehcleanup:                                        ; preds = %invoke.cont
+  %2 = cleanuppad within %1 []
+  call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %y)
+  cleanupret from %2 unwind label %ehcleanup5
+
+ehcleanup5:                                       ; preds = %invoke.cont2, %invoke.cont3, %ehcleanup, %catch, %catch.dispatch
+  %3 = cleanuppad within none []
+  call void @"\01??1S@@QEAA@XZ"(%struct.S* nonnull %x)
+  cleanupret from %3 unwind to caller
+
+unreachable:                                      ; preds = %entry
+  unreachable
+}
+
+; X86-LABEL: _g:
+; X86: movl $-1, [[state:[-0-9]+]](%ebp)
+; X86: movl $___ehhandler$g, {{.*}}
+;
+; X86: movl $1, [[state]](%ebp)
+; X86: movl $-1, (%esp)
+; X86: calll _may_throw
+;
+; X86: movl $2, [[state]](%ebp)
+; X86: movl $0, (%esp)
+; X86: calll _may_throw
+;
+; X86: movl $3, [[state]](%ebp)
+; X86: movl $1, (%esp)
+; X86: calll _may_throw
+;
+; X86: movl $2, [[state]](%ebp)
+; X86: movl $2, (%esp)
+; X86: calll _may_throw
+
+; X64-LABEL: g:
+; X64-LABEL: $ip2state$g:
+; X64-NEXT:   .long .Lfunc_begin1@IMGREL
+; X64-NEXT:   .long -1
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long 1
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long -1
+; X64-NEXT:   .long "?catch${{.*}}@?0?g@4HA"@IMGREL
+; X64-NEXT:   .long 2
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long 3
+; X64-NEXT:   .long .Ltmp{{.*}}@IMGREL+1
+; X64-NEXT:   .long 2
+
+
+; X86: .safeseh ___ehhandler$f
+; X86: .safeseh ___ehhandler$g
diff --git a/llvm/test/CodeGen/X86/win32-eh.ll b/llvm/test/CodeGen/X86/win32-eh.ll
index 87926a4..73c7b48 100644
--- a/llvm/test/CodeGen/X86/win32-eh.ll
+++ b/llvm/test/CodeGen/X86/win32-eh.ll
@@ -19,12 +19,10 @@
 cont:
   ret void
 lpad:
-  %p = catchpad [i8* bitcast (i32 ()* @catchall_filt to i8*)]
-      to label %catch unwind label %endpad
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchret %p to label %cont
-endpad:
-  catchendpad unwind to caller
+  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)]
+  catchret from %p to label %cont
 }
 
 ; CHECK-LABEL: _use_except_handler3:
@@ -45,7 +43,7 @@
 ; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
 ; CHECK: movl %[[next]], %fs:0
 ; CHECK: retl
-; CHECK: LBB1_2: # %lpad{{$}}
+; CHECK: LBB1_2: # %catch{{$}}
 
 ; CHECK: .section .xdata,"dr"
 ; CHECK-LABEL: L__ehtable$use_except_handler3:
@@ -60,12 +58,10 @@
 cont:
   ret void
 lpad:
-  %p = catchpad [i8* bitcast (i32 ()* @catchall_filt to i8*)]
-      to label %catch unwind label %endpad
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchret %p to label %cont
-endpad:
-  catchendpad unwind to caller
+  %p = catchpad within %cs [i8* bitcast (i32 ()* @catchall_filt to i8*)]
+  catchret from %p to label %cont
 }
 
 ; CHECK-LABEL: _use_except_handler4:
@@ -86,7 +82,7 @@
 ; CHECK: movl -28(%ebp), %[[next:[^ ,]*]]
 ; CHECK: movl %[[next]], %fs:0
 ; CHECK: retl
-; CHECK: LBB2_2: # %lpad{{$}}
+; CHECK: LBB2_2: # %catch{{$}}
 
 ; CHECK: .section .xdata,"dr"
 ; CHECK-LABEL: L__ehtable$use_except_handler4:
@@ -105,14 +101,10 @@
   ret void
 
 catchall:
-  %p = catchpad [i8* null, i32 64, i8* null]
-      to label %catch unwind label %endcatch
-
+  %cs = catchswitch within none [label %catch] unwind to caller
 catch:
-  catchret %p to label %cont
-
-endcatch:
-  catchendpad unwind to caller
+  %p = catchpad within %cs [i8* null, i32 64, i8* null]
+  catchret from %p to label %cont
 }
 
 ; CHECK-LABEL: _use_CxxFrameHandler3:
diff --git a/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll b/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll
index 24db164..23aeea3 100644
--- a/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll
+++ b/llvm/test/CodeGen/X86/win32-seh-catchpad-realign.ll
@@ -15,17 +15,14 @@
           to label %__try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %pad = catchpad [i8* bitcast (i32 ()* @"\01?filt$0@0@realigned_try@@" to i8*)]
-          to label %__except.ret unwind label %catchendblock
+  %cs1 = catchswitch within none [label %__except.ret] unwind to caller
 
 __except.ret:                                     ; preds = %catch.dispatch
-  catchret %pad to label %__try.cont
+  %pad = catchpad within %cs1 [i8* bitcast (i32 ()* @"\01?filt$0@0@realigned_try@@" to i8*)]
+  catchret from %pad to label %__try.cont
 
 __try.cont:                                       ; preds = %entry, %__except.ret
   ret void
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
 }
 
 ; Function Attrs: nounwind argmemonly
@@ -69,7 +66,7 @@
 ; CHECK: popl    %ebp
 ; CHECK: retl
 ;
-; CHECK: LBB0_1:                                 # %catch.dispatch
+; CHECK: LBB0_1:                                 # %__except.ret
 ; Restore ESP
 ; CHECK: movl    -24(%ebp), %esp
 ; Recompute ESI by subtracting 60 from the end of the registration node.
diff --git a/llvm/test/CodeGen/X86/win32-seh-catchpad.ll b/llvm/test/CodeGen/X86/win32-seh-catchpad.ll
index 4e373af..88dea36 100644
--- a/llvm/test/CodeGen/X86/win32-seh-catchpad.ll
+++ b/llvm/test/CodeGen/X86/win32-seh-catchpad.ll
@@ -11,10 +11,11 @@
           to label %invoke.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock
+  %cs1 = catchswitch within none [label %__except.ret] unwind to caller
 
 __except.ret:                                     ; preds = %catch.dispatch
-  catchret %0 to label %__except
+  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)]
+  catchret from %0 to label %__except
 
 __except:                                         ; preds = %__except.ret
   call void @f(i32 2)
@@ -24,9 +25,6 @@
   call void @f(i32 3)
   ret void
 
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
-
 invoke.cont:                                      ; preds = %entry
   br label %__try.cont
 }
@@ -77,81 +75,69 @@
           to label %__try.cont unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock
+  %cs1 = catchswitch within none [label %__except.ret] unwind label %catch.dispatch.11
 
 __except.ret:                                     ; preds = %catch.dispatch
-  catchret %0 to label %__try.cont
+  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
+  catchret from %0 to label %__try.cont
 
 __try.cont:                                       ; preds = %entry, %__except.ret
   invoke void @crash() #3
           to label %__try.cont.9 unwind label %catch.dispatch.5
 
 catch.dispatch.5:                                 ; preds = %__try.cont
-  %1 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.7 unwind label %catchendblock.6
+  %cs2 = catchswitch within none [label %__except.ret.7] unwind label %catch.dispatch.11
 
 __except.ret.7:                                   ; preds = %catch.dispatch.5
-  catchret %1 to label %__try.cont.9
+  %1 = catchpad within %cs2 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
+  catchret from %1 to label %__try.cont.9
 
 __try.cont.9:                                     ; preds = %__try.cont, %__except.ret.7
   invoke void @crash() #3
           to label %__try.cont.15 unwind label %catch.dispatch.11
 
 catch.dispatch.11:                                ; preds = %catchendblock, %catchendblock.6, %__try.cont.9
-  %2 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.13 unwind label %catchendblock.12
+  %cs3 = catchswitch within none [label %__except.ret.13] unwind label %catch.dispatch.17
 
 __except.ret.13:                                  ; preds = %catch.dispatch.11
-  catchret %2 to label %__try.cont.15
+  %2 = catchpad within %cs3 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
+  catchret from %2 to label %__try.cont.15
 
 __try.cont.15:                                    ; preds = %__try.cont.9, %__except.ret.13
   invoke void @crash() #3
           to label %__try.cont.35 unwind label %catch.dispatch.17
 
 catch.dispatch.17:                                ; preds = %catchendblock.12, %__try.cont.15
-  %3 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.19 unwind label %catchendblock.18
+  %cs4 = catchswitch within none [label %__except.ret.19] unwind to caller
 
 __except.ret.19:                                  ; preds = %catch.dispatch.17
-  catchret %3 to label %__except.20
+  %3 = catchpad within %cs4 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
+  catchret from %3 to label %__except.20
 
 __except.20:                                      ; preds = %__except.ret.19
   invoke void @crash() #3
           to label %__try.cont.27 unwind label %catch.dispatch.23
 
 catch.dispatch.23:                                ; preds = %__except.20
-  %4 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.25 unwind label %catchendblock.24
+  %cs5 = catchswitch within none [label %__except.ret.25] unwind to caller
 
 __except.ret.25:                                  ; preds = %catch.dispatch.23
-  catchret %4 to label %__try.cont.27
+  %4 = catchpad within %cs5 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
+  catchret from %4 to label %__try.cont.27
 
 __try.cont.27:                                    ; preds = %__except.20, %__except.ret.25
   invoke void @crash() #3
           to label %__try.cont.35 unwind label %catch.dispatch.30
 
 catch.dispatch.30:                                ; preds = %__try.cont.27
-  %5 = catchpad [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)] to label %__except.ret.32 unwind label %catchendblock.31
+  %cs6 = catchswitch within none [label %__except.ret.32] unwind to caller
 
 __except.ret.32:                                  ; preds = %catch.dispatch.30
-  catchret %5 to label %__try.cont.35
+  %5 = catchpad within %cs6 [i8* bitcast (i32 ()* @nested_exceptions_filter_catchall to i8*)]
+  catchret from %5 to label %__try.cont.35
 
 __try.cont.35:                                    ; preds = %__try.cont.15, %__try.cont.27, %__except.ret.32
   ret void
-
-catchendblock.31:                                 ; preds = %catch.dispatch.30
-  catchendpad unwind to caller
-
-catchendblock.24:                                 ; preds = %catch.dispatch.23
-  catchendpad unwind to caller
-
-catchendblock.18:                                 ; preds = %catch.dispatch.17
-  catchendpad unwind to caller
-
-catchendblock.12:                                 ; preds = %catch.dispatch.11
-  catchendpad unwind label %catch.dispatch.17
-
-catchendblock.6:                                  ; preds = %catch.dispatch.5
-  catchendpad unwind label %catch.dispatch.11
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind label %catch.dispatch.11
 }
 
 ; This table is equivalent to the one produced by MSVC, even if it isn't in
@@ -162,19 +148,19 @@
 ; CHECK:         .long   -1
 ; CHECK:         .long   _nested_exceptions_filter_catchall
 ; CHECK:         .long   LBB
-; CHECK:         .long   -1
+; CHECK:         .long   0
+; CHECK:         .long   _nested_exceptions_filter_catchall
+; CHECK:         .long   LBB
+; CHECK:         .long   1
+; CHECK:         .long   _nested_exceptions_filter_catchall
+; CHECK:         .long   LBB
+; CHECK:         .long   1
 ; CHECK:         .long   _nested_exceptions_filter_catchall
 ; CHECK:         .long   LBB
 ; CHECK:         .long   -1
 ; CHECK:         .long   _nested_exceptions_filter_catchall
 ; CHECK:         .long   LBB
-; CHECK:         .long   2
-; CHECK:         .long   _nested_exceptions_filter_catchall
-; CHECK:         .long   LBB
-; CHECK:         .long   3
-; CHECK:         .long   _nested_exceptions_filter_catchall
-; CHECK:         .long   LBB
-; CHECK:         .long   3
+; CHECK:         .long   -1
 ; CHECK:         .long   _nested_exceptions_filter_catchall
 ; CHECK:         .long   LBB
 
@@ -203,21 +189,19 @@
           to label %__except unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %entry
-  %0 = catchpad [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)] to label %__except.ret unwind label %catchendblock
+  %cs1 = catchswitch within none [label %__except.ret] unwind to caller
 
 __except.ret:                                     ; preds = %catch.dispatch
+  %0 = catchpad within %cs1 [i8* bitcast (i32 ()* @try_except_filter_catchall to i8*)]
   call void @f(i32 2)
-  catchret %0 to label %__except
+  catchret from %0 to label %__except
 
 __except:
   ret void
-
-catchendblock:                                    ; preds = %catch.dispatch
-  catchendpad unwind to caller
 }
 
 ; CHECK-LABEL: _code_in_catchpad:
-; CHECK: # %catch.dispatch
+; CHECK: # %__except.ret
 ; CHECK-NEXT:         movl    -24(%ebp), %esp
 ; CHECK-NEXT:         addl    $12, %ebp
 ; CHECK-NEXT:         movl    $-1, -16(%ebp)
diff --git a/llvm/test/CodeGen/X86/win32-seh-cleanupendpad.ll b/llvm/test/CodeGen/X86/win32-seh-nested-finally.ll
similarity index 81%
rename from llvm/test/CodeGen/X86/win32-seh-cleanupendpad.ll
rename to llvm/test/CodeGen/X86/win32-seh-nested-finally.ll
index 35d9bfe..c91a142 100644
--- a/llvm/test/CodeGen/X86/win32-seh-cleanupendpad.ll
+++ b/llvm/test/CodeGen/X86/win32-seh-nested-finally.ll
@@ -17,26 +17,17 @@
   ret void
 
 ehcleanup:                                        ; preds = %entry
-  %0 = cleanuppad []
+  %0 = cleanuppad within none []
   invoke void @f(i32 2) #3
-          to label %invoke.cont.2 unwind label %ehcleanup.end
+          to label %invoke.cont.2 unwind label %ehcleanup.3
 
 invoke.cont.2:                                    ; preds = %ehcleanup
-  cleanupret %0 unwind label %ehcleanup.3
-
-ehcleanup.end:                                    ; preds = %ehcleanup
-  cleanupendpad %0 unwind label %ehcleanup.3
+  cleanupret from %0 unwind label %ehcleanup.3
 
 ehcleanup.3:                                      ; preds = %invoke.cont.2, %ehcleanup.end, %invoke.cont
-  %1 = cleanuppad []
-  invoke void @f(i32 3) #3
-          to label %invoke.cont.4 unwind label %ehcleanup.end.5
-
-invoke.cont.4:                                    ; preds = %ehcleanup.3
-  cleanupret %1 unwind to caller
-
-ehcleanup.end.5:                                  ; preds = %ehcleanup.3
-  cleanupendpad %1 unwind to caller
+  %1 = cleanuppad within none []
+  call void @f(i32 3) #3
+  cleanupret from %1 unwind to caller
 }
 
 declare void @f(i32) #0
diff --git a/llvm/test/CodeGen/WinEH/wineh-coreclr.ll b/llvm/test/CodeGen/X86/wineh-coreclr.ll
similarity index 72%
rename from llvm/test/CodeGen/WinEH/wineh-coreclr.ll
rename to llvm/test/CodeGen/X86/wineh-coreclr.ll
index 079993f..7bbc64e 100644
--- a/llvm/test/CodeGen/WinEH/wineh-coreclr.ll
+++ b/llvm/test/CodeGen/X86/wineh-coreclr.ll
@@ -13,7 +13,7 @@
 ;       f(2);
 ;     } catch (type1) {
 ;       f(3);
-;     } catch (type2) [
+;     } catch (type2) {
 ;       f(4);
 ;       try {
 ;         f(5);
@@ -50,10 +50,10 @@
   invoke void @f(i32 2)
     to label %finally.clone unwind label %catch1.pad
 catch1.pad:
-; CHECK: .seh_proc [[L_catch1:[^ ]+]]
-  %catch1 = catchpad [i32 1]
-    to label %catch1.body unwind label %catch2.pad
+  %cs1 = catchswitch within none [label %catch1.body, label %catch2.body] unwind label %finally.pad
 catch1.body:
+  %catch1 = catchpad within %cs1 [i32 1]
+; CHECK: .seh_proc [[L_catch1:[^ ]+]]
 ; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
 ;                        ^ all funclets use the same frame size
 ; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
@@ -71,14 +71,12 @@
 ; CHECK-NEXT: callq f
 ; CHECK-NEXT: [[L_after_f3:.+]]:
   invoke void @f(i32 3)
-    to label %catch1.ret unwind label %catch.end
+    to label %catch1.ret unwind label %finally.pad
 catch1.ret:
-  catchret %catch1 to label %finally.clone
-catch2.pad:
-; CHECK: .seh_proc [[L_catch2:[^ ]+]]
-  %catch2 = catchpad [i32 2]
-    to label %catch2.body unwind label %catch.end
+  catchret from %catch1 to label %finally.clone
 catch2.body:
+  %catch2 = catchpad within %cs1 [i32 2]
+; CHECK: .seh_proc [[L_catch2:[^ ]+]]
 ; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
 ;                        ^ all funclets use the same frame size
 ; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
@@ -96,7 +94,7 @@
 ; CHECK-NEXT: callq f
 ; CHECK-NEXT: [[L_after_f4:.+]]:
   invoke void @f(i32 4)
-    to label %try_in_catch unwind label %catch.end
+    to label %try_in_catch unwind label %finally.pad
 try_in_catch:
 ; CHECK: # %try_in_catch
 ; CHECK: [[L_before_f5:.+]]:
@@ -107,7 +105,7 @@
     to label %catch2.ret unwind label %fault.pad
 fault.pad:
 ; CHECK: .seh_proc [[L_fault:[^ ]+]]
-  %fault = cleanuppad [i32 undef]
+  %fault = cleanuppad within none [i32 undef]
 ; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
 ;                        ^ all funclets use the same frame size
 ; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
@@ -120,21 +118,17 @@
 ; CHECK-NEXT: callq f
 ; CHECK-NEXT: [[L_after_f6:.+]]:
   invoke void @f(i32 6)
-    to label %fault.ret unwind label %fault.end
+    to label %fault.ret unwind label %finally.pad
 fault.ret:
-  cleanupret %fault unwind label %catch.end
-fault.end:
-  cleanupendpad %fault unwind label %catch.end
+  cleanupret from %fault unwind label %finally.pad
 catch2.ret:
-  catchret %catch2 to label %finally.clone
-catch.end:
-  catchendpad unwind label %finally.pad
+  catchret from %catch2 to label %finally.clone
 finally.clone:
   call void @f(i32 7)
   br label %tail
 finally.pad:
 ; CHECK: .seh_proc [[L_finally:[^ ]+]]
-  %finally = cleanuppad []
+  %finally = cleanuppad within none []
 ; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
 ;                        ^ all funclets use the same frame size
 ; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
@@ -142,136 +136,132 @@
 ; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
 ; CHECK: leaq [[FPOffset]](%rcx), %rbp
 ; CHECK: .seh_endprologue
-; CHECK: [[L_before_f7:.+]]:
 ; CHECK-NEXT: movl $7, %ecx
 ; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f7:.+]]:
-  invoke void @f(i32 7)
-    to label %finally.ret unwind label %finally.end
-finally.ret:
-  cleanupret %finally unwind to caller
-finally.end:
-   cleanupendpad %finally unwind to caller
+  call void @f(i32 7)
+  cleanupret from %finally unwind to caller
 tail:
   call void @f(i32 8)
   ret void
 ; CHECK: [[L_end:.*func_end.*]]:
 }
 
+; FIXME: Verify that the new clauses are correct and re-enable these checks.
+
 ; Now check for EH table in xdata (following standard xdata)
-; CHECK-LABEL: .section .xdata
+; CHECKX-LABEL: .section .xdata
 ; standard xdata comes here
-; CHECK:      .long 4{{$}}
+; CHECKX:      .long 4{{$}}
 ;                   ^ number of funclets
-; CHECK-NEXT: .long [[L_catch1]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_catch1]]-[[L_begin]]
 ;                   ^ offset from L_begin to start of 1st funclet
-; CHECK-NEXT: .long [[L_catch2]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_catch2]]-[[L_begin]]
 ;                   ^ offset from L_begin to start of 2nd funclet
-; CHECK-NEXT: .long [[L_fault]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_fault]]-[[L_begin]]
 ;                   ^ offset from L_begin to start of 3rd funclet
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]]
 ;                   ^ offset from L_begin to start of 4th funclet
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_end]]-[[L_begin]]
 ;                   ^ offset from L_begin to end of last funclet
-; CHECK-NEXT: .long 7
+; CHECKX-NEXT: .long 7
 ;                   ^ number of EH clauses
 ; Clause 1: call f(2) is guarded by catch1
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ flags (0 => catch handler)
-; CHECK-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_catch1]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_catch1]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_catch2]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_catch2]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 1
+; CHECKX-NEXT: .long 1
 ;                   ^ type token of catch (from catchpad)
 ; Clause 2: call f(2) is also guarded by catch2
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ flags (0 => catch handler)
-; CHECK-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_catch2]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_catch2]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_fault]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_fault]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 2
+; CHECKX-NEXT: .long 2
 ;                   ^ type token of catch (from catchpad)
 ; Clause 3: calls f(1) and f(2) are guarded by finally
-; CHECK-NEXT: .long 2
+; CHECKX-NEXT: .long 2
 ;                   ^ flags (2 => finally handler)
-; CHECK-NEXT: .long ([[L_before_f1]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f1]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_end]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ type token slot (null for finally)
 ; Clause 4: call f(3) is guarded by finally
 ;           This is a "duplicate" because the protected range (f(3))
 ;           is in funclet catch1 but the finally's immediate parent
 ;           is the main function, not that funclet.
-; CHECK-NEXT: .long 10
+; CHECKX-NEXT: .long 10
 ;                   ^ flags (2 => finally handler | 8 => duplicate)
-; CHECK-NEXT: .long ([[L_before_f3]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f3]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f3]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f3]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_end]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ type token slot (null for finally)
 ; Clause 5: call f(5) is guarded by fault
-; CHECK-NEXT: .long 4
+; CHECKX-NEXT: .long 4
 ;                   ^ flags (4 => fault handler)
-; CHECK-NEXT: .long ([[L_before_f5]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f5]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_fault]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_fault]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ type token slot (null for fault)
 ; Clause 6: calls f(4) and f(5) are guarded by finally
 ;           This is a "duplicate" because the protected range (f(4)-f(5))
 ;           is in funclet catch2 but the finally's immediate parent
 ;           is the main function, not that funclet.
-; CHECK-NEXT: .long 10
+; CHECKX-NEXT: .long 10
 ;                   ^ flags (2 => finally handler | 8 => duplicate)
-; CHECK-NEXT: .long ([[L_before_f4]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f4]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_end]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ type token slot (null for finally)
 ; Clause 7: call f(6) is guarded by finally
 ;           This is a "duplicate" because the protected range (f(3))
 ;           is in funclet catch1 but the finally's immediate parent
 ;           is the main function, not that funclet.
-; CHECK-NEXT: .long 10
+; CHECKX-NEXT: .long 10
 ;                   ^ flags (2 => finally handler | 8 => duplicate)
-; CHECK-NEXT: .long ([[L_before_f6]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_before_f6]]-[[L_begin]])+1
 ;                   ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f6]]-[[L_begin]])+1
+; CHECKX-NEXT: .long ([[L_after_f6]]-[[L_begin]])+1
 ;                   ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_finally]]-[[L_begin]]
 ;                   ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
+; CHECKX-NEXT: .long [[L_end]]-[[L_begin]]
 ;                   ^ offset of end of handler
-; CHECK-NEXT: .long 0
+; CHECKX-NEXT: .long 0
 ;                   ^ type token slot (null for finally)
diff --git a/llvm/test/CodeGen/WinEH/wineh-exceptionpointer.ll b/llvm/test/CodeGen/X86/wineh-exceptionpointer.ll
similarity index 78%
rename from llvm/test/CodeGen/WinEH/wineh-exceptionpointer.ll
rename to llvm/test/CodeGen/X86/wineh-exceptionpointer.ll
index 47ffc35..9c1f0aa 100644
--- a/llvm/test/CodeGen/WinEH/wineh-exceptionpointer.ll
+++ b/llvm/test/CodeGen/X86/wineh-exceptionpointer.ll
@@ -11,18 +11,16 @@
   invoke void @f()
     to label %exit unwind label %catch.pad
 catch.pad:
-; CHECK: {{^[^: ]+}}: # %catch.pad
-  %catch = catchpad [i32 5]
-    to label %catch.body unwind label %catch.end
+  %cs1 = catchswitch within none [label %catch.body] unwind to caller
 catch.body:
-  %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch)
-  %cast_exn = bitcast i8 addrspace(1)* %exn to i32 addrspace(1)*
+  ; CHECK: {{^[^: ]+}}: # %catch.body
   ; CHECK: movq %rdx, %rcx
   ; CHECK-NEXT: callq g
+  %catch = catchpad within %cs1 [i32 5]
+  %exn = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch)
+  %cast_exn = bitcast i8 addrspace(1)* %exn to i32 addrspace(1)*
   call void @g(i32 addrspace(1)* %cast_exn)
-  catchret %catch to label %exit
-catch.end:
-  catchendpad unwind to caller
+  catchret from %catch to label %exit
 exit:
   ret void
 }