summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/WinEH
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen/WinEH')
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-cloning.ll398
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-coreclr.ll277
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-demotion.ll121
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-exceptionpointer.ll28
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-intrinsics.ll14
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-multi-parent-cloning.ll1548
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-no-demotion.ll78
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll68
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-statenumbering.ll31
9 files changed, 226 insertions, 2337 deletions
diff --git a/llvm/test/CodeGen/WinEH/wineh-cloning.ll b/llvm/test/CodeGen/WinEH/wineh-cloning.ll
index 7d6529d6009..66a9132980f 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 @@ entry:
; %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 @@ endcatch:
; 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 @@ entry:
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 @@ exit:
; 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 @@ exit:
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 @@ exit:
; 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 @@ exit:
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 @@ exit:
; 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 @@ exit:
; 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 @@ exit:
; 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 @@ exit:
; 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.cont:
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,109 +253,32 @@ shared:
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: 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 @test7() 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 @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: shared.cont.for.left:
; CHECK: unreachable
+; CHECK: inner:
+; CHECK: %i = cleanuppad within none []
+; CHECK: call void @h(i32 %x1.wineh.reload)
+; CHECK: cleanupret from %i unwind to caller
-define void @test8() personality i32 (...)* @__CxxFrameHandler3 {
+define void @test9() personality i32 (...)* @__C_specific_handler {
entry:
invoke void @f()
to label %invoke.cont unwind label %left
@@ -369,119 +286,32 @@ 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 @@ entry:
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 @@ unreachable:
; 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 @@ cont:
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 @@ entry:
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-coreclr.ll b/llvm/test/CodeGen/WinEH/wineh-coreclr.ll
deleted file mode 100644
index 079993f74db..00000000000
--- a/llvm/test/CodeGen/WinEH/wineh-coreclr.ll
+++ /dev/null
@@ -1,277 +0,0 @@
-; RUN: llc -mtriple=x86_64-pc-windows-coreclr -verify-machineinstrs < %s | FileCheck %s
-
-declare void @ProcessCLRException()
-declare void @f(i32)
-declare void @g(i8 addrspace(1)*)
-declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token)
-
-; Simplified IR for pseudo-C# like the following:
-; void test1() {
-; try {
-; f(1);
-; try {
-; f(2);
-; } catch (type1) {
-; f(3);
-; } catch (type2) [
-; f(4);
-; try {
-; f(5);
-; } fault {
-; f(6);
-; }
-; }
-; } finally {
-; f(7);
-; }
-; f(8);
-; }
-
-; CHECK-LABEL: test1: # @test1
-; CHECK-NEXT: [[L_begin:.*func_begin.*]]:
-define void @test1() personality i8* bitcast (void ()* @ProcessCLRException to i8*) {
-entry:
-; CHECK: # %entry
-; CHECK: leaq [[FPOffset:[0-9]+]](%rsp), %rbp
-; CHECK: .seh_endprologue
-; CHECK: movq %rsp, [[PSPSymOffset:[0-9]+]](%rsp)
-; CHECK: [[L_before_f1:.+]]:
-; CHECK-NEXT: movl $1, %ecx
-; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f1:.+]]:
- invoke void @f(i32 1)
- to label %inner_try unwind label %finally.pad
-inner_try:
-; CHECK: # %inner_try
-; CHECK: [[L_before_f2:.+]]:
-; CHECK-NEXT: movl $2, %ecx
-; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f2:.+]]:
- 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
-catch1.body:
-; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
-; ^ all funclets use the same frame size
-; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
-; ^ establisher frame pointer passed in rcx
-; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
-; CHECK: leaq [[FPOffset]](%rcx), %rbp
-; CHECK: .seh_endprologue
-; CHECK: movq %rdx, %rcx
-; ^ exception pointer passed in rdx
-; CHECK-NEXT: callq g
- %exn1 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch1)
- call void @g(i8 addrspace(1)* %exn1)
-; CHECK: [[L_before_f3:.+]]:
-; CHECK-NEXT: movl $3, %ecx
-; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f3:.+]]:
- invoke void @f(i32 3)
- to label %catch1.ret unwind label %catch.end
-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
-catch2.body:
-; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
-; ^ all funclets use the same frame size
-; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
-; ^ establisher frame pointer passed in rcx
-; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
-; CHECK: leaq [[FPOffset]](%rcx), %rbp
-; CHECK: .seh_endprologue
-; CHECK: movq %rdx, %rcx
-; ^ exception pointer passed in rdx
-; CHECK-NEXT: callq g
- %exn2 = call i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token %catch2)
- call void @g(i8 addrspace(1)* %exn2)
-; CHECK: [[L_before_f4:.+]]:
-; CHECK-NEXT: movl $4, %ecx
-; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f4:.+]]:
- invoke void @f(i32 4)
- to label %try_in_catch unwind label %catch.end
-try_in_catch:
-; CHECK: # %try_in_catch
-; CHECK: [[L_before_f5:.+]]:
-; CHECK-NEXT: movl $5, %ecx
-; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f5:.+]]:
- invoke void @f(i32 5)
- to label %catch2.ret unwind label %fault.pad
-fault.pad:
-; CHECK: .seh_proc [[L_fault:[^ ]+]]
- %fault = cleanuppad [i32 undef]
-; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
-; ^ all funclets use the same frame size
-; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
-; ^ establisher frame pointer passed in rcx
-; CHECK: movq %rcx, [[PSPSymOffset]](%rsp)
-; CHECK: leaq [[FPOffset]](%rcx), %rbp
-; CHECK: .seh_endprologue
-; CHECK: [[L_before_f6:.+]]:
-; CHECK-NEXT: movl $6, %ecx
-; CHECK-NEXT: callq f
-; CHECK-NEXT: [[L_after_f6:.+]]:
- invoke void @f(i32 6)
- to label %fault.ret unwind label %fault.end
-fault.ret:
- cleanupret %fault unwind label %catch.end
-fault.end:
- cleanupendpad %fault unwind label %catch.end
-catch2.ret:
- catchret %catch2 to label %finally.clone
-catch.end:
- catchendpad unwind label %finally.pad
-finally.clone:
- call void @f(i32 7)
- br label %tail
-finally.pad:
-; CHECK: .seh_proc [[L_finally:[^ ]+]]
- %finally = cleanuppad []
-; CHECK: .seh_stackalloc [[FuncletFrameSize:[0-9]+]]
-; ^ all funclets use the same frame size
-; CHECK: movq [[PSPSymOffset]](%rcx), %rcx
-; ^ establisher frame pointer passed in rcx
-; 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
-tail:
- call void @f(i32 8)
- ret void
-; CHECK: [[L_end:.*func_end.*]]:
-}
-
-; Now check for EH table in xdata (following standard xdata)
-; CHECK-LABEL: .section .xdata
-; standard xdata comes here
-; CHECK: .long 4{{$}}
-; ^ number of funclets
-; CHECK-NEXT: .long [[L_catch1]]-[[L_begin]]
-; ^ offset from L_begin to start of 1st funclet
-; CHECK-NEXT: .long [[L_catch2]]-[[L_begin]]
-; ^ offset from L_begin to start of 2nd funclet
-; CHECK-NEXT: .long [[L_fault]]-[[L_begin]]
-; ^ offset from L_begin to start of 3rd funclet
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
-; ^ offset from L_begin to start of 4th funclet
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
-; ^ offset from L_begin to end of last funclet
-; CHECK-NEXT: .long 7
-; ^ number of EH clauses
-; Clause 1: call f(2) is guarded by catch1
-; CHECK-NEXT: .long 0
-; ^ flags (0 => catch handler)
-; CHECK-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_catch1]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_catch2]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-NEXT: .long 1
-; ^ type token of catch (from catchpad)
-; Clause 2: call f(2) is also guarded by catch2
-; CHECK-NEXT: .long 0
-; ^ flags (0 => catch handler)
-; CHECK-NEXT: .long ([[L_before_f2]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_catch2]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_fault]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-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
-; ^ flags (2 => finally handler)
-; CHECK-NEXT: .long ([[L_before_f1]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f2]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-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
-; ^ flags (2 => finally handler | 8 => duplicate)
-; CHECK-NEXT: .long ([[L_before_f3]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f3]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-NEXT: .long 0
-; ^ type token slot (null for finally)
-; Clause 5: call f(5) is guarded by fault
-; CHECK-NEXT: .long 4
-; ^ flags (4 => fault handler)
-; CHECK-NEXT: .long ([[L_before_f5]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_fault]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-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
-; ^ flags (2 => finally handler | 8 => duplicate)
-; CHECK-NEXT: .long ([[L_before_f4]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f5]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-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
-; ^ flags (2 => finally handler | 8 => duplicate)
-; CHECK-NEXT: .long ([[L_before_f6]]-[[L_begin]])+1
-; ^ offset of start of clause
-; CHECK-NEXT: .long ([[L_after_f6]]-[[L_begin]])+1
-; ^ offset of end of clause
-; CHECK-NEXT: .long [[L_finally]]-[[L_begin]]
-; ^ offset of start of handler
-; CHECK-NEXT: .long [[L_end]]-[[L_begin]]
-; ^ offset of end of handler
-; CHECK-NEXT: .long 0
-; ^ type token slot (null for finally)
diff --git a/llvm/test/CodeGen/WinEH/wineh-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-demotion.ll
index 96f33b0ed1a..bd239133ea8 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 @@ merge:
; 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 @@ right:
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 @@ right:
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 @@ join:
%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 @@ invoke.cont:
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 @@ merge:
; 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 @@ invoke.cont2:
; 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 @@ entry:
%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 @@ invoke.cont:
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 @@ right:
; 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 @@ done:
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-exceptionpointer.ll b/llvm/test/CodeGen/WinEH/wineh-exceptionpointer.ll
deleted file mode 100644
index 47ffc35acac..00000000000
--- a/llvm/test/CodeGen/WinEH/wineh-exceptionpointer.ll
+++ /dev/null
@@ -1,28 +0,0 @@
-; RUN: llc -mtriple=x86_64-pc-windows-coreclr < %s | FileCheck %s
-
-declare void @ProcessCLRException()
-declare i8 addrspace(1)* @llvm.eh.exceptionpointer.p1i8(token)
-declare void @f()
-declare void @g(i32 addrspace(1)*)
-
-; CHECK-LABEL: test1: # @test1
-define void @test1() personality i8* bitcast (void ()* @ProcessCLRException to i8*) {
-entry:
- 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
-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: movq %rdx, %rcx
- ; CHECK-NEXT: callq g
- call void @g(i32 addrspace(1)* %cast_exn)
- catchret %catch to label %exit
-catch.end:
- catchendpad unwind to caller
-exit:
- ret void
-}
diff --git a/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll b/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll
index acdeb796ac1..3658792a384 100644
--- a/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-intrinsics.ll
@@ -15,13 +15,12 @@ entry:
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 @@ entry:
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 1e9342d17cb..00000000000
--- 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 4f023947caa..7d18238c003 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 i32 @g()
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 @@ invoke.cont2:
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 @@ shared.cont:
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 @@ invoke.cont:
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 @@ shared.cont:
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 @@ invoke.cont:
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 bd1f2322878..f5889f03965 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 @dummy_filter()
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 @@ entry:
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 @@ exit:
;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 2d5f7ca0c0e..b7ec843aa39 100644
--- a/llvm/test/CodeGen/WinEH/wineh-statenumbering.ll
+++ b/llvm/test/CodeGen/WinEH/wineh-statenumbering.ll
@@ -37,9 +37,10 @@ entry:
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 @@ catch: ; preds = %catch.dispatch
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
-
-invoke.cont: ; preds = %catch.3
- catchret %2 to label %try.cont
+ ; CHECK: call void @g(i32 1)
+ call void @g(i32 1)
+ catchret from %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
OpenPOWER on IntegriCloud