From a7cb477277faae8632eaac9858d950d8d9899c4a Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 30 Aug 2016 17:10:49 +0000 Subject: [PATCH] [InstCombine] clean up foldICmpDivConstant; NFCI 1. Fix comments to match variable names 2. Remove redundant CmpRHS variable 3. Add FIXME to replace some checks with asserts llvm-svn: 280112 --- .../Transforms/InstCombine/InstCombineCompares.cpp | 36 ++++++++++++---------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 81dcbb7..d3155e1 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -1971,55 +1971,59 @@ Instruction *InstCombiner::foldICmpUDivConstant(ICmpInst &Cmp, Instruction *InstCombiner::foldICmpDivConstant(ICmpInst &Cmp, BinaryOperator *Div, const APInt *C) { - // FIXME: This check restricts all folds under here to scalar types. + // FIXME: These checks restrict all folds under here to scalar types. ConstantInt *RHS = dyn_cast(Cmp.getOperand(1)); if (!RHS) return nullptr; - // Fold: icmp pred ([us]div X, C1), C2 -> range test + ConstantInt *DivRHS = dyn_cast(Div->getOperand(1)); + if (!DivRHS) + return nullptr; + + // Fold: icmp pred ([us]div X, C2), C -> range test // Fold this div into the comparison, producing a range check. // Determine, based on the divide type, what the range is being // checked. If there is an overflow on the low or high side, remember // it, otherwise compute the range [low, hi) bounding the new value. // See: InsertRangeTest above for the kinds of replacements possible. - ConstantInt *DivRHS = dyn_cast(Div->getOperand(1)); - if (!DivRHS) + const APInt *C2; + if (!match(Div->getOperand(1), m_APInt(C2))) return nullptr; - ConstantInt *CmpRHS = cast(Cmp.getOperand(1)); - // FIXME: If the operand types don't match the type of the divide // then don't attempt this transform. The code below doesn't have the // logic to deal with a signed divide and an unsigned compare (and - // vice versa). This is because (x /s C1) getOpcode() == Instruction::SDiv; if (!Cmp.isEquality() && DivIsSigned != Cmp.isSigned()) return nullptr; - if (DivRHS->isZero()) + + // FIXME: These 3 checks can be asserts. + if (*C2 == 0) return nullptr; // The ProdOV computation fails on divide by zero. - if (DivIsSigned && DivRHS->isAllOnesValue()) + if (DivIsSigned && C2->isAllOnesValue()) return nullptr; // The overflow computation also screws up here - if (DivRHS->isOne()) { + if (*C2 == 1) { // This eliminates some funny cases with INT_MIN. Cmp.setOperand(0, Div->getOperand(0)); // X/1 == X. return &Cmp; } // Compute Prod = CI * DivRHS. We are essentially solving an equation - // of form X/C1=C2. We solve for X by multiplying C1 (DivRHS) and - // C2 (CI). By solving for X we can turn this into a range check + // of form X/C2=C. We solve for X by multiplying C2 (DivRHS) and + // C (CI). By solving for X we can turn this into a range check // instead of computing a divide. - Constant *Prod = ConstantExpr::getMul(CmpRHS, DivRHS); + Constant *Prod = ConstantExpr::getMul(RHS, DivRHS); // Determine if the product overflows by seeing if the product is // not equal to the divide. Make sure we do the same kind of divide // as in the LHS instruction that we're folding. bool ProdOV = (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) : - ConstantExpr::getUDiv(Prod, DivRHS)) != CmpRHS; + ConstantExpr::getUDiv(Prod, DivRHS)) != RHS; // Get the ICmp opcode ICmpInst::Predicate Pred = Cmp.getPredicate(); -- 2.7.4