diff options
-rw-r--r-- | llvm/lib/CodeGen/WinEHPrepare.cpp | 3 | ||||
-rw-r--r-- | llvm/test/CodeGen/WinEH/wineh-cleanuppad-nounwind.ll | 24 |
2 files changed, 26 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index c4eaef88673..12733acf3b8 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -1072,7 +1072,8 @@ void WinEHPrepare::fixupNoReturnCleanupPads(Function &F) { if (!CleanupPad) continue; // Skip over any cleanups have unwind targets, they do not need this. - if (getCleanupRetUnwindDest(CleanupPad) != nullptr) + if (any_of(CleanupPad->users(), + [](const User *U) { return isa<CleanupReturnInst>(U); })) continue; // Walk the blocks within the cleanup which end in 'unreachable'. // We will replace the unreachable instruction with a cleanupret; diff --git a/llvm/test/CodeGen/WinEH/wineh-cleanuppad-nounwind.ll b/llvm/test/CodeGen/WinEH/wineh-cleanuppad-nounwind.ll index 09b4d3b8a1b..ff6b70ab190 100644 --- a/llvm/test/CodeGen/WinEH/wineh-cleanuppad-nounwind.ll +++ b/llvm/test/CodeGen/WinEH/wineh-cleanuppad-nounwind.ll @@ -65,6 +65,30 @@ exit: unreachable } +; CHECK-LABEL: @test2( +define void @test2(i1 %B) personality i32 (...)* @__CxxFrameHandler3 { +entry: + invoke void @f() + to label %invoke.cont unwind label %ehcleanup + +invoke.cont: + unreachable + +ehcleanup: + %cp = cleanuppad within none [] + br i1 %B, label %ret, label %if.then + +if.then: + call void @exit(i32 1) [ "funclet"(token %cp) ] + unreachable + +ret: + cleanupret from %cp unwind to caller +} + +; CHECK: call void @exit(i32 1) [ "funclet"(token %cp) ] +; CHECK-NEXT: unreachable + declare void @f() declare void @exit(i32) nounwind noreturn |