Index: llvm/lib/Analysis/DependenceAnalysis.cpp =================================================================== --- llvm/lib/Analysis/DependenceAnalysis.cpp +++ llvm/lib/Analysis/DependenceAnalysis.cpp @@ -3304,16 +3304,6 @@ const SCEV *DstAccessFn, SmallVectorImpl &SrcSubscripts, SmallVectorImpl &DstSubscripts) { - // In general we cannot safely assume that the subscripts recovered from GEPs - // are in the range of values defined for their corresponding array - // dimensions. For example some C language usage/interpretation make it - // impossible to verify this at compile-time. As such we give up here unless - // we can assume that the subscripts do not overlap into neighboring - // dimensions and that the number of dimensions matches the number of - // subscripts being recovered. - if (!DisableDelinearizationChecks) - return false; - Value *SrcPtr = getLoadStorePointerOperand(Src); Value *DstPtr = getLoadStorePointerOperand(Dst); const SCEVUnknown *SrcBase = @@ -3352,22 +3342,54 @@ // Check that for identical base pointers we do not miss index offsets // that have been added before this GEP is applied. - if (SrcBasePtr == SrcBase->getValue() && DstBasePtr == DstBase->getValue()) { - assert(SrcSubscripts.size() == DstSubscripts.size() && - SrcSubscripts.size() == SrcSizes.size() + 1 && - "Expected equal number of entries in the list of sizes and " - "subscripts."); - LLVM_DEBUG({ - dbgs() << "Delinearized subscripts of fixed-size array\n" - << "SrcGEP:" << *SrcGEP << "\n" - << "DstGEP:" << *DstGEP << "\n"; - }); - return true; + if (SrcBasePtr != SrcBase->getValue() || DstBasePtr != DstBase->getValue()) { + SrcSubscripts.clear(); + DstSubscripts.clear(); + return false; } - - SrcSubscripts.clear(); - DstSubscripts.clear(); - return false; + // Statically check that the array bounds are in-range. + if (!DisableDelinearizationChecks) { + bool FailedRangeCheck = false; + size_t SrcSize = SrcSubscripts.size(); + for (size_t I = 1; I < SrcSize && !FailedRangeCheck; ++I) { + const auto *S = SrcSubscripts[I]; + if (!isKnownNonNegative(S, SrcPtr)) + FailedRangeCheck = true; + if (auto *SType = dyn_cast(S->getType())) { + const SCEV *Range = + SE->getConstant(ConstantInt::get(SType, SrcSizes[I - 1], false)); + if (!isKnownLessThan(S, Range)) + FailedRangeCheck = true; + } + } + size_t DstSize = DstSubscripts.size(); + for (size_t I = 1; I < DstSize && !FailedRangeCheck; ++I) { + const auto *S = DstSubscripts[I]; + if (!isKnownNonNegative(S, DstPtr)) + FailedRangeCheck = true; + if (auto *SType = dyn_cast(S->getType())) { + const SCEV *Range = + SE->getConstant(ConstantInt::get(SType, DstSizes[I - 1], false)); + if (!isKnownLessThan(S, Range)) + FailedRangeCheck = true; + } + } + if (FailedRangeCheck) { + SrcSubscripts.clear(); + DstSubscripts.clear(); + return false; + } + } + assert(SrcSubscripts.size() == DstSubscripts.size() && + SrcSubscripts.size() == SrcSizes.size() + 1 && + "Expected equal number of entries in the list of sizes and " + "subscripts."); + LLVM_DEBUG({ + dbgs() << "Delinearized subscripts of fixed-size array\n" + << "SrcGEP:" << *SrcGEP << "\n" + << "DstGEP:" << *DstGEP << "\n"; + }); + return true; } bool DependenceInfo::tryDelinearizeParametricSize( Index: llvm/test/Analysis/DependenceAnalysis/Coupled.ll =================================================================== --- llvm/test/Analysis/DependenceAnalysis/Coupled.ll +++ llvm/test/Analysis/DependenceAnalysis/Coupled.ll @@ -438,7 +438,8 @@ ; CHECK-LABEL: couple11 ; CHECK: da analyze - none! -; CHECK: da analyze - flow [=|<]! +; CHECK: da analyze - flow [=|<] splitable! +; CHECK: da analyze - split level = 1, iteration = 9! ; CHECK: da analyze - confused! ; CHECK: da analyze - none! ; CHECK: da analyze - confused! @@ -476,7 +477,8 @@ ; CHECK-LABEL: couple12 ; CHECK: da analyze - none! -; CHECK: da analyze - flow [<]! +; CHECK: da analyze - flow [<] splitable! +; CHECK: da analyze - split level = 1, iteration = 11! ; CHECK: da analyze - confused! ; CHECK: da analyze - none! ; CHECK: da analyze - confused! Index: llvm/test/Analysis/DependenceAnalysis/Invariant.ll =================================================================== --- llvm/test/Analysis/DependenceAnalysis/Invariant.ll +++ llvm/test/Analysis/DependenceAnalysis/Invariant.ll @@ -5,9 +5,18 @@ ; Test for a bug, which caused an assert when an invalid ; SCEVAddRecExpr is created in addToCoefficient. +; float foo (float g, float* rr[40]) { +; float res= 0.0f; +; for (int i = 0, j = 0; i < 40 && j < 40; i +=5, j+=5) { +; float add = rr[j][j] + rr[i][j]; +; res = add > g? add : res; +; } +; return res; +; } + ; CHECK-LABEL: foo ; CHECK: da analyze - consistent input [S 0]! -; CHECK: da analyze - input [* *|<]! +; CHECK: da analyze - input [* 0|<]! ; CHECK: da analyze - none! define float @foo(float %g, [40 x float]* %rr) nounwind { Index: llvm/test/Analysis/DependenceAnalysis/Separability.ll =================================================================== --- llvm/test/Analysis/DependenceAnalysis/Separability.ll +++ llvm/test/Analysis/DependenceAnalysis/Separability.ll @@ -17,7 +17,7 @@ entry: br label %for.cond1.preheader -; CHECK: da analyze - output [= * * S]! +; CHECK: da analyze - output [0 * * S]! ; CHECK: da analyze - flow [* * * *|<]! ; CHECK: da analyze - confused! ; CHECK: da analyze - input [* * S *]! @@ -92,7 +92,7 @@ entry: br label %for.cond1.preheader -; CHECK: da analyze - output [= * * S]! +; CHECK: da analyze - output [0 * * S]! ; CHECK: da analyze - flow [* * * *|<]! ; CHECK: da analyze - confused! ; CHECK: da analyze - input [* * S *]! @@ -166,10 +166,10 @@ entry: br label %for.cond1.preheader -; CHECK: da analyze - output [= S = =]! -; CHECK: da analyze - flow [* * * <>]! +; CHECK: da analyze - consistent output [0 S 0 0]! +; CHECK: da analyze - flow [> * * -10]! ; CHECK: da analyze - confused! -; CHECK: da analyze - input [= * * *]! +; CHECK: da analyze - input [0 * * 0]! ; CHECK: da analyze - confused! ; CHECK: da analyze - none! @@ -240,10 +240,10 @@ entry: br label %for.cond1.preheader -; CHECK: da analyze - output [= S = =]! -; CHECK: da analyze - flow [* * * *|<]! +; CHECK: da analyze - consistent output [0 S 0 0]! +; CHECK: da analyze - flow [> * * *]! ; CHECK: da analyze - confused! -; CHECK: da analyze - input [= * * *]! +; CHECK: da analyze - input [0 * * 0]! ; CHECK: da analyze - confused! ; CHECK: da analyze - none! Index: llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll =================================================================== --- llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll +++ llvm/test/Transforms/LoopInterchange/loop-interchange-optimization-remarks.ll @@ -178,12 +178,12 @@ br i1 %exitcond, label %for.body4, label %for.cond.loopexit } -; CHECK: --- !Missed +; CHECK: --- !Passed ; CHECK-NEXT: Pass: loop-interchange -; CHECK-NEXT: Name: Dependence +; CHECK-NEXT: Name: Interchanged ; CHECK-NEXT: Function: test03 ; CHECK-NEXT: Args: -; CHECK-NEXT: - String: Cannot interchange loops due to dependences. +; CHECK-NEXT: - String: Loop interchanged with enclosing loop. ; CHECK-NEXT: ... ; DELIN: --- !Passed Index: llvm/test/Transforms/LoopInterchange/profitability.ll =================================================================== --- llvm/test/Transforms/LoopInterchange/profitability.ll +++ llvm/test/Transforms/LoopInterchange/profitability.ll @@ -2,11 +2,6 @@ ; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange ; RUN: FileCheck -input-file %t %s -; RUN: opt < %s -loop-interchange -pass-remarks-output=%t -verify-dom-info -verify-loop-info \ -; RUN: -pass-remarks=loop-interchange -pass-remarks-missed=loop-interchange \ -; RUN: -da-disable-delinearization-checks -; RUN: FileCheck --check-prefix=DELIN -input-file %t %s - ;; We test profitability model in these test cases. target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -21,12 +16,9 @@ ;; for(int j=1;j<100;j++) ;; A[j][i] = A[j - 1][i] + B[j][i]; -; CHECK: Name: Dependence +; CHECK: Name: Interchanged ; CHECK-NEXT: Function: interchange_01 -; DELIN: Name: Interchanged -; DELIN-NEXT: Function: interchange_01 - define void @interchange_01() { entry: br label %for2.preheader