@@ -2090,14 +2090,12 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
2090
2090
return MemoryDepChecker::Dependence::Unknown;
2091
2091
}
2092
2092
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.
2098
2093
uint64_t ASz = DL.getTypeAllocSize (ATy);
2099
2094
uint64_t BSz = DL.getTypeAllocSize (BTy);
2100
- uint64_t TypeByteSize = (AStoreSz == BStoreSz) ? BSz : 0 ;
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);
2101
2099
2102
2100
uint64_t StrideAScaled = std::abs (StrideAPtrInt) * ASz;
2103
2101
uint64_t StrideBScaled = std::abs (StrideBPtrInt) * BSz;
@@ -2119,8 +2117,23 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
2119
2117
return Dependence::Unknown;
2120
2118
}
2121
2119
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.isKnownNonZero (Dist)) {
2126
+ LLVM_DEBUG (dbgs () << " LAA: possibly zero dependence distance with "
2127
+ " different type sizes\n " );
2128
+ return Dependence::Unknown;
2129
+ }
2130
+
2131
+ // TODO: Remove this.
2132
+ bool HasSameSize = AStoreSz == BStoreSz;
2133
+
2122
2134
return DepDistanceStrideAndSizeInfo (Dist, MaxStride, CommonStride,
2123
- TypeByteSize, AIsWrite, BIsWrite);
2135
+ TypeByteSize, HasSameSize, AIsWrite,
2136
+ BIsWrite);
2124
2137
}
2125
2138
2126
2139
MemoryDepChecker::Dependence::DepType
@@ -2152,9 +2165,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
2152
2165
return std::get<Dependence::DepType>(Res);
2153
2166
}
2154
2167
2155
- auto &[Dist, MaxStride, CommonStride, TypeByteSize, AIsWrite, BIsWrite] =
2156
- std::get<DepDistanceStrideAndSizeInfo>(Res);
2157
- bool HasSameSize = TypeByteSize > 0 ;
2168
+ auto &[Dist, MaxStride, CommonStride, TypeByteSize, HasSameSize, AIsWrite,
2169
+ BIsWrite] = std::get<DepDistanceStrideAndSizeInfo>(Res);
2158
2170
2159
2171
ScalarEvolution &SE = *PSE.getSE ();
2160
2172
auto &DL = InnermostLoop->getHeader ()->getDataLayout ();
@@ -2180,7 +2192,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
2180
2192
// If the distance between accesses and their strides are known constants,
2181
2193
// check whether the accesses interlace each other.
2182
2194
if (ConstDist > 0 && CommonStride && CommonStride > 1 && HasSameSize &&
2183
- areStridedAccessesIndependent (ConstDist, *CommonStride, TypeByteSize)) {
2195
+ areStridedAccessesIndependent (ConstDist, *CommonStride,
2196
+ TypeByteSize.first )) {
2184
2197
LLVM_DEBUG (dbgs () << " LAA: Strided accesses are independent\n " );
2185
2198
return Dependence::NoDep;
2186
2199
}
@@ -2194,13 +2207,9 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
2194
2207
// Negative distances are not plausible dependencies.
2195
2208
if (SE.isKnownNonPositive (Dist)) {
2196
2209
if (SE.isKnownNonNegative (Dist)) {
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;
2210
+ // Write to the same location with the same size.
2211
+ assert (HasSameSize && " Accesses must have the same size" );
2212
+ return Dependence::Forward;
2204
2213
}
2205
2214
2206
2215
bool IsTrueDataDependence = (AIsWrite && !BIsWrite);
@@ -2218,7 +2227,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
2218
2227
: Dependence::Unknown;
2219
2228
}
2220
2229
if (!HasSameSize ||
2221
- couldPreventStoreLoadForward (ConstDist, TypeByteSize)) {
2230
+ couldPreventStoreLoadForward (ConstDist, TypeByteSize. first )) {
2222
2231
LLVM_DEBUG (
2223
2232
dbgs () << " LAA: Forward but may prevent st->ld forwarding\n " );
2224
2233
return Dependence::ForwardButPreventsForwarding;
@@ -2284,7 +2293,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
2284
2293
// We know that Dist is positive, but it may not be constant. Use the signed
2285
2294
// minimum for computations below, as this ensures we compute the closest
2286
2295
// possible dependence distance.
2287
- uint64_t MinDistanceNeeded = MaxStride * (MinNumIter - 1 ) + TypeByteSize;
2296
+ uint64_t MinDistanceNeeded =
2297
+ MaxStride * (MinNumIter - 1 ) + TypeByteSize.first ;
2288
2298
if (MinDistanceNeeded > static_cast <uint64_t >(MinDistance)) {
2289
2299
if (!ConstDist) {
2290
2300
// For non-constant distances, we checked the lower bound of the
@@ -2312,14 +2322,15 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
2312
2322
2313
2323
bool IsTrueDataDependence = (!AIsWrite && BIsWrite);
2314
2324
if (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
2315
- couldPreventStoreLoadForward (MinDistance, TypeByteSize, *CommonStride))
2325
+ couldPreventStoreLoadForward (MinDistance, TypeByteSize.first ,
2326
+ *CommonStride))
2316
2327
return Dependence::BackwardVectorizableButPreventsForwarding;
2317
2328
2318
2329
uint64_t MaxVF = MinDepDistBytes / MaxStride;
2319
2330
LLVM_DEBUG (dbgs () << " LAA: Positive min distance " << MinDistance
2320
2331
<< " with max VF = " << MaxVF << ' \n ' );
2321
2332
2322
- uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8 ;
2333
+ uint64_t MaxVFInBits = MaxVF * TypeByteSize. first * 8 ;
2323
2334
if (!ConstDist && MaxVFInBits < MaxTargetVectorWidthInBits) {
2324
2335
// For non-constant distances, we checked the lower bound of the dependence
2325
2336
// distance and the distance may be larger at runtime (and safe for
0 commit comments