diff options
author | Ramkumar Ramachandra <ramkumar.ramachandra@codasip.com> | 2025-05-15 10:08:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-15 10:08:05 +0100 |
commit | c807395011a027caae9ac196edfac328fb90443a (patch) | |
tree | d054df8fa76765513be878c561e79d3c5ff6071a /llvm/lib/Analysis/LoopAccessAnalysis.cpp | |
parent | 8bd35ca41253ea36fff78d5acf59956a30b6555b (diff) | |
download | llvm-c807395011a027caae9ac196edfac328fb90443a.zip llvm-c807395011a027caae9ac196edfac328fb90443a.tar.gz llvm-c807395011a027caae9ac196edfac328fb90443a.tar.bz2 |
[LAA/SLP] Don't truncate APInt in getPointersDiff (#139941)
Change getPointersDiff to return an std::optional<int64_t>, and fill
this value with using APInt::trySExtValue. This simple change requires
changes to other functions in LAA, and major changes in SLPVectorizer
changing types from 32-bit to 64-bit.
Fixes #139202.
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/LoopAccessAnalysis.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index af1a3c5..ab407e9 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1541,11 +1541,11 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr, return std::nullopt; } -std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA, - Type *ElemTyB, Value *PtrB, - const DataLayout &DL, - ScalarEvolution &SE, bool StrictCheck, - bool CheckType) { +std::optional<int64_t> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA, + Type *ElemTyB, Value *PtrB, + const DataLayout &DL, + ScalarEvolution &SE, + bool StrictCheck, bool CheckType) { assert(PtrA && PtrB && "Expected non-nullptr pointers."); // Make sure that A and B are different pointers. @@ -1570,7 +1570,7 @@ std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA, const Value *PtrB1 = PtrB->stripAndAccumulateConstantOffsets( DL, OffsetB, /*AllowNonInbounds=*/true); - int Val; + std::optional<int64_t> Val; if (PtrA1 == PtrB1) { // Retrieve the address space again as pointer stripping now tracks through // `addrspacecast`. @@ -1585,7 +1585,7 @@ std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA, OffsetB = OffsetB.sextOrTrunc(IdxWidth); OffsetB -= OffsetA; - Val = OffsetB.getSExtValue(); + Val = OffsetB.trySExtValue(); } else { // Otherwise compute the distance with SCEV between the base pointers. const SCEV *PtrSCEVA = SE.getSCEV(PtrA); @@ -1594,10 +1594,14 @@ std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA, SE.computeConstantDifference(PtrSCEVB, PtrSCEVA); if (!Diff) return std::nullopt; - Val = Diff->getSExtValue(); + Val = Diff->trySExtValue(); } - int Size = DL.getTypeStoreSize(ElemTyA); - int Dist = Val / Size; + + if (!Val) + return std::nullopt; + + int64_t Size = DL.getTypeStoreSize(ElemTyA); + int64_t Dist = *Val / Size; // Ensure that the calculated distance matches the type-based one after all // the bitcasts removal in the provided pointers. @@ -1616,14 +1620,15 @@ bool llvm::sortPtrAccesses(ArrayRef<Value *> VL, Type *ElemTy, // first pointer in the array. Value *Ptr0 = VL[0]; - using DistOrdPair = std::pair<int64_t, int>; + using DistOrdPair = std::pair<int64_t, unsigned>; auto Compare = llvm::less_first(); std::set<DistOrdPair, decltype(Compare)> Offsets(Compare); Offsets.emplace(0, 0); bool IsConsecutive = true; for (auto [Idx, Ptr] : drop_begin(enumerate(VL))) { - std::optional<int> Diff = getPointersDiff(ElemTy, Ptr0, ElemTy, Ptr, DL, SE, - /*StrictCheck=*/true); + std::optional<int64_t> Diff = + getPointersDiff(ElemTy, Ptr0, ElemTy, Ptr, DL, SE, + /*StrictCheck=*/true); if (!Diff) return false; @@ -1654,7 +1659,7 @@ bool llvm::isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL, return false; Type *ElemTyA = getLoadStoreType(A); Type *ElemTyB = getLoadStoreType(B); - std::optional<int> Diff = + std::optional<int64_t> Diff = getPointersDiff(ElemTyA, PtrA, ElemTyB, PtrB, DL, SE, /*StrictCheck=*/true, CheckType); return Diff && *Diff == 1; |