Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,7 @@ static int CompareValueComplexity(const LoopInfo *const LI, Value *LV,
// If the max analysis depth was reached, return std::nullopt, assuming we do
// not know if they are equivalent for sure.
static std::optional<int>
CompareSCEVComplexity(EquivalenceClasses<const SCEV *> &EqCacheSCEV,
const LoopInfo *const LI, const SCEV *LHS,
CompareSCEVComplexity(const LoopInfo *const LI, const SCEV *LHS,
const SCEV *RHS, DominatorTree &DT, unsigned Depth = 0) {
// Fast-path: SCEVs are uniqued so we can do a quick equality check.
if (LHS == RHS)
Expand All @@ -665,9 +664,6 @@ CompareSCEVComplexity(EquivalenceClasses<const SCEV *> &EqCacheSCEV,
if (LType != RType)
return (int)LType - (int)RType;

if (EqCacheSCEV.isEquivalent(LHS, RHS))
return 0;

if (Depth > MaxSCEVCompareDepth)
return std::nullopt;

Expand All @@ -681,8 +677,6 @@ CompareSCEVComplexity(EquivalenceClasses<const SCEV *> &EqCacheSCEV,

int X =
CompareValueComplexity(LI, LU->getValue(), RU->getValue(), Depth + 1);
if (X == 0)
EqCacheSCEV.unionSets(LHS, RHS);
return X;
}

Expand Down Expand Up @@ -747,12 +741,10 @@ CompareSCEVComplexity(EquivalenceClasses<const SCEV *> &EqCacheSCEV,
return (int)LNumOps - (int)RNumOps;

for (unsigned i = 0; i != LNumOps; ++i) {
auto X = CompareSCEVComplexity(EqCacheSCEV, LI, LOps[i], ROps[i], DT,
Depth + 1);
auto X = CompareSCEVComplexity(LI, LOps[i], ROps[i], DT, Depth + 1);
if (X != 0)
return X;
}
EqCacheSCEV.unionSets(LHS, RHS);
return 0;
}

Expand All @@ -775,11 +767,9 @@ static void GroupByComplexity(SmallVectorImpl<const SCEV *> &Ops,
LoopInfo *LI, DominatorTree &DT) {
if (Ops.size() < 2) return; // Noop

EquivalenceClasses<const SCEV *> EqCacheSCEV;

// Whether LHS has provably less complexity than RHS.
auto IsLessComplex = [&](const SCEV *LHS, const SCEV *RHS) {
auto Complexity = CompareSCEVComplexity(EqCacheSCEV, LI, LHS, RHS, DT);
auto Complexity = CompareSCEVComplexity(LI, LHS, RHS, DT);
return Complexity && *Complexity < 0;
};
if (Ops.size() == 2) {
Expand Down
31 changes: 31 additions & 0 deletions llvm/unittests/Analysis/ScalarEvolutionTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1706,4 +1706,35 @@ TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering) {
});
}

TEST_F(ScalarEvolutionsTest, ComplexityComparatorIsStrictWeakOrdering2) {
// Regression test for a case where caching of equivalent values caused the
// comparator to get inconsistent.

Type *Int64Ty = Type::getInt64Ty(Context);
Type *PtrTy = PointerType::get(Context, 0);
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
{PtrTy, PtrTy, PtrTy, Int64Ty}, false);
Function *F = Function::Create(FTy, Function::ExternalLinkage, "f", M);
BasicBlock *BB = BasicBlock::Create(Context, "entry", F);
ReturnInst::Create(Context, nullptr, BB);

ScalarEvolution SE = buildSE(*F);

const SCEV *S0 = SE.getSCEV(F->getArg(0));
const SCEV *S1 = SE.getSCEV(F->getArg(1));
const SCEV *S2 = SE.getSCEV(F->getArg(2));

const SCEV *P0 = SE.getPtrToIntExpr(S0, Int64Ty);
const SCEV *P1 = SE.getPtrToIntExpr(S1, Int64Ty);
const SCEV *P2 = SE.getPtrToIntExpr(S2, Int64Ty);

const SCEV *M0 = SE.getNegativeSCEV(P0);
const SCEV *M2 = SE.getNegativeSCEV(P2);

SmallVector<const SCEV *, 6> Ops = {M2, P0, M0, P1, P2};
// When _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG, this will
// crash if the comparator has the specific caching bug.
SE.getAddExpr(Ops);
}

} // end namespace llvm
Loading