Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.520.2.8 -> 1.520.2.9 PredicateSimplifier.cpp updated: 1.20.2.2 -> 1.20.2.3 Reassociate.cpp updated: 1.62.2.3 -> 1.62.2.4 --- Log message: --- Diffs of the changes: (+186 -93) InstructionCombining.cpp | 271 +++++++++++++++++++++++++++++++---------------- PredicateSimplifier.cpp | 4 Reassociate.cpp | 4 3 files changed, 186 insertions(+), 93 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.8 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.9 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.520.2.8 Sun Oct 22 18:27:20 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Oct 23 13:13:27 2006 @@ -131,12 +131,16 @@ Instruction *visitAdd(BinaryOperator &I); Instruction *visitSub(BinaryOperator &I); Instruction *visitMul(BinaryOperator &I); + Instruction *visitURem(BinaryOperator &I); + Instruction *visitSRem(BinaryOperator &I); + Instruction *visitFRem(BinaryOperator &I); + Instruction *commonRemTransforms(BinaryOperator &I); + Instruction *commonIRemTransforms(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); Instruction *visitXor(BinaryOperator &I); @@ -2431,9 +2435,9 @@ return Result; } -Instruction *InstCombiner::visitRem(BinaryOperator &I) { +Instruction *InstCombiner::commonRemTransforms(BinaryOperator &I) { Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - + // 0 % X == 0, we don't need to preserve faults! if (Constant *LHS = dyn_cast<Constant>(Op0)) if (LHS->isNullValue()) @@ -2443,34 +2447,11 @@ return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); if (isa<UndefValue>(Op1)) return ReplaceInstUsesWith(I, Op1); // X % undef -> undef - - if (I.getType()->isSigned()) { - if (Value *RHSNeg = dyn_castNegVal(Op1)) - if (!isa<ConstantInt>(RHSNeg) || !RHSNeg->getType()->isSigned() || - cast<ConstantInt>(RHSNeg)->getSExtValue() > 0) { - // X % -Y -> X % Y - AddUsesToWorkList(I); - I.setOperand(1, RHSNeg); - return &I; - } - - // If the top bits of both operands are zero (i.e. we can prove they are - // unsigned inputs), turn this into a urem. - 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 *Rem = BinaryOperator::createRem(LHS, RHS, I.getName()); - InsertNewInstBefore(Rem, I); - return new CastInst(Rem, I.getType()); - } - } + return 0; +} + +Instruction *InstCombiner::commonIRemTransforms(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { // X % 0 == undef, we don't need to preserve faults! @@ -2480,13 +2461,6 @@ if (RHS->equalsInt(1)) // X % 1 == 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); - // Check to see if this is an unsigned remainder with an exact power of 2, - // if so, convert to a bitwise and. - if (ConstantInt *C = dyn_cast<ConstantInt>(RHS)) - if (RHS->getType()->isUnsigned()) - if (isPowerOf2_64(C->getZExtValue())) - return BinaryOperator::createAnd(Op0, SubOne(C)); - if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) { if (SelectInst *SI = dyn_cast<SelectInst>(Op0I)) { if (Instruction *R = FoldOpIntoSelect(I, SI, this)) @@ -2495,17 +2469,90 @@ if (Instruction *NV = FoldOpIntoPhi(I)) return NV; } + } + } + + // If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two, + // transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'. + if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) { + // rem X, (Cond ? 0 : Y) -> rem X, Y. If the rem and the select are in + // the same basic block, then we replace the select with Y, and the + // condition of the select with false (if the cond value is in the same + // BB). If the select has uses other than the div, this allows them to be + // simplified also. + if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1))) + if (ST->isNullValue()) { + Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); + if (CondI && CondI->getParent() == I.getParent()) + UpdateValueUsesWith(CondI, ConstantBool::getFalse()); + else if (I.getParent() != SI->getParent() || SI->hasOneUse()) + I.setOperand(1, SI->getOperand(2)); + else + UpdateValueUsesWith(SI, SI->getOperand(2)); + return &I; + } + // Likewise for: rem X, (Cond ? Y : 0) -> rem X, Y + if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) + if (ST->isNullValue()) { + Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); + if (CondI && CondI->getParent() == I.getParent()) + UpdateValueUsesWith(CondI, ConstantBool::getTrue()); + else if (I.getParent() != SI->getParent() || SI->hasOneUse()) + I.setOperand(1, SI->getOperand(1)); + else + UpdateValueUsesWith(SI, SI->getOperand(1)); + return &I; + } + + 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. + if (isPowerOf2_64(STO->getZExtValue()) && + isPowerOf2_64(SFO->getZExtValue())) { + Value *TrueAnd = InsertNewInstBefore( + BinaryOperator::createAnd(Op0, SubOne(STO), SI->getName()+".t"), + I); + Value *FalseAnd = InsertNewInstBefore( + BinaryOperator::createAnd(Op0, SubOne(SFO), SI->getName()+".f"), + I); + return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd); + } + } + } + + return 0; +} + +Instruction *InstCombiner::visitURem(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + Instruction* common = commonRemTransforms(I); + if (common) + return common; + + common = commonIRemTransforms(I); + if (common) + return common; + + if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { + // Check to see if this is an unsigned remainder with an exact power of 2, + // if so, convert to a bitwise and. + if (ConstantInt *C = dyn_cast<ConstantInt>(RHS)) + if (isPowerOf2_64(C->getZExtValue())) + return BinaryOperator::createAnd(Op0, SubOne(C)); + + if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) { // X*C1%C2 --> 0 iff C1%C2 == 0 - if (ConstantExpr::getRem(GetFactor(Op0I), RHS)->isNullValue()) + if (ConstantExpr::getURem(GetFactor(Op0I), RHS)->isNullValue()) return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); } } if (Instruction *RHSI = dyn_cast<Instruction>(I.getOperand(1))) { // Turn A % (C << N), where C is 2^k, into A & ((C << N)-1) [urem only]. - if (I.getType()->isUnsigned() && - RHSI->getOpcode() == Instruction::Shl && + if (RHSI->getOpcode() == Instruction::Shl && isa<ConstantInt>(RHSI->getOperand(0)) && RHSI->getOperand(0)->getType()->isUnsigned()) { unsigned C1 = cast<ConstantInt>(RHSI->getOperand(0))->getZExtValue(); @@ -2517,57 +2564,97 @@ } } - // If this is 'urem X, (Cond ? C1, C2)' where C1&C2 are powers of two, - // transform this into: '(Cond ? (urem X, C1) : (urem X, C2))'. - if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) { - // rem X, (Cond ? 0 : Y) -> rem X, Y. If the rem and the select are in - // the same basic block, then we replace the select with Y, and the - // condition of the select with false (if the cond value is in the same - // BB). If the select has uses other than the div, this allows them to be - // simplified also. - if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1))) - if (ST->isNullValue()) { - Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); - if (CondI && CondI->getParent() == I.getParent()) - UpdateValueUsesWith(CondI, ConstantBool::getFalse()); - else if (I.getParent() != SI->getParent() || SI->hasOneUse()) - I.setOperand(1, SI->getOperand(2)); - else - UpdateValueUsesWith(SI, SI->getOperand(2)); - return &I; - } - // Likewise for: rem X, (Cond ? Y : 0) -> rem X, Y - if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) - if (ST->isNullValue()) { - Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); - if (CondI && CondI->getParent() == I.getParent()) - UpdateValueUsesWith(CondI, ConstantBool::getTrue()); - else if (I.getParent() != SI->getParent() || SI->hasOneUse()) - I.setOperand(1, SI->getOperand(1)); - else - UpdateValueUsesWith(SI, SI->getOperand(1)); - return &I; - } + } + + return 0; +} - - 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. - if (isPowerOf2_64(STO->getZExtValue()) && - isPowerOf2_64(SFO->getZExtValue())) { - Value *TrueAnd = InsertNewInstBefore( - BinaryOperator::createAnd(Op0, SubOne(STO), SI->getName()+".t"), - I); - Value *FalseAnd = InsertNewInstBefore( - BinaryOperator::createAnd(Op0, SubOne(SFO), SI->getName()+".f"), - I); - return new SelectInst(SI->getOperand(0), TrueAnd, FalseAnd); - } - } +Instruction *InstCombiner::visitSRem(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + Instruction *common = commonRemTransforms(I); + if (common) + return common; + + common = commonIRemTransforms(I); + if (common) + return common; + + if (Value *RHSNeg = dyn_castNegVal(Op1)) + if (!isa<ConstantInt>(RHSNeg) || !RHSNeg->getType()->isSigned() || + cast<ConstantInt>(RHSNeg)->getSExtValue() > 0) { + // X % -Y -> X % Y + AddUsesToWorkList(I); + I.setOperand(1, RHSNeg); + return &I; + } + + // If the top bits of both operands are zero (i.e. we can prove they are + // unsigned inputs), turn this into a urem. + 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 *URem = BinaryOperator::createURem(LHS, RHS, I.getName()); + InsertNewInstBefore(URem, I); + return new CastInst(URem, I.getType()); + } + + if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { + if (Instruction *Op0I = dyn_cast<Instruction>(Op0)) { + // X*C1%C2 --> 0 iff C1%C2 == 0 + if (ConstantExpr::getSRem(GetFactor(Op0I), RHS)->isNullValue()) + return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); } } - + + return 0; +} + +Instruction *InstCombiner::visitFRem(BinaryOperator &I) { + Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); + + Instruction *common = commonRemTransforms(I); + if (common) + return common; + + if (SelectInst *SI = dyn_cast<SelectInst>(Op1)) { + // rem X, (Cond ? 0 : Y) -> rem X, Y. If the rem and the select are in + // the same basic block, then we replace the select with Y, and the + // condition of the select with false (if the cond value is in the same + // BB). If the select has uses other than the div, this allows them to be + // simplified also. + if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1))) + if (ST->isNullValue()) { + Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); + if (CondI && CondI->getParent() == I.getParent()) + UpdateValueUsesWith(CondI, ConstantBool::getFalse()); + else if (I.getParent() != SI->getParent() || SI->hasOneUse()) + I.setOperand(1, SI->getOperand(2)); + else + UpdateValueUsesWith(SI, SI->getOperand(2)); + return &I; + } + // Likewise for: rem X, (Cond ? Y : 0) -> rem X, Y + if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) + if (ST->isNullValue()) { + Instruction *CondI = dyn_cast<Instruction>(SI->getOperand(0)); + if (CondI && CondI->getParent() == I.getParent()) + UpdateValueUsesWith(CondI, ConstantBool::getTrue()); + else if (I.getParent() != SI->getParent() || SI->hasOneUse()) + I.setOperand(1, SI->getOperand(1)); + else + UpdateValueUsesWith(SI, SI->getOperand(1)); + return &I; + } + } + return 0; } @@ -4585,7 +4672,9 @@ break; #endif - case Instruction::Rem: + case Instruction::URem: + break; + case Instruction::SRem: // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one. if (CI->isNullValue() && isa<ConstantInt>(BO->getOperand(1)) && BO->hasOneUse() && BO->getOperand(1)->getType()->isSigned()) { @@ -4596,7 +4685,7 @@ Value *NewX = InsertNewInstBefore(new CastInst(BO->getOperand(0), UTy, "tmp"), I); Constant *RHSCst = ConstantInt::get(UTy, 1ULL << L2); - Value *NewRem =InsertNewInstBefore(BinaryOperator::createRem(NewX, + Value *NewRem =InsertNewInstBefore(BinaryOperator::createURem(NewX, RHSCst, BO->getName()), I); return BinaryOperator::create(I.getOpcode(), NewRem, Constant::getNullValue(UTy)); Index: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp diff -u llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.2 llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.3 --- llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.20.2.2 Sun Oct 22 03:59:01 2006 +++ llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp Mon Oct 23 13:13:27 2006 @@ -726,10 +726,12 @@ Instruction::BinaryOps ops = BO.getOpcode(); switch (ops) { + case Instruction::URem: + case Instruction::SRem: case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: - case Instruction::Rem: { + case Instruction::FRem: { Value *Divisor = BO.getOperand(1); KP.addNotEqual(Constant::getNullValue(Divisor->getType()), Divisor); break; Index: llvm/lib/Transforms/Scalar/Reassociate.cpp diff -u llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.3 llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.4 --- llvm/lib/Transforms/Scalar/Reassociate.cpp:1.62.2.3 Sun Oct 22 03:59:01 2006 +++ llvm/lib/Transforms/Scalar/Reassociate.cpp Mon Oct 23 13:13:27 2006 @@ -113,10 +113,12 @@ I->getOpcode() == Instruction::Malloc || I->getOpcode() == Instruction::Invoke || I->getOpcode() == Instruction::Call || + I->getOpcode() == Instruction::URem || + I->getOpcode() == Instruction::SRem || I->getOpcode() == Instruction::UDiv || I->getOpcode() == Instruction::SDiv || I->getOpcode() == Instruction::FDiv || - I->getOpcode() == Instruction::Rem) + I->getOpcode() == Instruction::FRem) return true; return false; } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits