[llvm] r256317 - [WinEH] Don't visit the same catchswitch twice
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 22 19:59:04 PST 2015
Author: majnemer
Date: Tue Dec 22 21:59:04 2015
New Revision: 256317
URL: http://llvm.org/viewvc/llvm-project?rev=256317&view=rev
Log:
[WinEH] Don't visit the same catchswitch twice
We visited the same catchswitch twice because it was both the child of
another funclet and the predecessor of a cleanuppad.
Instead, change the numbering algorithm to only recurse if the unwind
destination of the inner funclet agrees with the unwind destination of
the catchswitch.
This fixes PR25926.
Modified:
llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll
Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=256317&r1=256316&r2=256317&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Tue Dec 22 21:59:04 2015
@@ -165,8 +165,7 @@ static void calculateStateNumbersForInvo
continue;
auto &BBColors = BlockColors[&BB];
- assert(BBColors.size() == 1 &&
- "multi-color BB not removed by preparation");
+ assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
BasicBlock *FuncletEntryBB = BBColors.front();
BasicBlock *FuncletUnwindDest;
@@ -249,8 +248,13 @@ static void calculateCXXStateNumbers(Win
FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
for (const User *U : CatchPad->users()) {
const auto *UserI = cast<Instruction>(U);
- if (UserI->isEHPad())
- calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
+ if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
+ if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
+ calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
+ if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
+ if (getCleanupRetUnwindDest(InnerCleanupPad) ==
+ CatchSwitch->getUnwindDest())
+ calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
}
}
int CatchHigh = FuncInfo.getLastStateNumber();
@@ -347,9 +351,13 @@ static void calculateSEHStateNumbers(Win
// outside the __try.
for (const User *U : CatchPad->users()) {
const auto *UserI = cast<Instruction>(U);
- if (UserI->isEHPad()) {
- calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
- }
+ if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
+ if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
+ calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
+ if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
+ if (getCleanupRetUnwindDest(InnerCleanupPad) ==
+ CatchSwitch->getUnwindDest())
+ calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
}
} else {
auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
Modified: llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll?rev=256317&r1=256316&r2=256317&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll (original)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll Tue Dec 22 21:59:04 2015
@@ -79,8 +79,63 @@ define i32 @nopads() #0 personality i32
; CHECK-NEXT: ret i32 0
; CHECK-NOT: __ehhandler$nopads
+; CHECK-LABEL: define void @PR25926()
+define void @PR25926() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+ ; CHECK: entry:
+ ; CHECK: store i32 -1
+ ; CHECK: store i32 0
+ ; CHECK: invoke void @_CxxThrowException(
+ invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null)
+ to label %unreachable unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %0 = catchswitch within none [label %catch] unwind to caller
+
+catch: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [i8* null, i32 64, i8* null]
+ ; CHECK: catch:
+ ; CHECK: store i32 3
+ ; CHECK: invoke void @_CxxThrowException(
+ invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) [ "funclet"(token %1) ]
+ to label %unreachable1 unwind label %catch.dispatch1
+
+catch.dispatch1: ; preds = %catch
+ %2 = catchswitch within %1 [label %catch2] unwind label %ehcleanup
+
+catch2: ; preds = %catch.dispatch1
+ %3 = catchpad within %2 [i8* null, i32 64, i8* null]
+ catchret from %3 to label %try.cont
+
+try.cont: ; preds = %catch2
+ ; CHECK: try.cont:
+ ; CHECK: store i32 1
+ ; CHECK: call void @dtor()
+ call void @dtor() #3 [ "funclet"(token %1) ]
+ catchret from %1 to label %try.cont4
+
+try.cont4: ; preds = %try.cont
+ ret void
+
+ehcleanup: ; preds = %catch.dispatch1
+ %4 = cleanuppad within %1 []
+ ; CHECK: ehcleanup:
+ ; CHECK: store i32 -1
+ ; CHECK: call void @dtor()
+ call void @dtor() #3 [ "funclet"(token %4) ]
+ cleanupret from %4 unwind to caller
+
+unreachable: ; preds = %entry
+ unreachable
+
+unreachable1: ; preds = %catch
+ unreachable
+}
+
declare void @g(i32) #0
+declare void @dtor()
+
declare x86_stdcallcc void @_CxxThrowException(i8*, %eh.ThrowInfo*)
declare i32 @__CxxFrameHandler3(...)
More information about the llvm-commits
mailing list