diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index bc8b9b8479e4ff..58ea395fc88ffa 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -2873,21 +2873,6 @@ static Value *stripGetElementPtr(Value *Ptr, ScalarEvolution *SE, Loop *Lp) { return GEP->getOperand(InductionOperand); } -/// If a value has only one user that is a CastInst, return it. -static Value *getUniqueCastUse(Value *Ptr, Loop *Lp, Type *Ty) { - Value *UniqueCast = nullptr; - for (User *U : Ptr->users()) { - CastInst *CI = dyn_cast(U); - if (CI && CI->getType() == Ty) { - if (!UniqueCast) - UniqueCast = CI; - else - return nullptr; - } - } - return UniqueCast; -} - /// Get the stride of a pointer access in a loop. Looks for symbolic /// strides "a[i*stride]". Returns the symbolic stride, or null otherwise. static const SCEV *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp) { @@ -2950,21 +2935,14 @@ static const SCEV *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *L return nullptr; // Look for the loop invariant symbolic value. - const SCEVUnknown *U = dyn_cast(V); - if (!U) { - const auto *C = dyn_cast(V); - if (!C) - return nullptr; - U = dyn_cast(C->getOperand()); - if (!U) - return nullptr; + if (isa(V)) + return V; - // Match legacy behavior - this is not needed for correctness - if (!getUniqueCastUse(U->getValue(), Lp, V->getType())) - return nullptr; - } + if (const auto *C = dyn_cast(V)) + if (isa(C->getOperand())) + return V; - return V; + return nullptr; } void LoopAccessInfo::collectStridedAccess(Value *MemAccess) { diff --git a/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll b/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll index 3da0f543c5c1ca..8641f0a618b879 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/symbolic-stride.ll @@ -170,16 +170,23 @@ define void @single_stride_castexpr_multiuse(i32 %offset, ptr %src, ptr %dst, i1 ; CHECK-NEXT: %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3 ; CHECK-NEXT: Grouped accesses: ; CHECK-NEXT: Group [[GRP3]]: -; CHECK-NEXT: (Low: (((4 * %iv.1) + %dst) umin ((4 * %iv.1) + (4 * (sext i32 %offset to i64) * (200 + (-1 * (zext i32 %offset to i64)))) + %dst)) High: (4 + (((4 * %iv.1) + %dst) umax ((4 * %iv.1) + (4 * (sext i32 %offset to i64) * (200 + (-1 * (zext i32 %offset to i64)))) + %dst)))) -; CHECK-NEXT: Member: {((4 * %iv.1) + %dst),+,(4 * (sext i32 %offset to i64))}<%inner.loop> +; CHECK-NEXT: (Low: ((4 * %iv.1) + %dst) High: (804 + (4 * %iv.1) + (-4 * (zext i32 %offset to i64)) + %dst)) +; CHECK-NEXT: Member: {((4 * %iv.1) + %dst),+,4}<%inner.loop> ; CHECK-NEXT: Group [[GRP4]]: -; CHECK-NEXT: (Low: ((4 * (zext i32 %offset to i64)) + %src) High: (804 + %src)) -; CHECK-NEXT: Member: {((4 * (zext i32 %offset to i64)) + %src),+,4}<%inner.loop> +; CHECK-NEXT: (Low: (4 + %src) High: (808 + (-4 * (zext i32 %offset to i64)) + %src)) +; CHECK-NEXT: Member: {(4 + %src),+,4}<%inner.loop> ; CHECK-EMPTY: ; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. ; CHECK-NEXT: SCEV assumptions: +; CHECK-NEXT: Equal predicate: %offset == 1 ; CHECK-EMPTY: ; CHECK-NEXT: Expressions re-written: +; CHECK-NEXT: [PSE] %gep.src = getelementptr inbounds i32, ptr %src, i64 %iv.3: +; CHECK-NEXT: {((4 * (zext i32 %offset to i64)) + %src),+,4}<%inner.loop> +; CHECK-NEXT: --> {(4 + %src),+,4}<%inner.loop> +; CHECK-NEXT: [PSE] %gep.dst = getelementptr i32, ptr %dst, i64 %iv.2: +; CHECK-NEXT: {((4 * %iv.1) + %dst),+,(4 * (sext i32 %offset to i64))}<%inner.loop> +; CHECK-NEXT: --> {((4 * %iv.1) + %dst),+,4}<%inner.loop> ; CHECK-NEXT: outer.header: ; CHECK-NEXT: Report: loop is not the innermost loop ; CHECK-NEXT: Dependences: