summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-12-23 03:59:04 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-12-23 03:59:04 +0000
commitc640f863e03ec8df606858e054025bec8fc2507c (patch)
tree3ad9fa641feff3638c6706e0a97c7e083a57521c /llvm/lib
parentce7d39d5e1724e1643f784c1bc625522dcdbfc42 (diff)
downloadbcm5719-llvm-c640f863e03ec8df606858e054025bec8fc2507c.tar.gz
bcm5719-llvm-c640f863e03ec8df606858e054025bec8fc2507c.zip
[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. llvm-svn: 256317
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/WinEHPrepare.cpp22
1 files changed, 15 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp
index 3b076b65e69..dc9f78f006a 100644
--- a/llvm/lib/CodeGen/WinEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WinEHPrepare.cpp
@@ -165,8 +165,7 @@ static void calculateStateNumbersForInvokes(const Function *Fn,
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(WinEHFuncInfo &FuncInfo,
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(WinEHFuncInfo &FuncInfo,
// 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);
OpenPOWER on IntegriCloud