diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2015-11-06 10:07:33 +0000 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2015-11-06 10:07:33 +0000 |
commit | 9947cacebfc667b033e0b2297fd2173b34716b12 (patch) | |
tree | b0d1314128d0e9d6484804067b784a5b6ffda023 /llvm/test | |
parent | 7856ad0bccd6d4956b2dd319ccdf8375d3b73964 (diff) | |
download | bcm5719-llvm-9947cacebfc667b033e0b2297fd2173b34716b12.tar.gz bcm5719-llvm-9947cacebfc667b033e0b2297fd2173b34716b12.zip |
Revert r252249 (and r252255, r252258), "[WinEH] Clone funclets with multiple parents"
It behaved flaky due to iterating pointer key values on std::set and std::map.
llvm-svn: 252279
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/CodeGen/WinEH/wineh-cloning.ll | 115 | ||||
-rw-r--r-- | llvm/test/CodeGen/WinEH/wineh-demotion.ll | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/WinEH/wineh-multi-parent-cloning.ll | 1561 | ||||
-rw-r--r-- | llvm/test/CodeGen/WinEH/wineh-no-demotion.ll | 18 |
4 files changed, 10 insertions, 1690 deletions
diff --git a/llvm/test/CodeGen/WinEH/wineh-cloning.ll b/llvm/test/CodeGen/WinEH/wineh-cloning.ll index 58bf71e62b6..b4e785d42dd 100644 --- a/llvm/test/CodeGen/WinEH/wineh-cloning.ll +++ b/llvm/test/CodeGen/WinEH/wineh-cloning.ll @@ -280,30 +280,7 @@ exit: ; 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: 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: store i32 %x, i32* %x.wineh.spillslot -; 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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: cleanupret [[I_R]] unwind label %right.end -; CHECK: [[INNER_LEFT]]: -; CHECK: [[I_L:\%.+]] = cleanuppad [] -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable +; TODO: CHECKs define void @test7() personality i32 (...)* @__CxxFrameHandler3 { @@ -335,32 +312,7 @@ unreachable: ; with the join at the entry itself instead of following a ; non-pad join. ; CHECK-LABEL: define void @test7( -; CHECK: invoke.cont: -; CHECK: to label %[[UNREACHABLE_ENTRY:.+]] unwind label %right -; CHECK: left: -; CHECK: to label %[[UNREACHABLE_LEFT:.+]] unwind label %[[INNER_LEFT:.+]] -; CHECK: right: -; CHECK: to label %right.catch unwind label %right.end -; CHECK: right.catch: -; CHECK: to label %unreachable unwind label %[[INNER_RIGHT:.+]] -; CHECK: right.end: -; CHECK: catchendpad unwind to caller -; CHECK: [[INNER_RIGHT]]: -; CHECK: [[I_R:\%.+]] = cleanuppad [] -; CHECK: [[X_R:\%.+]] = call i32 @g() -; CHECK: call void @h(i32 [[X_R]]) -; CHECK: cleanupret [[I_R]] unwind label %right.end -; CHECK: [[INNER_LEFT]]: -; CHECK: [[I_L:\%.+]] = cleanuppad [] -; CHECK: [[X_L:\%.+]] = call i32 @g() -; CHECK: call void @h(i32 [[X_L]]) -; CHECK: unreachable -; CHECK: unreachable: -; CHECK: unreachable -; CHECK: [[UNREACHABLE_LEFT]]: -; CHECK: unreachable -; CHECK: [[UNREACHABLE_ENTRY]]: -; CHECK: unreachable +; TODO: CHECKs define void @test8() personality i32 (...)* @__CxxFrameHandler3 { @@ -398,40 +350,7 @@ 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 +; TODO: CHECKs define void @test9() personality i32 (...)* @__CxxFrameHandler3 { @@ -464,33 +383,7 @@ unreachable: ; of which was which along the way; generating each possibility lets ; whichever case was correct execute correctly. ; 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: [[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 - +; TODO: CHECKs define void @test10() personality i32 (...)* @__CxxFrameHandler3 { entry: diff --git a/llvm/test/CodeGen/WinEH/wineh-demotion.ll b/llvm/test/CodeGen/WinEH/wineh-demotion.ll index e849a8ec80c..113d95015a0 100644 --- a/llvm/test/CodeGen/WinEH/wineh-demotion.ll +++ b/llvm/test/CodeGen/WinEH/wineh-demotion.ll @@ -86,18 +86,18 @@ catch.inner: ; 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 merge.outer: ; CHECK: merge.outer: + ; CHECK-NOT: = phi ; CHECK: [[CatchPad:%[^ ]+]] = catchpad [] + %y = phi i32 [ %x, %catchend.inner ], [ %z, %catch.inner ] %cpouter = catchpad [] to label %catch.outer unwind label %catchend.outer catchend.outer: 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 96028542671..00000000000 --- a/llvm/test/CodeGen/WinEH/wineh-multi-parent-cloning.ll +++ /dev/null @@ -1,1561 +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: 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: store i32 %x, i32* %x.wineh.spillslot -; 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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: cleanupret [[I_R]] unwind label %right.end -; CHECK: [[INNER_LEFT]]: -; CHECK: [[I_L:\%.+]] = cleanuppad [] -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; 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: 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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; 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: 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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; 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: 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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable -; CHECK: [[INNER_END_LEFT]]: -; CHECK: catchendpad unwind label %[[LEFT_END]] -; CHECK: [[INNER_END_RIGHT]]: -; CHECK: catchendpad unwind to caller - - -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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable -; CHECK: [[INNER_END_LEFT]]: -; CHECK: catchendpad unwind label %[[LEFT_END]] -; CHECK: [[INNER_END_RIGHT]]: -; CHECK: catchendpad unwind to caller - -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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable -; CHECK: [[INNER_END_LEFT]]: -; CHECK: catchendpad unwind label %[[LEFT_END]] -; CHECK: [[INNER_END_RIGHT]]: -; CHECK: catchendpad unwind to caller - - -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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable -; CHECK: [[INNER_END_LEFT]]: -; CHECK: catchendpad unwind label %[[INNER_SIBLING_LEFT:.+]] -; CHECK: [[INNER_END_RIGHT]]: -; CHECK: catchendpad unwind label %[[INNER_SIBLING_RIGHT:.+]] -; 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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable -; CHECK: [[INNER_END_LEFT]]: -; CHECK: catchendpad unwind label %[[LEFT_END]] -; CHECK: [[INNER_END_RIGHT]]: -; CHECK: catchendpad unwind to caller - - -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: [[X_RELOAD_R:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_R]]) -; CHECK: unreachable -; CHECK: [[INNER_CATCH_LEFT]]: -; CHECK: [[X_RELOAD_L:\%.+]] = load i32, i32* %x.wineh.spillslot -; CHECK: call void @h(i32 [[X_RELOAD_L]]) -; CHECK: unreachable -; CHECK: [[INNER_END_LEFT]]: -; CHECK: catchendpad unwind label %[[RIGHT_END]] -; CHECK: [[INNER_END_RIGHT]]: -; 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_LEFT]]: -; CHECK: catchendpad unwind label %[[LEFT_END]] -; CHECK: [[INNER_END_RIGHT]]: -; CHECK: catchendpad unwind to caller - - -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() -; TODO: Re-enable this check when it is less flaky. -; to label %[[UNREACHABLE_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]] -; CHECK: [[INNER_SIBLING_CATCH_LEFT]]: -; CHECK: invoke void @f() -; TODO: Re-enable this check when it is less flaky. -; 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 [] -; TODO: Re-enable this check when it is less flaky. -; to label %[[INNER_SIBLING_CATCH_RIGHT:.+]] unwind label %[[INNER_END_RIGHT]] -; CHECK: [[INNER_SIBLING_LEFT]]: -; CHECK: [[IS_LEFT:\%.+]] = catchpad [] -; TODO: Re-enable this check when it is less flaky. -; 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..4e4206eb2be 100644 --- a/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll +++ b/llvm/test/CodeGen/WinEH/wineh-no-demotion.ll @@ -39,20 +39,12 @@ shared.cont: unreachable inner: + ; CHECK: %phi = phi i32 [ %x, %right ], [ 0, %invoke.cont2 ], [ %x.for.left, %left ] %phi = phi i32 [ %x, %shared ], [ 0, %invoke.cont2 ] %i = cleanuppad [] 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) - exit: unreachable } @@ -84,16 +76,12 @@ shared.cont: unreachable inner: + ; CHECK: %x1 = phi i32 [ %x.for.left, %left ], [ %x, %right ] + ; CHECK: call void @h(i32 %x1) %i = cleanuppad [] 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) - exit: unreachable } |