Index: llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp =================================================================== --- llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp +++ llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp @@ -1815,6 +1815,9 @@ } Value *SCEVExpander::visitUMinExpr(const SCEVUMinExpr *S) { + // For the umin(1,X1...Xn) pattern described in the cost modeling, we let + // instcombine do the actual transform, relying on the order of SCEV + // canonicalization to put the constant in the outermost umin. Value *LHS = expand(S->getOperand(S->getNumOperands() - 1)); Type *Ty = LHS->getType(); for (int i = S->getNumOperands() - 2; i >= 0; --i) { @@ -2308,10 +2311,23 @@ // see SCEVExpander::visitMulExpr(), ExpandOpBinPowN(). Cost = ArithCost(Instruction::Mul, S->getNumOperands() - 1); break; - case scUMaxExpr: + case scUMinExpr: + // umin(1, x2, ..., xn) is zero if any x1..xn is zero, and one otherwise. + // This is equivalent to zext(icmp ne umin(x1..xn), 0). (e.g. one select + // can be replaced with an zext.) + if (llvm::any_of(S->operands(), [](const SCEV *S) { + return S->getType()->isIntegerTy() && S->isOne(); + })) { + Cost += CmpSelCost(Instruction::ICmp, S->getNumOperands() - 1, 0, 1); + if (S->getNumOperands() > 2) + Cost += CmpSelCost(Instruction::Select, S->getNumOperands() - 2, 0, 2); + Cost += CastCost(Instruction::ZExt); + break; + } + LLVM_FALLTHROUGH; case scSMaxExpr: - case scSMinExpr: - case scUMinExpr: { + case scUMaxExpr: + case scSMinExpr: { // FIXME: should this ask the cost for Intrinsic's? Cost += CmpSelCost(Instruction::ICmp, S->getNumOperands() - 1, 0, 1); Cost += CmpSelCost(Instruction::Select, S->getNumOperands() - 1, 0, 2);