@@ -1954,6 +1954,37 @@ static bool areStridedAccessesIndependent(uint64_t Distance, uint64_t Stride,
1954
1954
return Distance % Stride;
1955
1955
}
1956
1956
1957
+ bool MemoryDepChecker::areAccessesCompletelyBeforeOrAfter (const SCEV *Src,
1958
+ Type *SrcTy,
1959
+ const SCEV *Sink,
1960
+ Type *SinkTy) {
1961
+ const SCEV *BTC = PSE.getBackedgeTakenCount ();
1962
+ const SCEV *SymbolicMaxBTC = PSE.getSymbolicMaxBackedgeTakenCount ();
1963
+ ScalarEvolution &SE = *PSE.getSE ();
1964
+ const auto &[SrcStart_, SrcEnd_] = getStartAndEndForAccess (
1965
+ InnermostLoop, Src, SrcTy, BTC, SymbolicMaxBTC, &SE, &PointerBounds);
1966
+ if (isa<SCEVCouldNotCompute>(SrcStart_) || isa<SCEVCouldNotCompute>(SrcEnd_))
1967
+ return false ;
1968
+
1969
+ const auto &[SinkStart_, SinkEnd_] = getStartAndEndForAccess (
1970
+ InnermostLoop, Sink, SinkTy, BTC, SymbolicMaxBTC, &SE, &PointerBounds);
1971
+ if (isa<SCEVCouldNotCompute>(SinkStart_) ||
1972
+ isa<SCEVCouldNotCompute>(SinkEnd_))
1973
+ return false ;
1974
+
1975
+ if (!LoopGuards)
1976
+ LoopGuards.emplace (ScalarEvolution::LoopGuards::collect (InnermostLoop, SE));
1977
+
1978
+ auto SrcEnd = SE.applyLoopGuards (SrcEnd_, *LoopGuards);
1979
+ auto SinkStart = SE.applyLoopGuards (SinkStart_, *LoopGuards);
1980
+ if (SE.isKnownPredicate (CmpInst::ICMP_ULE, SrcEnd, SinkStart))
1981
+ return true ;
1982
+
1983
+ auto SinkEnd = SE.applyLoopGuards (SinkEnd_, *LoopGuards);
1984
+ auto SrcStart = SE.applyLoopGuards (SrcStart_, *LoopGuards);
1985
+ return SE.isKnownPredicate (CmpInst::ICMP_ULE, SinkEnd, SrcStart);
1986
+ }
1987
+
1957
1988
std::variant<MemoryDepChecker::Dependence::DepType,
1958
1989
MemoryDepChecker::DepDistanceStrideAndSizeInfo>
1959
1990
MemoryDepChecker::getDependenceDistanceStrideAndSize (
@@ -2001,37 +2032,13 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize(
2001
2032
LLVM_DEBUG (dbgs () << " LAA: Distance for " << *AInst << " to " << *BInst
2002
2033
<< " : " << *Dist << " \n " );
2003
2034
2004
- // Check if we can prove that Sink only accesses memory after Src's end or
2005
- // vice versa. At the moment this is limited to cases where either source or
2035
+ // At the moment this is limited to cases where either source or
2006
2036
// sink are loop invariant to avoid compile-time increases. This is not
2007
2037
// required for correctness.
2008
2038
if (SE.isLoopInvariant (Src, InnermostLoop) ||
2009
2039
SE.isLoopInvariant (Sink, InnermostLoop)) {
2010
- const SCEV *BTC = PSE.getBackedgeTakenCount ();
2011
- const SCEV *SymbolicMaxBTC = PSE.getSymbolicMaxBackedgeTakenCount ();
2012
- const auto &[SrcStart_, SrcEnd_] =
2013
- getStartAndEndForAccess (InnermostLoop, Src, ATy, BTC, SymbolicMaxBTC,
2014
- PSE.getSE (), &PointerBounds);
2015
- const auto &[SinkStart_, SinkEnd_] =
2016
- getStartAndEndForAccess (InnermostLoop, Sink, BTy, BTC, SymbolicMaxBTC,
2017
- PSE.getSE (), &PointerBounds);
2018
- if (!isa<SCEVCouldNotCompute>(SrcStart_) &&
2019
- !isa<SCEVCouldNotCompute>(SrcEnd_) &&
2020
- !isa<SCEVCouldNotCompute>(SinkStart_) &&
2021
- !isa<SCEVCouldNotCompute>(SinkEnd_)) {
2022
- if (!LoopGuards)
2023
- LoopGuards.emplace (
2024
- ScalarEvolution::LoopGuards::collect (InnermostLoop, SE));
2025
- auto SrcEnd = SE.applyLoopGuards (SrcEnd_, *LoopGuards);
2026
- auto SinkStart = SE.applyLoopGuards (SinkStart_, *LoopGuards);
2027
- if (SE.isKnownPredicate (CmpInst::ICMP_ULE, SrcEnd, SinkStart))
2028
- return MemoryDepChecker::Dependence::NoDep;
2029
-
2030
- auto SinkEnd = SE.applyLoopGuards (SinkEnd_, *LoopGuards);
2031
- auto SrcStart = SE.applyLoopGuards (SrcStart_, *LoopGuards);
2032
- if (SE.isKnownPredicate (CmpInst::ICMP_ULE, SinkEnd, SrcStart))
2033
- return MemoryDepChecker::Dependence::NoDep;
2034
- }
2040
+ if (areAccessesCompletelyBeforeOrAfter (Src, ATy, Sink, BTy))
2041
+ return Dependence::NoDep;
2035
2042
}
2036
2043
2037
2044
// Need accesses with constant strides and the same direction for further
0 commit comments