Index: llvm/trunk/lib/Transforms/Utils/Local.cpp =================================================================== --- llvm/trunk/lib/Transforms/Utils/Local.cpp +++ llvm/trunk/lib/Transforms/Utils/Local.cpp @@ -91,6 +91,10 @@ STATISTIC(NumRemoved, "Number of unreachable basic blocks removed"); +// Max recursion depth for collectBitParts used when detecting bswap and +// bitreverse idioms +static const unsigned BitPartRecursionMaxDepth = 64; + //===----------------------------------------------------------------------===// // Local constant propagation. // @@ -2619,7 +2623,7 @@ /// does not invalidate internal references (std::map instead of DenseMap). static const Optional & collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals, - std::map> &BPS) { + std::map> &BPS, int Depth) { auto I = BPS.find(V); if (I != BPS.end()) return I->second; @@ -2627,13 +2631,19 @@ auto &Result = BPS[V] = None; auto BitWidth = cast(V->getType())->getBitWidth(); + // Prevent stack overflow by limiting the recursion depth + if (Depth == BitPartRecursionMaxDepth) { + LLVM_DEBUG(dbgs() << "collectBitParts max recursion depth reached.\n"); + return Result; + } + if (Instruction *I = dyn_cast(V)) { // If this is an or instruction, it may be an inner node of the bswap. if (I->getOpcode() == Instruction::Or) { auto &A = collectBitParts(I->getOperand(0), MatchBSwaps, - MatchBitReversals, BPS); + MatchBitReversals, BPS, Depth + 1); auto &B = collectBitParts(I->getOperand(1), MatchBSwaps, - MatchBitReversals, BPS); + MatchBitReversals, BPS, Depth + 1); if (!A || !B) return Result; @@ -2666,7 +2676,7 @@ return Result; auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps, - MatchBitReversals, BPS); + MatchBitReversals, BPS, Depth + 1); if (!Res) return Result; Result = Res; @@ -2698,7 +2708,7 @@ return Result; auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps, - MatchBitReversals, BPS); + MatchBitReversals, BPS, Depth + 1); if (!Res) return Result; Result = Res; @@ -2713,7 +2723,7 @@ // If this is a zext instruction zero extend the result. if (I->getOpcode() == Instruction::ZExt) { auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps, - MatchBitReversals, BPS); + MatchBitReversals, BPS, Depth + 1); if (!Res) return Result; @@ -2775,7 +2785,7 @@ // Try to find all the pieces corresponding to the bswap. std::map> BPS; - auto Res = collectBitParts(I, MatchBSwaps, MatchBitReversals, BPS); + auto Res = collectBitParts(I, MatchBSwaps, MatchBitReversals, BPS, 0); if (!Res) return false; auto &BitProvenance = Res->Provenance;