@@ -1373,7 +1373,8 @@ bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
13731373bool DependenceInfo::strongSIVtest (const SCEV *Coeff, const SCEV *SrcConst,
13741374 const SCEV *DstConst, const Loop *CurSrcLoop,
13751375 const Loop *CurDstLoop, unsigned Level,
1376- FullDependence &Result) const {
1376+ FullDependence &Result,
1377+ bool UnderRuntimeAssumptions) {
13771378 if (!isDependenceTestEnabled (DependenceTestType::StrongSIV))
13781379 return false ;
13791380
@@ -1445,7 +1446,38 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
14451446 Result.DV [Level].Direction &= Dependence::DVEntry::EQ;
14461447 ++StrongSIVsuccesses;
14471448 } else if (Delta->isZero ()) {
1448- // since 0/X == 0
1449+ // Check if coefficient could be zero. If so, 0/0 is undefined and we
1450+ // cannot conclude that only same-iteration dependencies exist.
1451+ // When coeff=0, all iterations access the same location.
1452+ if (isa<SCEVUnknown>(Coeff)) {
1453+ // Use both isKnownNonZero and range analysis to prove coefficient != 0.
1454+ bool CoeffKnownNonZero = SE->isKnownNonZero (Coeff) ||
1455+ isKnownPredicate (CmpInst::ICMP_NE, Coeff,
1456+ SE->getZero (Coeff->getType ()));
1457+ if (!CoeffKnownNonZero) {
1458+ // Cannot prove at compile time, would need runtime assumption.
1459+ if (UnderRuntimeAssumptions) {
1460+ const SCEVPredicate *Pred = SE->getComparePredicate (
1461+ ICmpInst::ICMP_NE, Coeff, SE->getZero (Coeff->getType ()));
1462+ SmallVector<const SCEVPredicate *, 4 > NewPreds (
1463+ Result.Assumptions .getPredicates ());
1464+ NewPreds.push_back (Pred);
1465+ Result.Assumptions = SCEVUnionPredicate (NewPreds, *SE);
1466+ LLVM_DEBUG (dbgs () << " \t Added runtime assumption: " << *Coeff
1467+ << " != 0\n " );
1468+ } else {
1469+ // Cannot add runtime assumptions, this test cannot handle this case.
1470+ // Let more complex tests try.
1471+ LLVM_DEBUG (dbgs () << " \t Would need runtime assumption " << *Coeff
1472+ << " != 0, but not allowed. Failing this test.\n " );
1473+ return false ;
1474+ }
1475+ } else {
1476+ LLVM_DEBUG (
1477+ dbgs () << " \t Coefficient proven non-zero by SCEV analysis\n " );
1478+ }
1479+ }
1480+ // Since 0/X == 0 (where X is known non-zero or assumed non-zero).
14491481 Result.DV [Level].Distance = Delta;
14501482 Result.DV [Level].Direction &= Dependence::DVEntry::EQ;
14511483 ++StrongSIVsuccesses;
@@ -2408,7 +2440,8 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
24082440//
24092441// Return true if dependence disproved.
24102442bool DependenceInfo::testSIV (const SCEV *Src, const SCEV *Dst, unsigned &Level,
2411- FullDependence &Result) const {
2443+ FullDependence &Result,
2444+ bool UnderRuntimeAssumptions) {
24122445 LLVM_DEBUG (dbgs () << " src = " << *Src << " \n " );
24132446 LLVM_DEBUG (dbgs () << " dst = " << *Dst << " \n " );
24142447 const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
@@ -2426,8 +2459,9 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
24262459 Level = mapSrcLoop (CurSrcLoop);
24272460 bool disproven;
24282461 if (SrcCoeff == DstCoeff)
2429- disproven = strongSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2430- CurDstLoop, Level, Result);
2462+ disproven =
2463+ strongSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop, CurDstLoop,
2464+ Level, Result, UnderRuntimeAssumptions);
24312465 else if (SrcCoeff == SE->getNegativeSCEV (DstCoeff))
24322466 disproven = weakCrossingSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop,
24332467 CurDstLoop, Level, Result);
@@ -3666,6 +3700,10 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36663700
36673701 FullDependence Result (Src, Dst, SCEVUnionPredicate (Assume, *SE),
36683702 PossiblyLoopIndependent, CommonLevels);
3703+ // Track assumptions before running dependence tests. If new assumptions are
3704+ // added during tests, we must return the result even if AllEqual to preserve
3705+ // those assumptions for the caller.
3706+ size_t AssumptionsBeforeTests = Result.Assumptions .getPredicates ().size ();
36693707 ++TotalArrayPairs;
36703708
36713709 for (unsigned P = 0 ; P < Pairs; ++P) {
@@ -3709,7 +3747,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
37093747 case Subscript::SIV: {
37103748 LLVM_DEBUG (dbgs () << " , SIV\n " );
37113749 unsigned Level;
3712- if (testSIV (Pair[SI].Src , Pair[SI].Dst , Level, Result))
3750+ if (testSIV (Pair[SI].Src , Pair[SI].Dst , Level, Result,
3751+ UnderRuntimeAssumptions))
37133752 return nullptr ;
37143753 break ;
37153754 }
@@ -3790,14 +3829,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
37903829 } else {
37913830 // On the other hand, if all directions are equal and there's no
37923831 // loop-independent dependence possible, then no dependence exists.
3832+ // However, if we added runtime assumptions during the dependence tests,
3833+ // we must return the result to preserve those assumptions for the caller.
37933834 bool AllEqual = true ;
37943835 for (unsigned II = 1 ; II <= CommonLevels; ++II) {
37953836 if (Result.getDirection (II) != Dependence::DVEntry::EQ) {
37963837 AllEqual = false ;
37973838 break ;
37983839 }
37993840 }
3800- if (AllEqual)
3841+ bool AddedAssumptionsDuringTests =
3842+ Result.Assumptions .getPredicates ().size () > AssumptionsBeforeTests;
3843+ if (AllEqual && !AddedAssumptionsDuringTests)
38013844 return nullptr ;
38023845 }
38033846
0 commit comments