diff options
author | Chris Lattner <sabre@nondot.org> | 2003-02-18 19:57:07 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-02-18 19:57:07 +0000 |
commit | ad3448c91733f14866821c1e5d24ef2ce389a358 (patch) | |
tree | 56c069ee471240f2358f3931db0b4b68d7616b1f | |
parent | fa59079c3c39e895c882a3d190f56bda365b96ab (diff) |
4 new transformations:
* X*C + X --> X * (C+1)
* X + X*C --> X * (C+1)
* X - X*C --> X * (1-C)
* X*C - X --> X * (C-1)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5592 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 0c46a7b223..f652e2bbc7 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -146,6 +146,16 @@ static unsigned Log2(uint64_t Val) { return Count; } +static inline Value *dyn_castFoldableMul(Value *V) { + if (V->use_size() == 1 && V->getType()->isInteger()) + if (Instruction *I = dyn_cast<Instruction>(V)) + if (I->getOpcode() == Instruction::Mul) + if (isa<Constant>(I->getOperand(1))) + return I->getOperand(0); + return 0; +} + + Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyBinOp(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); @@ -182,6 +192,22 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { } } + // X*C + X --> X * (C+1) + if (dyn_castFoldableMul(LHS) == RHS) { + Constant *CP1 = *cast<Constant>(cast<Instruction>(LHS)->getOperand(1)) + + *ConstantInt::get(I.getType(), 1); + assert(CP1 && "Couldn't constant fold C + 1?"); + return BinaryOperator::create(Instruction::Mul, RHS, CP1); + } + + // X + X*C --> X * (C+1) + if (dyn_castFoldableMul(RHS) == LHS) { + Constant *CP1 = *cast<Constant>(cast<Instruction>(RHS)->getOperand(1)) + + *ConstantInt::get(I.getType(), 1); + assert(CP1 && "Couldn't constant fold C + 1?"); + return BinaryOperator::create(Instruction::Mul, LHS, CP1); + } + return Changed ? &I : 0; } @@ -231,8 +257,24 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { Instruction *NewNot = BinaryOperator::createNot(OtherOp, "B.not", &I); return BinaryOperator::create(Instruction::And, Op0, NewNot); } + + // X - X*C --> X * (1-C) + if (dyn_castFoldableMul(Op1I) == Op0) { + Constant *CP1 = *ConstantInt::get(I.getType(), 1) - + *cast<Constant>(cast<Instruction>(Op1)->getOperand(1)); + assert(CP1 && "Couldn't constant fold 1-C?"); + return BinaryOperator::create(Instruction::Mul, Op0, CP1); + } } + // X*C - X --> X * (C-1) + if (dyn_castFoldableMul(Op0) == Op1) { + Constant *CP1 = *cast<Constant>(cast<Instruction>(Op0)->getOperand(1)) - + *ConstantInt::get(I.getType(), 1); + assert(CP1 && "Couldn't constant fold C - 1?"); + return BinaryOperator::create(Instruction::Mul, Op1, CP1); + } + return 0; } |