@@ -2854,14 +2854,18 @@ bool DependenceInfo::testMIV(const SCEV *Src, const SCEV *Dst,
28542854 banerjeeMIVtest (Src, Dst, Loops, Result);
28552855}
28562856
2857- // Given a product, e.g., 10*X*Y, returns the first constant operand,
2858- // in this case 10. If there is no constant part, returns std::nullopt.
2859- static std::optional<APInt> getConstantPart (const SCEV *Expr) {
2857+ // / Given a SCEVMulExpr, returns its first operand if its first operand is a
2858+ // / constant and the product doesn't overflow in a signed sense. Otherwise,
2859+ // / returns std::nullopt. For example, given (10 * X * Y)<nsw>, it returns 10.
2860+ // / Notably, if it doesn't have nsw, the multiplication may overflow, and if
2861+ // / so, it may not a multiple of 10.
2862+ static std::optional<APInt> getConstanCoefficient (const SCEV *Expr) {
28602863 if (const auto *Constant = dyn_cast<SCEVConstant>(Expr))
28612864 return Constant->getAPInt ();
28622865 if (const auto *Product = dyn_cast<SCEVMulExpr>(Expr))
28632866 if (const auto *Constant = dyn_cast<SCEVConstant>(Product->getOperand (0 )))
2864- return Constant->getAPInt ();
2867+ if (Product->hasNoSignedWrap ())
2868+ return Constant->getAPInt ();
28652869 return std::nullopt ;
28662870}
28672871
@@ -2887,7 +2891,7 @@ bool DependenceInfo::accumulateCoefficientsGCD(const SCEV *Expr,
28872891 if (AddRec->getLoop () == CurLoop) {
28882892 CurLoopCoeff = Step;
28892893 } else {
2890- std::optional<APInt> ConstCoeff = getConstantPart (Step);
2894+ std::optional<APInt> ConstCoeff = getConstanCoefficient (Step);
28912895
28922896 // If the coefficient is the product of a constant and other stuff, we can
28932897 // use the constant in the GCD computation.
@@ -2940,7 +2944,7 @@ bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
29402944 const SCEV *Coeff = AddRec->getStepRecurrence (*SE);
29412945 // If the coefficient is the product of a constant and other stuff,
29422946 // we can use the constant in the GCD computation.
2943- std::optional<APInt> ConstCoeff = getConstantPart (Coeff);
2947+ std::optional<APInt> ConstCoeff = getConstanCoefficient (Coeff);
29442948 if (!ConstCoeff)
29452949 return false ;
29462950 RunningGCD = APIntOps::GreatestCommonDivisor (RunningGCD, ConstCoeff->abs ());
@@ -2958,7 +2962,7 @@ bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
29582962 const SCEV *Coeff = AddRec->getStepRecurrence (*SE);
29592963 // If the coefficient is the product of a constant and other stuff,
29602964 // we can use the constant in the GCD computation.
2961- std::optional<APInt> ConstCoeff = getConstantPart (Coeff);
2965+ std::optional<APInt> ConstCoeff = getConstanCoefficient (Coeff);
29622966 if (!ConstCoeff)
29632967 return false ;
29642968 RunningGCD = APIntOps::GreatestCommonDivisor (RunningGCD, ConstCoeff->abs ());
@@ -2979,7 +2983,7 @@ bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
29792983 } else if (const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
29802984 // Search for constant operand to participate in GCD;
29812985 // If none found; return false.
2982- std::optional<APInt> ConstOp = getConstantPart (Product);
2986+ std::optional<APInt> ConstOp = getConstanCoefficient (Product);
29832987 if (!ConstOp)
29842988 return false ;
29852989 ExtraGCD = APIntOps::GreatestCommonDivisor (ExtraGCD, ConstOp->abs ());
@@ -3032,7 +3036,7 @@ bool DependenceInfo::gcdMIVtest(const SCEV *Src, const SCEV *Dst,
30323036 Delta = SE->getMinusSCEV (SrcCoeff, DstCoeff);
30333037 // If the coefficient is the product of a constant and other stuff,
30343038 // we can use the constant in the GCD computation.
3035- std::optional<APInt> ConstCoeff = getConstantPart (Delta);
3039+ std::optional<APInt> ConstCoeff = getConstanCoefficient (Delta);
30363040 if (!ConstCoeff)
30373041 // The difference of the two coefficients might not be a product
30383042 // or constant, in which case we give up on this direction.
0 commit comments