diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp index a4c1e08430..2876353ee5 100644 --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -1373,23 +1373,31 @@ static bool isAMCompletelyFolded(const TargetTransformInfo &TTI, bool HasBaseReg, int64_t Scale, Instruction *Fixup = nullptr); -static unsigned getSetupCost(const SCEV *Reg, unsigned Depth) { - if (isa(Reg) || isa(Reg)) +static unsigned getSetupCost(const SCEV *Reg, unsigned Depth, + const TargetTransformInfo &TTI) { + if (isa(Reg)) return 1; + if (const auto *C = dyn_cast(Reg)) { + if (TTI.getIntImmCost(C->getAPInt(), C->getType(), + TargetTransformInfo::TCK_RecipThroughput) == + TargetTransformInfo::TCC_Free) + return 0; + return 1; + } if (Depth == 0) return 0; if (const auto *S = dyn_cast(Reg)) - return getSetupCost(S->getStart(), Depth - 1); + return getSetupCost(S->getStart(), Depth - 1, TTI); if (auto S = dyn_cast(Reg)) - return getSetupCost(S->getOperand(), Depth - 1); + return getSetupCost(S->getOperand(), Depth - 1, TTI); if (auto S = dyn_cast(Reg)) return std::accumulate(S->operands().begin(), S->operands().end(), 0, [&](unsigned i, const SCEV *Reg) { - return i + getSetupCost(Reg, Depth - 1); + return i + getSetupCost(Reg, Depth - 1, TTI); }); if (auto S = dyn_cast(Reg)) - return getSetupCost(S->getLHS(), Depth - 1) + - getSetupCost(S->getRHS(), Depth - 1); + return getSetupCost(S->getLHS(), Depth - 1, TTI) + + getSetupCost(S->getRHS(), Depth - 1, TTI); return 0; } @@ -1459,7 +1467,7 @@ void Cost::RateRegister(const Formula &F, const SCEV *Reg, // Rough heuristic; favor registers which don't require extra setup // instructions in the preheader. - C.SetupCost += getSetupCost(Reg, SetupCostDepthLimit); + C.SetupCost += getSetupCost(Reg, SetupCostDepthLimit, *TTI); // Ensure we don't, even with the recusion limit, produce invalid costs. C.SetupCost = std::min(C.SetupCost, 1 << 16);