@@ -1949,17 +1949,21 @@ static bool isSafeDependenceDistance(const DataLayout &DL, ScalarEvolution &SE,
19491949
19501950// / Check the dependence for two accesses with the same stride \p Stride.
19511951// / \p Distance is the positive distance in bytes, and \p TypeByteSize is type
1952- // / size in bytes.
1952+ // / size of source and sink in bytes.
1953+ // / TODO: Relax HasSameSize check in caller.
19531954// /
19541955// / \returns true if they are independent.
1955- static  bool  areStridedAccessesIndependent (uint64_t  Distance, uint64_t  Stride,
1956-                                           uint64_t  TypeByteSize) {
1956+ static  bool 
1957+ areStridedAccessesIndependent (uint64_t  Distance, uint64_t  Stride,
1958+                               std::pair<uint64_t , uint64_t > TypeByteSize) {
19571959  assert (Stride > 1  && " The stride must be greater than 1" 
1958-   assert (TypeByteSize > 0  && " The type size in byte must be non-zero" 
1960+   assert (TypeByteSize.first  > 0  && TypeByteSize.second  > 0  &&
1961+          " The type size in byte must be non-zero" 
19591962  assert (Distance > 0  && " The distance must be non-zero" 
19601963
1961-   //  Skip if the distance is not multiple of type byte size.
1962-   if  (Distance % TypeByteSize)
1964+   //  Skip if the distance is not multiple of type byte size of either source or
1965+   //  sink.
1966+   if  (Distance % TypeByteSize.first  || Distance % TypeByteSize.second )
19631967    return  false ;
19641968
19651969  //  No dependence if the distance is not multiple of the stride.
@@ -2090,14 +2094,12 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
20902094    return  MemoryDepChecker::Dependence::Unknown;
20912095  }
20922096
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.
20982097  uint64_t  ASz = DL.getTypeAllocSize (ATy);
20992098  uint64_t  BSz = DL.getTypeAllocSize (BTy);
2100-   uint64_t  TypeByteSize = (AStoreSz == BStoreSz) ? BSz : 0 ;
2099+ 
2100+   //  Both the source and sink sizes are neeeded in dependence checks, depending
2101+   //  on the use.
2102+   std::pair<uint64_t , uint64_t > TypeByteSize (ASz, BSz);
21012103
21022104  uint64_t  StrideAScaled = std::abs (StrideAPtrInt) * ASz;
21032105  uint64_t  StrideBScaled = std::abs (StrideBPtrInt) * BSz;
@@ -2119,8 +2121,23 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
21192121    return  Dependence::Unknown;
21202122  }
21212123
2124+   //  When the distance is possibly zero, we're reading/writing the same memory
2125+   //  location: if the store sizes are not equal, fail with an unknown
2126+   //  dependence.
2127+   TypeSize AStoreSz = DL.getTypeStoreSize (ATy);
2128+   TypeSize BStoreSz = DL.getTypeStoreSize (BTy);
2129+   if  (AStoreSz != BStoreSz && !SE.isKnownNonZero (Dist)) {
2130+     LLVM_DEBUG (dbgs () << " LAA: possibly zero dependence distance with " 
2131+                          " different type sizes\n " 
2132+     return  Dependence::Unknown;
2133+   }
2134+ 
2135+   //  TODO: Remove this.
2136+   bool  HasSameSize = AStoreSz == BStoreSz;
2137+ 
21222138  return  DepDistanceStrideAndSizeInfo (Dist, MaxStride, CommonStride,
2123-                                       TypeByteSize, AIsWrite, BIsWrite);
2139+                                       TypeByteSize, HasSameSize, AIsWrite,
2140+                                       BIsWrite);
21242141}
21252142
21262143MemoryDepChecker::Dependence::DepType
@@ -2152,9 +2169,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
21522169    return  std::get<Dependence::DepType>(Res);
21532170  }
21542171
2155-   auto  &[Dist, MaxStride, CommonStride, TypeByteSize, AIsWrite, BIsWrite] =
2156-       std::get<DepDistanceStrideAndSizeInfo>(Res);
2157-   bool  HasSameSize = TypeByteSize > 0 ;
2172+   auto  &[Dist, MaxStride, CommonStride, TypeByteSize, HasSameSize, AIsWrite,
2173+          BIsWrite] = std::get<DepDistanceStrideAndSizeInfo>(Res);
21582174
21592175  ScalarEvolution &SE = *PSE.getSE ();
21602176  auto  &DL = InnermostLoop->getHeader ()->getDataLayout ();
@@ -2194,13 +2210,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
21942210  //  Negative distances are not plausible dependencies.
21952211  if  (SE.isKnownNonPositive (Dist)) {
21962212    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;
2213+       //  Write to the same location with the same size.
2214+       return  Dependence::Forward;
22042215    }
22052216
22062217    bool  IsTrueDataDependence = (AIsWrite && !BIsWrite);
@@ -2218,7 +2229,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
22182229                                              : Dependence::Unknown;
22192230      }
22202231      if  (!HasSameSize ||
2221-           couldPreventStoreLoadForward (ConstDist, TypeByteSize)) {
2232+           couldPreventStoreLoadForward (ConstDist, TypeByteSize. first )) {
22222233        LLVM_DEBUG (
22232234            dbgs () << " LAA: Forward but may prevent st->ld forwarding\n " 
22242235        return  Dependence::ForwardButPreventsForwarding;
@@ -2284,7 +2295,8 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
22842295  //  We know that Dist is positive, but it may not be constant. Use the signed
22852296  //  minimum for computations below, as this ensures we compute the closest
22862297  //  possible dependence distance.
2287-   uint64_t  MinDistanceNeeded = MaxStride * (MinNumIter - 1 ) + TypeByteSize;
2298+   uint64_t  MinDistanceNeeded =
2299+       MaxStride * (MinNumIter - 1 ) + TypeByteSize.first ;
22882300  if  (MinDistanceNeeded > static_cast <uint64_t >(MinDistance)) {
22892301    if  (!ConstDist) {
22902302      //  For non-constant distances, we checked the lower bound of the
@@ -2312,14 +2324,15 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx,
23122324
23132325  bool  IsTrueDataDependence = (!AIsWrite && BIsWrite);
23142326  if  (IsTrueDataDependence && EnableForwardingConflictDetection && ConstDist &&
2315-       couldPreventStoreLoadForward (MinDistance, TypeByteSize, *CommonStride))
2327+       couldPreventStoreLoadForward (MinDistance, TypeByteSize.first ,
2328+                                    *CommonStride))
23162329    return  Dependence::BackwardVectorizableButPreventsForwarding;
23172330
23182331  uint64_t  MaxVF = MinDepDistBytes / MaxStride;
23192332  LLVM_DEBUG (dbgs () << " LAA: Positive min distance " 
23202333                    << "  with max VF = " ' \n ' 
23212334
2322-   uint64_t  MaxVFInBits = MaxVF * TypeByteSize * 8 ;
2335+   uint64_t  MaxVFInBits = MaxVF * TypeByteSize. first  * 8 ;
23232336  if  (!ConstDist && MaxVFInBits < MaxTargetVectorWidthInBits) {
23242337    //  For non-constant distances, we checked the lower bound of the dependence
23252338    //  distance and the distance may be larger at runtime (and safe for
0 commit comments