@@ -1296,7 +1296,8 @@ bool DependenceInfo::testZIV(const SCEV *Src, const SCEV *Dst,
12961296bool DependenceInfo::strongSIVtest (const SCEV *Coeff, const SCEV *SrcConst,
12971297 const SCEV *DstConst, const Loop *CurSrcLoop,
12981298 const Loop *CurDstLoop, unsigned Level,
1299- FullDependence &Result) const {
1299+ FullDependence &Result,
1300+ bool UnderRuntimeAssumptions) {
13001301 if (!isDependenceTestEnabled (DependenceTestType::StrongSIV))
13011302 return false ;
13021303
@@ -1368,7 +1369,38 @@ bool DependenceInfo::strongSIVtest(const SCEV *Coeff, const SCEV *SrcConst,
13681369 Result.DV [Level].Direction &= Dependence::DVEntry::EQ;
13691370 ++StrongSIVsuccesses;
13701371 } else if (Delta->isZero ()) {
1371- // since 0/X == 0
1372+ // Check if coefficient could be zero. If so, 0/0 is undefined and we
1373+ // cannot conclude that only same-iteration dependencies exist.
1374+ // When coeff=0, all iterations access the same location.
1375+ if (isa<SCEVUnknown>(Coeff)) {
1376+ // Use both isKnownNonZero and range analysis to prove coefficient != 0.
1377+ bool CoeffKnownNonZero = SE->isKnownNonZero (Coeff) ||
1378+ isKnownPredicate (CmpInst::ICMP_NE, Coeff,
1379+ SE->getZero (Coeff->getType ()));
1380+ if (!CoeffKnownNonZero) {
1381+ // Cannot prove at compile time, would need runtime assumption.
1382+ if (UnderRuntimeAssumptions) {
1383+ const SCEVPredicate *Pred = SE->getComparePredicate (
1384+ ICmpInst::ICMP_NE, Coeff, SE->getZero (Coeff->getType ()));
1385+ SmallVector<const SCEVPredicate *, 4 > NewPreds (
1386+ Result.Assumptions .getPredicates ());
1387+ NewPreds.push_back (Pred);
1388+ Result.Assumptions = SCEVUnionPredicate (NewPreds, *SE);
1389+ LLVM_DEBUG (dbgs () << " \t Added runtime assumption: " << *Coeff
1390+ << " != 0\n " );
1391+ } else {
1392+ // Cannot add runtime assumptions, this test cannot handle this case.
1393+ // Let more complex tests try.
1394+ LLVM_DEBUG (dbgs () << " \t Would need runtime assumption " << *Coeff
1395+ << " != 0, but not allowed. Failing this test.\n " );
1396+ return false ;
1397+ }
1398+ } else {
1399+ LLVM_DEBUG (
1400+ dbgs () << " \t Coefficient proven non-zero by SCEV analysis\n " );
1401+ }
1402+ }
1403+ // Since 0/X == 0 (where X is known non-zero or assumed non-zero).
13721404 Result.DV [Level].Distance = Delta;
13731405 Result.DV [Level].Direction &= Dependence::DVEntry::EQ;
13741406 ++StrongSIVsuccesses;
@@ -2331,7 +2363,8 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
23312363//
23322364// Return true if dependence disproved.
23332365bool DependenceInfo::testSIV (const SCEV *Src, const SCEV *Dst, unsigned &Level,
2334- FullDependence &Result) const {
2366+ FullDependence &Result,
2367+ bool UnderRuntimeAssumptions) {
23352368 LLVM_DEBUG (dbgs () << " src = " << *Src << " \n " );
23362369 LLVM_DEBUG (dbgs () << " dst = " << *Dst << " \n " );
23372370 const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
@@ -2349,8 +2382,9 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
23492382 Level = mapSrcLoop (CurSrcLoop);
23502383 bool disproven;
23512384 if (SrcCoeff == DstCoeff)
2352- disproven = strongSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2353- CurDstLoop, Level, Result);
2385+ disproven =
2386+ strongSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop, CurDstLoop,
2387+ Level, Result, UnderRuntimeAssumptions);
23542388 else if (SrcCoeff == SE->getNegativeSCEV (DstCoeff))
23552389 disproven = weakCrossingSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop,
23562390 CurDstLoop, Level, Result);
@@ -3540,6 +3574,10 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35403574
35413575 FullDependence Result (Src, Dst, SCEVUnionPredicate (Assume, *SE),
35423576 PossiblyLoopIndependent, CommonLevels);
3577+ // Track assumptions before running dependence tests. If new assumptions are
3578+ // added during tests, we must return the result even if AllEqual to preserve
3579+ // those assumptions for the caller.
3580+ size_t AssumptionsBeforeTests = Result.Assumptions .getPredicates ().size ();
35433581 ++TotalArrayPairs;
35443582
35453583 for (unsigned P = 0 ; P < Pairs; ++P) {
@@ -3583,7 +3621,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35833621 case Subscript::SIV: {
35843622 LLVM_DEBUG (dbgs () << " , SIV\n " );
35853623 unsigned Level;
3586- if (testSIV (Pair[SI].Src , Pair[SI].Dst , Level, Result))
3624+ if (testSIV (Pair[SI].Src , Pair[SI].Dst , Level, Result,
3625+ UnderRuntimeAssumptions))
35873626 return nullptr ;
35883627 break ;
35893628 }
@@ -3664,14 +3703,18 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36643703 } else {
36653704 // On the other hand, if all directions are equal and there's no
36663705 // loop-independent dependence possible, then no dependence exists.
3706+ // However, if we added runtime assumptions during the dependence tests,
3707+ // we must return the result to preserve those assumptions for the caller.
36673708 bool AllEqual = true ;
36683709 for (unsigned II = 1 ; II <= CommonLevels; ++II) {
36693710 if (Result.getDirection (II) != Dependence::DVEntry::EQ) {
36703711 AllEqual = false ;
36713712 break ;
36723713 }
36733714 }
3674- if (AllEqual)
3715+ bool AddedAssumptionsDuringTests =
3716+ Result.Assumptions .getPredicates ().size () > AssumptionsBeforeTests;
3717+ if (AllEqual && !AddedAssumptionsDuringTests)
36753718 return nullptr ;
36763719 }
36773720
0 commit comments