@@ -15758,6 +15758,11 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1575815758 // DividesBy.
1575915759 std::function<bool(const SCEV *, const SCEV *&)> HasDivisibiltyInfo =
1576015760 [&](const SCEV *Expr, const SCEV *&DividesBy) {
15761+ const APInt &Multiple = SE.getConstantMultiple(Expr);
15762+ if (!Multiple.isOne()) {
15763+ DividesBy = SE.getConstant(Multiple);
15764+ return true;
15765+ }
1576115766 if (auto *Mul = dyn_cast<SCEVMulExpr>(Expr)) {
1576215767 if (Mul->getNumOperands() != 2)
1576315768 return false;
@@ -15780,7 +15785,8 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1578015785 // Return true if Expr known to divide by \p DividesBy.
1578115786 std::function<bool(const SCEV *, const SCEV *&)> IsKnownToDivideBy =
1578215787 [&](const SCEV *Expr, const SCEV *DividesBy) {
15783- if (SE.getURemExpr(Expr, DividesBy)->isZero())
15788+ if (Expr->getType()->isIntegerTy() &&
15789+ SE.getURemExpr(Expr, DividesBy)->isZero())
1578415790 return true;
1578515791 if (auto *MinMax = dyn_cast<SCEVMinMaxExpr>(Expr))
1578615792 return IsKnownToDivideBy(MinMax->getOperand(0), DividesBy) &&
@@ -15865,22 +15871,23 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1586515871 EnqueueOperands(SMax);
1586615872 break;
1586715873 case CmpInst::ICMP_UGT:
15868- case CmpInst::ICMP_UGE:
15869- To = SE.getUMaxExpr(FromRewritten, RHS);
15874+ case CmpInst::ICMP_UGE: {
15875+ const SCEV *OpAlignedUp =
15876+ DividesBy ? GetNextSCEVDividesByDivisor(RHS, DividesBy) : RHS;
15877+ To = SE.getUMaxExpr(FromRewritten, OpAlignedUp);
1587015878 if (auto *UMin = dyn_cast<SCEVUMinExpr>(FromRewritten))
1587115879 EnqueueOperands(UMin);
15872- if (RHS->isOne())
15873- ExprsToRewrite.push_back(From);
1587415880 break;
15881+ }
1587515882 case CmpInst::ICMP_SGT:
15876- case CmpInst::ICMP_SGE:
15877- To = SE.getSMaxExpr(FromRewritten, RHS);
15878- if (auto *SMin = dyn_cast<SCEVSMinExpr>(FromRewritten)) {
15883+ case CmpInst::ICMP_SGE: {
15884+ const SCEV *OpAlignedUp =
15885+ DividesBy ? GetNextSCEVDividesByDivisor(RHS, DividesBy) : RHS;
15886+ To = SE.getSMaxExpr(FromRewritten, OpAlignedUp);
15887+ if (auto *SMin = dyn_cast<SCEVSMinExpr>(FromRewritten))
1587915888 EnqueueOperands(SMin);
15880- }
15881- if (RHS->isOne())
15882- ExprsToRewrite.push_back(From);
1588315889 break;
15890+ }
1588415891 case CmpInst::ICMP_EQ:
1588515892 if (isa<SCEVConstant>(RHS))
1588615893 To = RHS;
@@ -16011,20 +16018,6 @@ void ScalarEvolution::LoopGuards::collectFromBlock(
1601116018 const SCEV *RewriteTo = Guards.RewriteMap[Expr];
1601216019 Guards.RewriteMap.erase(Expr);
1601316020 const SCEV *Rewritten = Guards.rewrite(RewriteTo);
16014-
16015- // Try to strengthen divisibility of SMax/UMax expressions coming from >=
16016- // 1 conditions.
16017- auto *Max = dyn_cast<SCEVMinMaxExpr>(Rewritten);
16018- if (Max && isa<SCEVSMaxExpr, SCEVUMaxExpr>(Rewritten) &&
16019- Rewritten->getType()->isIntegerTy() && Max->getOperand(0)->isOne()) {
16020- APInt CommonMultiple = SE.getConstantMultiple(Max->getOperand(1));
16021- for (const SCEV *Op : drop_begin(Max->operands(), 2)) {
16022- CommonMultiple = APIntOps::GreatestCommonDivisor(
16023- CommonMultiple, SE.getConstantMultiple(Op));
16024- }
16025- SmallVector<const SCEV *> Ops = {SE.getConstant(CommonMultiple), Max};
16026- Rewritten = SE.getMinMaxExpr(Max->getSCEVType(), Ops);
16027- }
1602816021 Guards.RewriteMap.insert({Expr, Rewritten});
1602916022 }
1603016023 }
0 commit comments