@@ -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,29 @@ 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 (SE->isKnownNonZero (Coeff)) {
1376+ LLVM_DEBUG (
1377+ dbgs () << " \t Coefficient proven non-zero by SCEV analysis\n " );
1378+ } else {
1379+ // Cannot prove at compile time, would need runtime assumption.
1380+ if (UnderRuntimeAssumptions) {
1381+ const SCEVPredicate *Pred = SE->getComparePredicate (
1382+ ICmpInst::ICMP_NE, Coeff, SE->getZero (Coeff->getType ()));
1383+ Result.Assumptions = Result.Assumptions .getUnionWith (Pred, *SE);
1384+ LLVM_DEBUG (dbgs () << " \t Added runtime assumption: " << *Coeff
1385+ << " != 0\n " );
1386+ } else {
1387+ // Cannot add runtime assumptions, this test cannot handle this case.
1388+ // Let more complex tests try.
1389+ LLVM_DEBUG (dbgs () << " \t Would need runtime assumption " << *Coeff
1390+ << " != 0, but not allowed. Failing this test.\n " );
1391+ return false ;
1392+ }
1393+ }
1394+ // Since 0/X == 0 (where X is known non-zero or assumed non-zero).
13721395 Result.DV [Level].Distance = Delta;
13731396 Result.DV [Level].Direction &= Dependence::DVEntry::EQ;
13741397 ++StrongSIVsuccesses;
@@ -2331,7 +2354,8 @@ bool DependenceInfo::symbolicRDIVtest(const SCEV *A1, const SCEV *A2,
23312354//
23322355// Return true if dependence disproved.
23332356bool DependenceInfo::testSIV (const SCEV *Src, const SCEV *Dst, unsigned &Level,
2334- FullDependence &Result) const {
2357+ FullDependence &Result,
2358+ bool UnderRuntimeAssumptions) {
23352359 LLVM_DEBUG (dbgs () << " src = " << *Src << " \n " );
23362360 LLVM_DEBUG (dbgs () << " dst = " << *Dst << " \n " );
23372361 const SCEVAddRecExpr *SrcAddRec = dyn_cast<SCEVAddRecExpr>(Src);
@@ -2349,8 +2373,9 @@ bool DependenceInfo::testSIV(const SCEV *Src, const SCEV *Dst, unsigned &Level,
23492373 Level = mapSrcLoop (CurSrcLoop);
23502374 bool disproven;
23512375 if (SrcCoeff == DstCoeff)
2352- disproven = strongSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2353- CurDstLoop, Level, Result);
2376+ disproven =
2377+ strongSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop, CurDstLoop,
2378+ Level, Result, UnderRuntimeAssumptions);
23542379 else if (SrcCoeff == SE->getNegativeSCEV (DstCoeff))
23552380 disproven = weakCrossingSIVtest (SrcCoeff, SrcConst, DstConst, CurSrcLoop,
23562381 CurDstLoop, Level, Result);
@@ -3463,11 +3488,10 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
34633488 SCEVUnionPredicate (Assume, *SE));
34643489 }
34653490
3466- if (!Assume. empty () && !UnderRuntimeAssumptions) {
3467- // Runtime assumptions needed but not allowed.
3491+ // Runtime assumptions needed but not allowed.
3492+ if (!Assume. empty () && !UnderRuntimeAssumptions)
34683493 return std::make_unique<Dependence>(Src, Dst,
34693494 SCEVUnionPredicate (Assume, *SE));
3470- }
34713495
34723496 unsigned Pairs = 1 ;
34733497 SmallVector<Subscript, 2 > Pair (Pairs);
@@ -3567,7 +3591,8 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
35673591 case Subscript::SIV: {
35683592 LLVM_DEBUG (dbgs () << " , SIV\n " );
35693593 unsigned Level;
3570- if (testSIV (Pair[SI].Src , Pair[SI].Dst , Level, Result))
3594+ if (testSIV (Pair[SI].Src , Pair[SI].Dst , Level, Result,
3595+ UnderRuntimeAssumptions))
35713596 return nullptr ;
35723597 break ;
35733598 }
@@ -3648,14 +3673,15 @@ DependenceInfo::depends(Instruction *Src, Instruction *Dst,
36483673 } else {
36493674 // On the other hand, if all directions are equal and there's no
36503675 // loop-independent dependence possible, then no dependence exists.
3676+ // However, if there are runtime assumptions, we must return the result.
36513677 bool AllEqual = true ;
36523678 for (unsigned II = 1 ; II <= CommonLevels; ++II) {
36533679 if (Result.getDirection (II) != Dependence::DVEntry::EQ) {
36543680 AllEqual = false ;
36553681 break ;
36563682 }
36573683 }
3658- if (AllEqual)
3684+ if (AllEqual && Result. Assumptions . getPredicates (). empty () )
36593685 return nullptr ;
36603686 }
36613687
0 commit comments