Skip to content

Commit 854179f

Browse files
artagnonTIFitis
authored andcommitted
[LAA/SLP] Don't truncate APInt in getPointersDiff (llvm#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 llvm#139202.
1 parent 4f92dc1 commit 854179f

File tree

4 files changed

+125
-103
lines changed

4 files changed

+125
-103
lines changed

llvm/include/llvm/Analysis/LoopAccessAnalysis.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -853,11 +853,10 @@ getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
853853
/// is a simple API that does not depend on the analysis pass.
854854
/// \param StrictCheck Ensure that the calculated distance matches the
855855
/// type-based one after all the bitcasts removal in the provided pointers.
856-
std::optional<int> getPointersDiff(Type *ElemTyA, Value *PtrA, Type *ElemTyB,
857-
Value *PtrB, const DataLayout &DL,
858-
ScalarEvolution &SE,
859-
bool StrictCheck = false,
860-
bool CheckType = true);
856+
std::optional<int64_t>
857+
getPointersDiff(Type *ElemTyA, Value *PtrA, Type *ElemTyB, Value *PtrB,
858+
const DataLayout &DL, ScalarEvolution &SE,
859+
bool StrictCheck = false, bool CheckType = true);
861860

862861
/// Attempt to sort the pointers in \p VL and return the sorted indices
863862
/// in \p SortedIndices, if reordering is required.

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,11 +1541,11 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
15411541
return std::nullopt;
15421542
}
15431543

1544-
std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA,
1545-
Type *ElemTyB, Value *PtrB,
1546-
const DataLayout &DL,
1547-
ScalarEvolution &SE, bool StrictCheck,
1548-
bool CheckType) {
1544+
std::optional<int64_t> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA,
1545+
Type *ElemTyB, Value *PtrB,
1546+
const DataLayout &DL,
1547+
ScalarEvolution &SE,
1548+
bool StrictCheck, bool CheckType) {
15491549
assert(PtrA && PtrB && "Expected non-nullptr pointers.");
15501550

15511551
// Make sure that A and B are different pointers.
@@ -1570,7 +1570,7 @@ std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA,
15701570
const Value *PtrB1 = PtrB->stripAndAccumulateConstantOffsets(
15711571
DL, OffsetB, /*AllowNonInbounds=*/true);
15721572

1573-
int Val;
1573+
std::optional<int64_t> Val;
15741574
if (PtrA1 == PtrB1) {
15751575
// Retrieve the address space again as pointer stripping now tracks through
15761576
// `addrspacecast`.
@@ -1585,7 +1585,7 @@ std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA,
15851585
OffsetB = OffsetB.sextOrTrunc(IdxWidth);
15861586

15871587
OffsetB -= OffsetA;
1588-
Val = OffsetB.getSExtValue();
1588+
Val = OffsetB.trySExtValue();
15891589
} else {
15901590
// Otherwise compute the distance with SCEV between the base pointers.
15911591
const SCEV *PtrSCEVA = SE.getSCEV(PtrA);
@@ -1594,10 +1594,14 @@ std::optional<int> llvm::getPointersDiff(Type *ElemTyA, Value *PtrA,
15941594
SE.computeConstantDifference(PtrSCEVB, PtrSCEVA);
15951595
if (!Diff)
15961596
return std::nullopt;
1597-
Val = Diff->getSExtValue();
1597+
Val = Diff->trySExtValue();
15981598
}
1599-
int Size = DL.getTypeStoreSize(ElemTyA);
1600-
int Dist = Val / Size;
1599+
1600+
if (!Val)
1601+
return std::nullopt;
1602+
1603+
int64_t Size = DL.getTypeStoreSize(ElemTyA);
1604+
int64_t Dist = *Val / Size;
16011605

16021606
// Ensure that the calculated distance matches the type-based one after all
16031607
// the bitcasts removal in the provided pointers.
@@ -1616,14 +1620,15 @@ bool llvm::sortPtrAccesses(ArrayRef<Value *> VL, Type *ElemTy,
16161620
// first pointer in the array.
16171621
Value *Ptr0 = VL[0];
16181622

1619-
using DistOrdPair = std::pair<int64_t, int>;
1623+
using DistOrdPair = std::pair<int64_t, unsigned>;
16201624
auto Compare = llvm::less_first();
16211625
std::set<DistOrdPair, decltype(Compare)> Offsets(Compare);
16221626
Offsets.emplace(0, 0);
16231627
bool IsConsecutive = true;
16241628
for (auto [Idx, Ptr] : drop_begin(enumerate(VL))) {
1625-
std::optional<int> Diff = getPointersDiff(ElemTy, Ptr0, ElemTy, Ptr, DL, SE,
1626-
/*StrictCheck=*/true);
1629+
std::optional<int64_t> Diff =
1630+
getPointersDiff(ElemTy, Ptr0, ElemTy, Ptr, DL, SE,
1631+
/*StrictCheck=*/true);
16271632
if (!Diff)
16281633
return false;
16291634

@@ -1654,7 +1659,7 @@ bool llvm::isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL,
16541659
return false;
16551660
Type *ElemTyA = getLoadStoreType(A);
16561661
Type *ElemTyB = getLoadStoreType(B);
1657-
std::optional<int> Diff =
1662+
std::optional<int64_t> Diff =
16581663
getPointersDiff(ElemTyA, PtrA, ElemTyB, PtrB, DL, SE,
16591664
/*StrictCheck=*/true, CheckType);
16601665
return Diff && *Diff == 1;

0 commit comments

Comments
 (0)