Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.520.2.6 -> 1.520.2.7 PredicateSimplifier.cpp updated: 1.20.2.1 -> 1.20.2.2 Reassociate.cpp updated: 1.62.2.2 -> 1.62.2.3 --- Log message: Implement the FDIV instruction for floating point divide. --- Diffs of the changes: (+93 -79) InstructionCombining.cpp | 170 +++++++++++++++++++++++++---------------------- PredicateSimplifier.cpp | 1 Reassociate.cpp | 1 3 files changed, 93 insertions(+), 79 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.6 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.7 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.6 Sat Oct 21 21:04:31 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Sun Oct 22 03:59:00 2006 @@ -131,8 +131,11 @@ Instruction *visitAdd(BinaryOperator &I); Instruction *visitSub(BinaryOperator &I); Instruction *visitMul(BinaryOperator &I); + Instruction *commonDivTransforms(BinaryOperator &I); + Instruction *commonIDivTransforms(BinaryOperator &I); Instruction *visitUDiv(BinaryOperator &I); Instruction *visitSDiv(BinaryOperator &I); + Instruction *visitFDiv(BinaryOperator &I); Instruction *visitRem(BinaryOperator &I); Instruction *visitAnd(BinaryOperator &I); Instruction *visitOr (BinaryOperator &I); @@ -2159,15 +2162,19 @@ return Changed ? &I : 0; } -Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { +Instruction* InstCombiner::commonDivTransforms(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (isa<UndefValue>(Op0)) // undef / X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); if (isa<UndefValue>(Op1)) return ReplaceInstUsesWith(I, Op1); // X / undef -> undef + return 0; +} + +Instruction* InstCombiner::commonIDivTransforms(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - // If right hand side is a constant intger .. if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { // div X, 1 == X if (RHS->equalsInt(1)) @@ -2180,25 +2187,14 @@ // (X / C1) / C2 -> X / (C1*C2) if (Instruction *LHS = dyn_cast<Instruction>(Op0)) if (LHS->getOpcode() == Instruction::SDiv || - LHS->getOpcode()==Instruction::UDiv) + LHS->getOpcode()==Instruction::UDiv || + LHS->getOpcode()==Instruction::FDiv) if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) { return BinaryOperator::create( Instruction::BinaryOps(LHS->getOpcode()), LHS->getOperand(0), ConstantExpr::getMul(RHS, LHSRHS)); } - // Check to see if this is an unsigned division with an exact power of 2, - // if so, convert to a right shift. - // X udiv C^2 -> X >> C - if (ConstantInt *C = dyn_cast<ConstantInt>(RHS)) - if (uint64_t Val = C->getZExtValue()) // Don't break X / 0 - if (isPowerOf2_64(Val)) { - uint64_t C = Log2_64(Val); - return new ShiftInst(Instruction::Shr, Op0, - ConstantInt::get(Type::UByteTy, C)); - } - - if (!RHS->isNullValue()) { // avoid X udiv 0 if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI, this)) @@ -2268,7 +2264,32 @@ if (LHS->equalsInt(0)) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - // Known to be an unsigned division. + return 0; +} + +Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + Instruction* common = commonDivTransforms(I); + if (common) + return common; + + common = commonIDivTransforms(I); + if (common) + return common; + + // Check to see if this is an unsigned division with an exact power of 2, + // if so, convert to a right shift. + // X udiv C^2 -> X >> C + if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) { + if (uint64_t Val = C->getZExtValue()) // Don't break X / 0 + if (isPowerOf2_64(Val)) { + uint64_t C = Log2_64(Val); + return new ShiftInst(Instruction::Shr, Op0, + ConstantInt::get(Type::UByteTy, C)); + } + } + if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) { // Turn A / (C1 << N), where C1 is "1<<C2" into A >> (N+C2) [udiv only]. if (RHSI->getOpcode() == Instruction::Shl && @@ -2294,35 +2315,66 @@ Instruction *InstCombiner::visitSDiv(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - if (isa<UndefValue>(Op0)) // undef / X -> 0 - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - if (isa<UndefValue>(Op1)) - return ReplaceInstUsesWith(I, Op1); // X / undef -> undef + Instruction* common = commonDivTransforms(I); + if (common) + return common; + + common = commonIDivTransforms(I); + if (common) + return common; if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { + // -X/C -> X/-C + if (Value *LHSNeg = dyn_castNegVal(Op0)) + return BinaryOperator::createSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); + } + + // If the sign bits of both operands are zero (i.e. we can prove they are + // unsigned inputs), turn this into a udiv. + uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1); + if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) { + const Type *NTy = Op0->getType()->getUnsignedVersion(); + Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); + InsertNewInstBefore(LHS, I); + Value *RHS; + if (Constant *R = dyn_cast<Constant>(Op1)) + RHS = ConstantExpr::getCast(R, NTy); + else + RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); + Instruction *Div = BinaryOperator::createUDiv(LHS, RHS, I.getName()); + InsertNewInstBefore(Div, I); + return new CastInst(Div, I.getType()); + } + + return 0; +} + +Instruction *InstCombiner::visitFDiv(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + Instruction* common = commonDivTransforms(I); + if (common) + return common; + + // If right hand side is a constant floating point ... + if (ConstantFP *RHS = dyn_cast<ConstantFP>(Op1)) { // div X, 1 == X - if (RHS->equalsInt(1)) + if (RHS->isExactlyValue(1.0)) return ReplaceInstUsesWith(I, Op0); // div X, -1 == -X - if (RHS->isAllOnesValue()) + if (RHS->isExactlyValue(-1.0)) return BinaryOperator::createNeg(Op0); // (X / C1) / C2 -> X / (C1*C2) if (Instruction *LHS = dyn_cast<Instruction>(Op0)) - if (LHS->getOpcode() == Instruction::SDiv || - LHS->getOpcode()==Instruction::UDiv) - if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) { - return BinaryOperator::create( - Instruction::BinaryOps(LHS->getOpcode()), LHS->getOperand(0), + if (LHS->getOpcode()==Instruction::FDiv) + if (ConstantFP *LHSRHS = dyn_cast<ConstantFP>(LHS->getOperand(1))) { + return BinaryOperator::create(Instruction::FDiv, LHS->getOperand(0), ConstantExpr::getMul(RHS, LHSRHS)); } - // -X/C -> X/-C - if (Value *LHSNeg = dyn_castNegVal(Op0)) - return BinaryOperator::createSDiv(LHSNeg, ConstantExpr::getNeg(RHS)); - - if (!RHS->isNullValue()) { + if (!RHS->isNullValue()) { // avoid X fdiv 0 if (SelectInst *SI = dyn_cast<SelectInst>(Op0)) if (Instruction *R = FoldOpIntoSelect(I, SI, this)) return R; @@ -2332,6 +2384,11 @@ } } + // 0 / X == 0 + if (ConstantFP *LHS = dyn_cast<ConstantFP>(Op0)) + if (LHS->isExactlyValue(0)) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); + // Handle div X, Cond?Y:Z if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) { // div X, (Cond ? 0 : Y) -> div X, Y. If the div and the select are in the @@ -2350,6 +2407,7 @@ UpdateValueUsesWith(SI, SI->getOperand(2)); return &I; } + // Likewise for: div X, (Cond ? Y : 0) -> div X, Y if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) if (ST->isNullValue()) { @@ -2362,58 +2420,11 @@ UpdateValueUsesWith(SI, SI->getOperand(1)); return &I; } - - // If this is 'udiv X, (Cond ? C1, C2)' where C1&C2 are powers of two, - // transform this into: '(Cond ? (udiv X, C1) : (udiv X, C2))'. - if (ConstantInt *STO = dyn_cast<ConstantInt>(SI->getOperand(1))) - if (ConstantInt *SFO = dyn_cast<ConstantInt>(SI->getOperand(2))) - if (STO->getType()->isUnsigned() && SFO->getType()->isUnsigned()) { - // STO == 0 and SFO == 0 handled above. - uint64_t TVA = STO->getZExtValue(), FVA = SFO->getZExtValue(); - if (isPowerOf2_64(TVA) && isPowerOf2_64(FVA)) { - unsigned TSA = Log2_64(TVA), FSA = Log2_64(FVA); - Constant *TC = ConstantInt::get(Type::UByteTy, TSA); - Instruction *TSI = new ShiftInst(Instruction::Shr, Op0, - TC, SI->getName()+".t"); - TSI = InsertNewInstBefore(TSI, I); - - Constant *FC = ConstantInt::get(Type::UByteTy, FSA); - Instruction *FSI = new ShiftInst(Instruction::Shr, Op0, - FC, SI->getName()+".f"); - FSI = InsertNewInstBefore(FSI, I); - return new SelectInst(SI->getOperand(0), TSI, FSI); - } - } } - // 0 / X == 0, we don't need to preserve faults! - if (ConstantInt *LHS = dyn_cast<ConstantInt>(Op0)) - if (LHS->equalsInt(0)) - return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - - // Known to be signed div - - // If the sign bits of both operands are zero (i.e. we can prove they are - // unsigned inputs), turn this into a udiv. - uint64_t Mask = 1ULL << (I.getType()->getPrimitiveSizeInBits()-1); - if (MaskedValueIsZero(Op1, Mask) && MaskedValueIsZero(Op0, Mask)) { - const Type *NTy = Op0->getType()->getUnsignedVersion(); - Instruction *LHS = new CastInst(Op0, NTy, Op0->getName()); - InsertNewInstBefore(LHS, I); - Value *RHS; - if (Constant *R = dyn_cast<Constant>(Op1)) - RHS = ConstantExpr::getCast(R, NTy); - else - RHS = InsertNewInstBefore(new CastInst(Op1, NTy, Op1->getName()), I); - Instruction *Div = BinaryOperator::createUDiv(LHS, RHS, I.getName()); - InsertNewInstBefore(Div, I); - return new CastInst(Div, I.getType()); - } - return 0; } - /// 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) { @@ -4486,6 +4497,7 @@ case Instruction::SDiv: case Instruction::UDiv: + case Instruction::FDiv: // Fold: (div X, C1) op C2 -> range check if (ConstantInt *DivRHS = dyn_cast<ConstantInt>(LHSI->getOperand(1))) { // Fold this div into the comparison, producing a range check. Index: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp diff -u llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.1 llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.2 --- llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.1 Fri Oct 20 03:19:49 2006 +++ llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp Sun Oct 22 03:59:01 2006 @@ -728,6 +728,7 @@ switch (ops) { case Instruction::UDiv: case Instruction::SDiv: + case Instruction::FDiv: case Instruction::Rem: { Value *Divisor = BO.getOperand(1); KP.addNotEqual(Constant::getNullValue(Divisor->getType()), Divisor); Index: llvm/lib/Transforms/Scalar/Reassociate.cpp diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.2 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.3 --- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.2 Fri Oct 20 03:19:49 2006 +++ llvm/lib/Transforms/Scalar/Reassociate.cpp Sun Oct 22 03:59:01 2006 @@ -115,6 +115,7 @@ I->getOpcode() == Instruction::Call || I->getOpcode() == Instruction::UDiv || I->getOpcode() == Instruction::SDiv || + I->getOpcode() == Instruction::FDiv || I->getOpcode() == Instruction::Rem) return true; return false; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits