From 57c8d99bbd11596609aef9d1b6a8e1644c2dd34d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 18 Feb 2003 19:57:07 +0000 Subject: 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) llvm-svn: 5592 --- .../lib/Transforms/Scalar/InstructionCombining.cpp | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'llvm/lib/Transforms') diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 0c46a7b2233..f652e2bbc71 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/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(V)) + if (I->getOpcode() == Instruction::Mul) + if (isa(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(cast(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(cast(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(cast(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(cast(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; } -- cgit v1.2.3