[llvm] r249792 - [WinEH] Fix cleanup state numbering
Joseph Tremoulet via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 8 17:46:08 PDT 2015
Author: josepht
Date: Thu Oct 8 19:46:08 2015
New Revision: 249792
URL: http://llvm.org/viewvc/llvm-project?rev=249792&view=rev
Log:
[WinEH] Fix cleanup state numbering
Summary:
- Recurse from cleanupendpads to their cleanuppads, to make sure the
cleanuppad is visited if it has a cleanupendpad but no cleanupret.
- Check for and avoid double-processing cleanuppads, to allow for them to
have multiple cleanuprets (plus cleanupendpads).
- Update Cxx state numbering to visit toplevel cleanupendpads and to
recurse from cleanupendpads to their preds, to ensure we number any
funclets in inlined cleanups. SEH state numbering already did this.
Reviewers: rnk
Subscribers: llvm-commits
Differential Revision: http://reviews.llvm.org/D13374
Added:
llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll
Modified:
llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=249792&r1=249791&r2=249792&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Thu Oct 8 19:46:08 2015
@@ -2715,6 +2715,9 @@ static void calculateExplicitCXXStateNum
DEBUG(dbgs() << "CatchHigh[" << FirstTryPad->getName() << "]: " << CatchHigh
<< '\n');
} else if (isa<CleanupPadInst>(FirstNonPHI)) {
+ // A cleanup can have multiple exits; don't re-process after the first.
+ if (FuncInfo.EHPadStateMap.count(FirstNonPHI))
+ return;
int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, &BB);
FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
@@ -2722,6 +2725,15 @@ static void calculateExplicitCXXStateNum
for (const BasicBlock *PredBlock : predecessors(&BB))
if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, CleanupState);
+ } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(FirstNonPHI)) {
+ // Propagate ParentState to the cleanuppad in case it doesn't have
+ // any cleanuprets.
+ BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
+ calculateExplicitCXXStateNumbers(FuncInfo, *CleanupBlock, ParentState);
+ // Anything unwinding through CleanupEndPadInst is in ParentState.
+ for (const BasicBlock *PredBlock : predecessors(&BB))
+ if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
+ calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, ParentState);
} else if (isa<TerminatePadInst>(FirstNonPHI)) {
report_fatal_error("Not yet implemented!");
} else {
@@ -2794,6 +2806,9 @@ static void calculateExplicitSEHStateNum
if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, ParentState);
} else if (isa<CleanupPadInst>(FirstNonPHI)) {
+ // A cleanup can have multiple exits; don't re-process after the first.
+ if (FuncInfo.EHPadStateMap.count(FirstNonPHI))
+ return;
int CleanupState = addSEHFinally(FuncInfo, ParentState, &BB);
FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
@@ -2801,7 +2816,11 @@ static void calculateExplicitSEHStateNum
for (const BasicBlock *PredBlock : predecessors(&BB))
if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, CleanupState);
- } else if (isa<CleanupEndPadInst>(FirstNonPHI)) {
+ } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(FirstNonPHI)) {
+ // Propagate ParentState to the cleanuppad in case it doesn't have
+ // any cleanuprets.
+ BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
+ calculateExplicitSEHStateNumbers(FuncInfo, *CleanupBlock, ParentState);
// Anything unwinding through CleanupEndPadInst is in ParentState.
FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
DEBUG(dbgs() << "Assigning state #" << ParentState << " to BB "
@@ -2859,9 +2878,6 @@ void llvm::calculateWinCXXEHStateNumbers
if (BB.isLandingPad())
report_fatal_error("MSVC C++ EH cannot use landingpads");
const Instruction *FirstNonPHI = BB.getFirstNonPHI();
- // Skip cleanupendpads; they are exits, not entries.
- if (isa<CleanupEndPadInst>(FirstNonPHI))
- continue;
if (!doesEHPadUnwindToCaller(FirstNonPHI))
continue;
calculateExplicitCXXStateNumbers(FuncInfo, BB, -1);
Added: llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll?rev=249792&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll (added)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering-cleanups.ll Thu Oct 8 19:46:08 2015
@@ -0,0 +1,100 @@
+; RUN: sed -e s/.Cxx:// %s | opt -mtriple=x86-pc-windows-msvc -S -x86-winehstate | FileCheck %s
+; RUN: sed -e s/.SEH:// %s | opt -mtriple=x86-pc-windows-msvc -S -x86-winehstate | FileCheck %s
+
+declare i32 @__CxxFrameHandler3(...)
+declare i32 @_except_handler3(...)
+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 {
+entry:
+ ; CHECK: entry:
+ ; CHECK: store i32 1
+ ; CHECK: invoke void @f(i32 1)
+ invoke void @f(i32 1)
+ to label %exit unwind label %cleanup.pad
+cleanup.pad:
+ %cleanup = cleanuppad []
+ br i1 %b, label %left, label %right
+left:
+ cleanupret %cleanup unwind label %catch.pad
+right:
+ cleanupret %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
+catch.body:
+ catchret %catch to label %exit
+catch.end:
+ catchendpad unwind to caller
+exit:
+ ret void
+}
+
+; CHECK-LABEL: define void @test3(
+;Cxx: define void @test3() personality i32 (...)* @__CxxFrameHandler3 {
+;SEH: define void @test3() personality i32 (...)* @_except_handler3 {
+entry:
+ ; CHECK: entry:
+ ; CHECK: store i32 1
+ ; 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: invoke void @f(i32 0)
+ %cleanup = cleanuppad []
+ invoke void @f(i32 0)
+ to label %unreachable unwind label %cleanup.end
+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
+catch.body:
+ catchret %catch to label %exit
+catch.end:
+ catchendpad unwind to caller
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list