Currently SCEV assumes that all recurrences used by a given SCEV need to dominate each other. In other words there must be a total ordering on the set of loops used in a SCEV expression. When doing MIV tests on accesses in two sibling loops that are triangular, we can run into a problem because the loops in SCEV expressions for the bounds of one access do not necessarily dominate the SCEV expressions for the bounds of the other access. For example, with an LLVM_ASSERT="on" build, we get a crash in ScalarEvolution when we running DependenceAnalysis on the following code (see the LIT test bellow for the IR):
void foo(int *restrict A, int n1, int n2, int n3) { for (int i1 = 0; i1 < n1; i1++) { for (int i2 = 2; i2 < n2; i2++) { for (int i3 = i2 + 1; i3 < n3; i3++) { A[i2 + i3*n2] = 11; } } for (int i4 = 2; i4 < n3; i4++) { for (int i5 = 1; i5 < i4 - 1; i5++) { A[i5] = 22; } } } }
ScalarEvolution.cpp:736: int CompareSCEVComplexity(EquivalenceClasses<const llvm::SCEV *> &, EquivalenceClasses<const llvm::Value *> &, const llvm::LoopInfo *const, const llvm::SCEV *, const llvm::SCEV *, llvm::DominatorTree &, unsigned int): Assertion `DT.dominates(RHead, LHead) && "No dominance between recurrences used by one SCEV?"' failed. Stack dump: ... #9 0x00007c9e3a1845d8 CompareSCEVComplexity(llvm::EquivalenceClasses<llvm::SCEV const*>&, llvm::EquivalenceClasses<llvm::Value const*>&, llvm::LoopInfo const*, llvm::SCEV const*, llvm::SCEV const*, llvm::DominatorTree&, unsigned int) #10 0x00007c9e3a145854 GroupByComplexity(llvm::SmallVectorImpl<llvm::SCEV const*>&, llvm::LoopInfo*, llvm::DominatorTree&) #11 0x00007c9e3a138b08 llvm::ScalarEvolution::getAddExpr(llvm::SmallVectorImpl<llvm::SCEV const*>&, llvm::SCEV::NoWrapFlags, unsigned int) #12 0x00007c9e39f7d300 llvm::DependenceInfo::testBounds(unsigned char, unsigned int, llvm::DependenceInfo::BoundInfo*, llvm::SCEV const*) const #13 0x00007c9e39f7c32c llvm::DependenceInfo::banerjeeMIVtest(llvm::SCEV const*, llvm::SCEV const*, llvm::SmallBitVector const&, llvm::FullDependence&) const #14 0x00007c9e39f7ba80 llvm::DependenceInfo::testMIV(llvm::SCEV const*, llvm::SCEV const*, llvm::SmallBitVector const&, llvm::FullDependence&) const #15 0x00007c9e39f857b0 llvm::DependenceInfo::depends(llvm::Instruction*, llvm::Instruction*, bool)
This patch adds a query to ScalarEvolution to be able to examine a list of SCEV expressions and determine if the total ordering constraint holds for the set of associated loops. The MIV test uses this facility to check if the bounds can even be represented by SCEV, and return if the check fails.
Since satisfiesTotalOrder does not add Exprs, (Mutable)ArrayRef might be sufficient as arguments.