Index: lib/Analysis/DependenceAnalysis.cpp =================================================================== --- lib/Analysis/DependenceAnalysis.cpp +++ lib/Analysis/DependenceAnalysis.cpp @@ -848,6 +848,15 @@ } } +static const Loop *getLowestCommonAncestor(const Loop *A, const Loop *B) { + if (!A || !B) + return nullptr; + if (A == B) + return A; + if (A->getLoopDepth() > B->getLoopDepth()) + return getLowestCommonAncestor(A->getParentLoop(), B); + return getLowestCommonAncestor(A, B->getParentLoop()); +} // Examine the scev and return true iff it's linear. // Collect any loops mentioned in the set of "Loops". @@ -856,6 +865,7 @@ const SCEVAddRecExpr *AddRec = dyn_cast(Src); if (!AddRec) return isLoopInvariant(Src, LoopNest); + const auto *Loop = AddRec->getLoop(); const SCEV *Start = AddRec->getStart(); const SCEV *Step = AddRec->getStepRecurrence(*SE); const SCEV *UB = SE->getBackedgeTakenCount(AddRec->getLoop()); @@ -866,6 +876,12 @@ return false; } } + + // Test if the Loop this AddRec refers to is an ancestor of LoopNest + auto *LCA = getLowestCommonAncestor(Loop, LoopNest); + if (LCA && LCA != Loop) // Loop is a sibling or uncle of LoopNest. + return false; + if (!isLoopInvariant(Step, LoopNest)) return false; Loops.set(mapSrcLoop(AddRec->getLoop())); @@ -881,9 +897,10 @@ const SCEVAddRecExpr *AddRec = dyn_cast(Dst); if (!AddRec) return isLoopInvariant(Dst, LoopNest); + const auto *Loop = AddRec->getLoop(); const SCEV *Start = AddRec->getStart(); const SCEV *Step = AddRec->getStepRecurrence(*SE); - const SCEV *UB = SE->getBackedgeTakenCount(AddRec->getLoop()); + const SCEV *UB = SE->getBackedgeTakenCount(Loop); if (!isa(UB)) { if (SE->getTypeSizeInBits(Start->getType()) < SE->getTypeSizeInBits(UB->getType())) { @@ -891,9 +908,14 @@ return false; } } + // Test if the Loop this AddRec refers to is an ancestor of LoopNest + auto *LCA = getLowestCommonAncestor(Loop, LoopNest); + if (LCA && LCA != Loop) // Loop is a sibling or uncle of LoopNest. + return false; + if (!isLoopInvariant(Step, LoopNest)) return false; - Loops.set(mapDstLoop(AddRec->getLoop())); + Loops.set(mapDstLoop(Loop)); return checkDstSubscript(Start, LoopNest, Loops); } Index: test/Analysis/DependenceAnalysis/pr31848.c =================================================================== --- /dev/null +++ test/Analysis/DependenceAnalysis/pr31848.c @@ -0,0 +1,21 @@ +// RUN: clang %s -O1 -o - -emit-llvm -c | opt -da -analyze 2>&1 | FileCheck %s + +void foo(int *A, int n) { + for (int j = 0; j < n; ++j) { + for (int i = 0; i < n; ++i) { + for (int di = -1; di <= 1; ++di) { + for (int dj = -1; dj <= 1; ++dj) { + int x = i + di; + int y = j + dj; + while (x < 0) + x += n; + while (y < 0) + y += n; + + // CHECK: da analyze - output [* * * *] + A[y * n + x] = 7; + } + } + } + } +}