summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp3
-rw-r--r--llvm/test/CodeGen/WinEH/wineh-cleanuppad-nounwind.ll24
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
OpenPOWER on IntegriCloud