Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.445 -> 1.446 --- Log message: Generalize the REM folding code to handle another case Nick Lewycky pointed out: realize the AND can provide factors and look through Casts. --- Diffs of the changes: (+43 -13) InstructionCombining.cpp | 56 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 43 insertions(+), 13 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.445 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.446 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.445 Tue Feb 28 13:47:20 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu Mar 2 00:50:58 2006 @@ -1812,6 +1812,45 @@ } +/// GetFactor - If we can prove that the specified value is at least a multiple +/// of some factor, return that factor. +static Constant *GetFactor(Value *V) { + if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) + return CI; + + // Unless we can be tricky, we know this is a multiple of 1. + Constant *Result = ConstantInt::get(V->getType(), 1); + + Instruction *I = dyn_cast<Instruction>(V); + if (!I) return Result; + + if (I->getOpcode() == Instruction::Mul) { + // Handle multiplies by a constant, etc. + return ConstantExpr::getMul(GetFactor(I->getOperand(0)), + GetFactor(I->getOperand(1))); + } else if (I->getOpcode() == Instruction::Shl) { + // (X<<C) -> X * (1 << C) + if (Constant *ShRHS = dyn_cast<Constant>(I->getOperand(1))) { + ShRHS = ConstantExpr::getShl(Result, ShRHS); + return ConstantExpr::getMul(GetFactor(I->getOperand(0)), ShRHS); + } + } else if (I->getOpcode() == Instruction::And) { + if (ConstantInt *RHS = dyn_cast<ConstantInt>(I->getOperand(1))) { + // X & 0xFFF0 is known to be a multiple of 16. + unsigned Zeros = CountTrailingZeros_64(RHS->getZExtValue()); + if (Zeros != V->getType()->getPrimitiveSizeInBits()) + return ConstantExpr::getShl(Result, + ConstantUInt::get(Type::UByteTy, Zeros)); + } + } else if (I->getOpcode() == Instruction::Cast) { + Value *Op = I->getOperand(0); + // Only handle int->int casts. + if (!Op->getType()->isInteger()) return Result; + return ConstantExpr::getCast(GetFactor(Op), V->getType()); + } + return Result; +} + Instruction *InstCombiner::visitRem(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); @@ -1874,20 +1913,11 @@ } else if (isa<PHINode>(Op0I)) { if (Instruction *NV = FoldOpIntoPhi(I)) return NV; - } else if (Op0I->getOpcode() == Instruction::Mul) { - // X*C1%C2 --> 0 iff C1%C2 == 0 - if (ConstantInt *MulRHS = dyn_cast<ConstantInt>(Op0I->getOperand(1))) { - if (ConstantExpr::getRem(MulRHS, RHS)->isNullValue()) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - } - } else if (Op0I->getOpcode() == Instruction::Shl) { - // (X<<C1)%C2 --> 0 iff (1<<C1)%C2 == 0 - if (Constant *ShRHS = dyn_cast<Constant>(Op0I->getOperand(1))) { - ShRHS = ConstantExpr::getShl(ConstantInt::get(I.getType(), 1), ShRHS); - if (ConstantExpr::getRem(ShRHS, RHS)->isNullValue()) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - } } + + // X*C1%C2 --> 0 iff C1%C2 == 0 + if (ConstantExpr::getRem(GetFactor(Op0I), RHS)->isNullValue()) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); } } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits