Skip to content

Commit 08c1e9e

Browse files
authored
[LAA] Revert 56a1cbb and 1aded51, due to crash (#160993)
This reverts commits 56a1cbb ([LAA] Fix non-NFC parts of 1aded51), 1aded51 ([LAA] Prepare to handle diff type sizes (NFC)). The original NFC patch caused some regressions, which the later patch tried to fix. However, the later patch is the cause of some crashes, and it would be best to revert both for now, and re-land after thorough testing.
1 parent fcf79e5 commit 08c1e9e

File tree

3 files changed

+35
-87
lines changed

3 files changed

+35
-87
lines changed

llvm/include/llvm/Analysis/LoopAccessAnalysis.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -413,30 +413,29 @@ class MemoryDepChecker {
413413
uint64_t MaxStride;
414414
std::optional<uint64_t> CommonStride;
415415

416-
/// TypeByteSize is a pair of alloc sizes of the source and sink.
417-
std::pair<uint64_t, uint64_t> TypeByteSize;
418-
419-
// HasSameSize is a boolean indicating whether the store sizes of the source
420-
// and sink are equal.
421-
// TODO: Remove this.
422-
bool HasSameSize;
416+
/// TypeByteSize is either the common store size of both accesses, or 0 when
417+
/// store sizes mismatch.
418+
uint64_t TypeByteSize;
423419

424420
bool AIsWrite;
425421
bool BIsWrite;
426422

427423
DepDistanceStrideAndSizeInfo(const SCEV *Dist, uint64_t MaxStride,
428424
std::optional<uint64_t> CommonStride,
429-
std::pair<uint64_t, uint64_t> TypeByteSize,
430-
bool HasSameSize, bool AIsWrite, bool BIsWrite)
425+
uint64_t TypeByteSize, bool AIsWrite,
426+
bool BIsWrite)
431427
: Dist(Dist), MaxStride(MaxStride), CommonStride(CommonStride),
432-
TypeByteSize(TypeByteSize), HasSameSize(HasSameSize),
433-
AIsWrite(AIsWrite), BIsWrite(BIsWrite) {}
428+
TypeByteSize(TypeByteSize), AIsWrite(AIsWrite), BIsWrite(BIsWrite) {}
434429
};
435430

436431
/// Get the dependence distance, strides, type size and whether it is a write
437-
/// for the dependence between A and B. Returns either a DepType, the
438-
/// dependence result, if it could already be determined, or a
439-
/// DepDistanceStrideAndSizeInfo struct.
432+
/// for the dependence between A and B. Returns a DepType, if we can prove
433+
/// there's no dependence or the analysis fails. Outlined to lambda to limit
434+
/// he scope of various temporary variables, like A/BPtr, StrideA/BPtr and
435+
/// others. Returns either the dependence result, if it could already be
436+
/// determined, or a DepDistanceStrideAndSizeInfo struct, noting that
437+
/// TypeByteSize could be 0 when store sizes mismatch, and this should be
438+
/// checked in the caller.
440439
std::variant<Dependence::DepType, DepDistanceStrideAndSizeInfo>
441440
getDependenceDistanceStrideAndSize(const MemAccessInfo &A, Instruction *AInst,
442441
const MemAccessInfo &B,

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,12 +2090,14 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
20902090
return MemoryDepChecker::Dependence::Unknown;
20912091
}
20922092

2093+
TypeSize AStoreSz = DL.getTypeStoreSize(ATy);
2094+
TypeSize BStoreSz = DL.getTypeStoreSize(BTy);
2095+
2096+
// If store sizes are not the same, set TypeByteSize to zero, so we can check
2097+
// it in the caller isDependent.
20932098
uint64_t ASz = DL.getTypeAllocSize(ATy);
20942099
uint64_t BSz = DL.getTypeAllocSize(BTy);
2095-
2096-
// Both the source and sink sizes are neeeded in dependence checks, depending
2097-
// on the use.
2098-
std::pair<uint64_t, uint64_t> TypeByteSize(ASz, BSz);
2100+
uint64_t TypeByteSize = (AStoreSz == BStoreSz) ? BSz : 0;
20992101

21002102
uint64_t StrideAScaled = std::abs(StrideAPtrInt) * ASz;
21012103
uint64_t StrideBScaled = std::abs(StrideBPtrInt) * BSz;
@@ -2117,24 +2119,8 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
21172119
return Dependence::Unknown;
21182120
}
21192121

2120-
// When the distance is possibly zero, we're reading/writing the same memory
2121-
// location: if the store sizes are not equal, fail with an unknown
2122-
// dependence.
2123-
TypeSize AStoreSz = DL.getTypeStoreSize(ATy);
2124-
TypeSize BStoreSz = DL.getTypeStoreSize(BTy);
2125-
if (AStoreSz != BStoreSz && SE.isKnownNonPositive(Dist) &&
2126-
SE.isKnownNonNegative(Dist)) {
2127-
LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence distance with "
2128-
"different type sizes\n");
2129-
return Dependence::Unknown;
2130-
}
2131-
2132-
// TODO: Remove this.
2133-
bool HasSameSize = AStoreSz == BStoreSz;
2134-
21352122
return DepDistanceStrideAndSizeInfo(Dist, MaxStride, CommonStride,
2136-
TypeByteSize, HasSameSize, AIsWrite,
2137-
BIsWrite);
2123+
TypeByteSize, AIsWrite, BIsWrite);
21382124
}
21392125

21402126
MemoryDepChecker::Dependence::DepType
@@ -2166,8 +2152,9 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
21662152
return std::get<Dependence::DepType>(Res);
21672153
}
21682154

2169-
auto &[Dist, MaxStride, CommonStride, TypeByteSize, HasSameSize, AIsWrite,
2170-
BIsWrite] = std::get<DepDistanceStrideAndSizeInfo>(Res);
2155+
auto &[Dist, MaxStride, CommonStride, TypeByteSize, AIsWrite, BIsWrite] =
2156+
std::get<DepDistanceStrideAndSizeInfo>(Res);
2157+
bool HasSameSize = TypeByteSize > 0;
21712158

21722159
ScalarEvolution &SE = *PSE.getSE();
21732160
auto &DL = InnermostLoop->getHeader()->getDataLayout();
@@ -2193,8 +2180,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
21932180
// If the distance between accesses and their strides are known constants,
21942181
// check whether the accesses interlace each other.
21952182
if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
2196-
areStridedAccessesIndependent(ConstDist, *CommonStride,
2197-
TypeByteSize.first)) {
2183+
areStridedAccessesIndependent(ConstDist, *CommonStride, TypeByteSize)) {
21982184
LLVM_DEBUG(dbgs() << "LAA: Strided accesses are independent\n");
21992185
return Dependence::NoDep;
22002186
}
@@ -2208,9 +2194,13 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
22082194
// Negative distances are not plausible dependencies.
22092195
if (SE.isKnownNonPositive(Dist)) {
22102196
if (SE.isKnownNonNegative(Dist)) {
2211-
// Write to the same location with the same size.
2212-
assert(HasSameSize && "Accesses must have the same size");
2213-
return Dependence::Forward;
2197+
if (HasSameSize) {
2198+
// Write to the same location with the same size.
2199+
return Dependence::Forward;
2200+
}
2201+
LLVM_DEBUG(dbgs() << "LAA: possibly zero dependence difference but "
2202+
"different type sizes\n");
2203+
return Dependence::Unknown;
22142204
}
22152205

22162206
bool IsTrueDataDependence = (AIsWrite && !BIsWrite);
@@ -2228,7 +2218,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
22282218
: Dependence::Unknown;
22292219
}
22302220
if (!HasSameSize ||
2231-
couldPreventStoreLoadForward(ConstDist, TypeByteSize.first)) {
2221+
couldPreventStoreLoadForward(ConstDist, TypeByteSize)) {
22322222
LLVM_DEBUG(
22332223
dbgs() << "LAA: Forward but may prevent st->ld forwarding\n");
22342224
return Dependence::ForwardButPreventsForwarding;
@@ -2294,8 +2284,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
22942284
// We know that Dist is positive, but it may not be constant. Use the signed
22952285
// minimum for computations below, as this ensures we compute the closest
22962286
// possible dependence distance.
2297-
uint64_t MinDistanceNeeded =
2298-
MaxStride * (MinNumIter - 1) + TypeByteSize.first;
2287+
uint64_t MinDistanceNeeded = MaxStride * (MinNumIter - 1) + TypeByteSize;
22992288
if (MinDistanceNeeded > static_cast<uint64_t>(MinDistance)) {
23002289
if (!ConstDist) {
23012290
// For non-constant distances, we checked the lower bound of the
@@ -2323,15 +2312,14 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
23232312

23242313
bool IsTrueDataDependence = (!AIsWrite && BIsWrite);
23252314
if (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
2326-
couldPreventStoreLoadForward(MinDistance, TypeByteSize.first,
2327-
*CommonStride))
2315+
couldPreventStoreLoadForward(MinDistance, TypeByteSize, *CommonStride))
23282316
return Dependence::BackwardVectorizableButPreventsForwarding;
23292317

23302318
uint64_t MaxVF = MinDepDistBytes / MaxStride;
23312319
LLVM_DEBUG(dbgs() << "LAA: Positive min distance " << MinDistance
23322320
<< " with max VF = " << MaxVF << '\n');
23332321

2334-
uint64_t MaxVFInBits = MaxVF * TypeByteSize.first * 8;
2322+
uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8;
23352323
if (!ConstDist && MaxVFInBits < MaxTargetVectorWidthInBits) {
23362324
// For non-constant distances, we checked the lower bound of the dependence
23372325
// distance and the distance may be larger at runtime (and safe for

llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -187,45 +187,6 @@ exit:
187187
ret void
188188
}
189189

190-
; In the following test, dependence distance is possibly zero,
191-
; but this is not equivalent to the condition known-non-positive
192-
; and known-non-negative.
193-
194-
define void @possibly_zero_dist_diff_typesz(ptr %p) {
195-
; CHECK-LABEL: 'possibly_zero_dist_diff_typesz'
196-
; CHECK-NEXT: loop:
197-
; CHECK-NEXT: Memory dependences are safe
198-
; CHECK-NEXT: Dependences:
199-
; CHECK-NEXT: Forward:
200-
; CHECK-NEXT: %ld.p = load i32, ptr %gep.p.iv.i32, align 1 ->
201-
; CHECK-NEXT: store i16 %trunc, ptr %gep.p.iv.i16, align 1
202-
; CHECK-EMPTY:
203-
; CHECK-NEXT: Run-time memory checks:
204-
; CHECK-NEXT: Grouped accesses:
205-
; CHECK-EMPTY:
206-
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
207-
; CHECK-NEXT: SCEV assumptions:
208-
; CHECK-EMPTY:
209-
; CHECK-NEXT: Expressions re-written:
210-
;
211-
entry:
212-
br label %loop
213-
214-
loop:
215-
%iv = phi i16 [ 0, %entry ], [ %iv.next, %loop ]
216-
%gep.p.iv.i32 = getelementptr inbounds nuw i32, ptr %p, i16 %iv
217-
%ld.p = load i32, ptr %gep.p.iv.i32, align 1
218-
%trunc = trunc i32 %ld.p to i16
219-
%gep.p.iv.i16 = getelementptr inbounds nuw i16, ptr %p, i16 %iv
220-
store i16 %trunc, ptr %gep.p.iv.i16, align 1
221-
%iv.next = add nuw nsw i16 %iv, 1
222-
%exit.cond = icmp eq i16 %iv.next, 32
223-
br i1 %exit.cond, label %exit, label %loop
224-
225-
exit:
226-
ret void
227-
}
228-
229190
; In the following test, the sink is loop-invariant.
230191

231192
define void @type_size_equivalence_sink_loopinv(ptr nocapture %vec, i64 %n) {

0 commit comments

Comments
 (0)