Skip to content

Commit 411488b

Browse files
committed
[CodeGenPrepare] Limit recursion depth for collectBitParts
Summary: Seeing some issues for windows debug pathological cases with collectBitParts recursion (1525 levels of recursion!) Setting the limit to 64 as this should be sufficient - passes all lit cases Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61728 Change-Id: I7f44cdc6c1badf1c2ccbf1b0c4b6afe27ecb39a1 llvm-svn: 360347
1 parent f58a5c8 commit 411488b

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ using namespace llvm::PatternMatch;
9191

9292
STATISTIC(NumRemoved, "Number of unreachable basic blocks removed");
9393

94+
// Max recursion depth for collectBitParts used when detecting bswap and
95+
// bitreverse idioms
96+
static const unsigned BitPartRecursionMaxDepth = 64;
97+
9498
//===----------------------------------------------------------------------===//
9599
// Local constant propagation.
96100
//
@@ -2619,21 +2623,27 @@ struct BitPart {
26192623
/// does not invalidate internal references (std::map instead of DenseMap).
26202624
static const Optional<BitPart> &
26212625
collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
2622-
std::map<Value *, Optional<BitPart>> &BPS) {
2626+
std::map<Value *, Optional<BitPart>> &BPS, int Depth) {
26232627
auto I = BPS.find(V);
26242628
if (I != BPS.end())
26252629
return I->second;
26262630

26272631
auto &Result = BPS[V] = None;
26282632
auto BitWidth = cast<IntegerType>(V->getType())->getBitWidth();
26292633

2634+
// Prevent stack overflow by limiting the recursion depth
2635+
if (Depth == BitPartRecursionMaxDepth) {
2636+
LLVM_DEBUG(dbgs() << "collectBitParts max recursion depth reached.\n");
2637+
return Result;
2638+
}
2639+
26302640
if (Instruction *I = dyn_cast<Instruction>(V)) {
26312641
// If this is an or instruction, it may be an inner node of the bswap.
26322642
if (I->getOpcode() == Instruction::Or) {
26332643
auto &A = collectBitParts(I->getOperand(0), MatchBSwaps,
2634-
MatchBitReversals, BPS);
2644+
MatchBitReversals, BPS, Depth + 1);
26352645
auto &B = collectBitParts(I->getOperand(1), MatchBSwaps,
2636-
MatchBitReversals, BPS);
2646+
MatchBitReversals, BPS, Depth + 1);
26372647
if (!A || !B)
26382648
return Result;
26392649

@@ -2666,7 +2676,7 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
26662676
return Result;
26672677

26682678
auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps,
2669-
MatchBitReversals, BPS);
2679+
MatchBitReversals, BPS, Depth + 1);
26702680
if (!Res)
26712681
return Result;
26722682
Result = Res;
@@ -2698,7 +2708,7 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
26982708
return Result;
26992709

27002710
auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps,
2701-
MatchBitReversals, BPS);
2711+
MatchBitReversals, BPS, Depth + 1);
27022712
if (!Res)
27032713
return Result;
27042714
Result = Res;
@@ -2713,7 +2723,7 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
27132723
// If this is a zext instruction zero extend the result.
27142724
if (I->getOpcode() == Instruction::ZExt) {
27152725
auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps,
2716-
MatchBitReversals, BPS);
2726+
MatchBitReversals, BPS, Depth + 1);
27172727
if (!Res)
27182728
return Result;
27192729

@@ -2775,7 +2785,7 @@ bool llvm::recognizeBSwapOrBitReverseIdiom(
27752785

27762786
// Try to find all the pieces corresponding to the bswap.
27772787
std::map<Value *, Optional<BitPart>> BPS;
2778-
auto Res = collectBitParts(I, MatchBSwaps, MatchBitReversals, BPS);
2788+
auto Res = collectBitParts(I, MatchBSwaps, MatchBitReversals, BPS, 0);
27792789
if (!Res)
27802790
return false;
27812791
auto &BitProvenance = Res->Provenance;

0 commit comments

Comments
 (0)