diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6589,6 +6589,26 @@ return nullptr; } +/// Fills \p Ops with unique operands of \p S, if it has operands. If not, +/// \p Ops remains unmodified. +static void collectUniqueOps(const SCEV *S, + SmallVectorImpl &Ops) { + SmallPtrSet Unique; + auto InsertUnique = [&](const SCEV *S) { + if (Unique.insert(S).second) + Ops.push_back(S); + }; + if (auto *S2 = dyn_cast(S)) + for (auto *Op : S2->operands()) + InsertUnique(Op); + else if (auto *S2 = dyn_cast(S)) + for (auto *Op : S2->operands()) + InsertUnique(Op); + else if (auto *S2 = dyn_cast(S)) + for (auto *Op : S2->operands()) + InsertUnique(Op); +} + const Instruction * ScalarEvolution::getDefiningScopeBound(ArrayRef Ops) { // Do a bounded search of the def relation of the requested SCEVs. @@ -6612,15 +6632,12 @@ if (auto *DefI = getNonTrivialDefiningScopeBound(S)) { if (!Bound || DT.dominates(Bound, DefI)) Bound = DefI; - } else if (auto *S2 = dyn_cast(S)) - for (auto *Op : S2->operands()) - pushOp(Op); - else if (auto *S2 = dyn_cast(S)) - for (auto *Op : S2->operands()) - pushOp(Op); - else if (auto *S2 = dyn_cast(S)) - for (auto *Op : S2->operands()) + } else { + SmallVector Ops; + collectUniqueOps(S, Ops); + for (auto *Op : Ops) pushOp(Op); + } } return Bound ? Bound : &*F.getEntryBlock().begin(); } @@ -12908,15 +12925,8 @@ // Verify intergity of SCEV users. for (const auto &S : UniqueSCEVs) { - SmallPtrSet Ops; - if (const auto *NS = dyn_cast(&S)) - Ops.insert(NS->op_begin(), NS->op_end()); - else if (const auto *CS = dyn_cast(&S)) - Ops.insert(CS->getOperand()); - else if (const auto *DS = dyn_cast(&S)) { - Ops.insert(DS->getLHS()); - Ops.insert(DS->getRHS()); - } + SmallVector Ops; + collectUniqueOps(&S, Ops); for (const auto *Op : Ops) { // We do not store dependencies of constants. if (isa(Op))