diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index 4b0ce21111b..35b944ea309 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -1582,11 +1582,10 @@ void WinEHPrepare::findCleanupHandlers(LandingPadActions &Actions, InsertValueInst *Insert1 = nullptr; InsertValueInst *Insert2 = nullptr; Value *ResumeVal = Resume->getOperand(0); - // If there is only one landingpad, we may use the lpad directly with no - // insertions. - if (isa(ResumeVal)) - return; - if (!isa(ResumeVal)) { + // If the resume value isn't a phi or landingpad value, it should be a + // series of insertions. Identify them so we can avoid them when scanning + // for cleanups. + if (!isa(ResumeVal) && !isa(ResumeVal)) { Insert2 = dyn_cast(ResumeVal); if (!Insert2) return createCleanupHandler(Actions, CleanupHandlerMap, BB); @@ -1702,7 +1701,6 @@ void WinEHPrepare::findCleanupHandlers(LandingPadActions &Actions, return; BB = Branch->getSuccessor(0); } - return; } // This is a public function, declared in WinEHFuncInfo.h and is also diff --git a/test/CodeGen/WinEH/seh-inlined-finally.ll b/test/CodeGen/WinEH/seh-inlined-finally.ll new file mode 100644 index 00000000000..3cfbcd175f5 --- /dev/null +++ b/test/CodeGen/WinEH/seh-inlined-finally.ll @@ -0,0 +1,35 @@ +; RUN: opt -S -winehprepare -sehprepare < %s | FileCheck %s + +; Check that things work when the mid-level optimizer inlines the finally +; block. + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc" + +declare i32 @puts(i8*) +declare void @may_crash() +declare i32 @__C_specific_handler(...) + +define void @use_finally() { +entry: + invoke void @may_crash() + to label %invoke.cont unwind label %lpad + +invoke.cont: ; preds = %entry + %call.i = tail call i32 @puts(i8* null) + ret void + +lpad: ; preds = %entry + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) + cleanup + %call.i2 = tail call i32 @puts(i8* null) + resume { i8*, i32 } %0 +} + +; CHECK-LABEL: define void @use_finally() +; CHECK: invoke void @may_crash() +; +; CHECK: landingpad +; CHECK-NEXT: cleanup +; CHECK-NEXT: call i8* (...)* @llvm.eh.actions(i32 0, void (i8*, i8*)* @use_finally.cleanup) +; CHECK-NEXT: indirectbr i8* %recover, []