diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-02-05 07:54:04 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-02-05 07:54:04 +0000 |
| commit | 5f3b0eeddb3f2da6a0012592d7b6b266fcea1ea6 (patch) | |
| tree | f63571e168dd4a15fde8b1495541de09cc289494 /lib/Transforms | |
| parent | fee906b482f2608d10435a583c9851fa6cd777a7 (diff) | |
| download | external_llvm-5f3b0eeddb3f2da6a0012592d7b6b266fcea1ea6.zip external_llvm-5f3b0eeddb3f2da6a0012592d7b6b266fcea1ea6.tar.gz external_llvm-5f3b0eeddb3f2da6a0012592d7b6b266fcea1ea6.tar.bz2 | |
Turn A % (C << N), where C is 2^k, into A & ((C << N)-1) [urem only].
Turn A / (C1 << N), where C1 is "1<<C2" into A >> (N+C2) [udiv only].
Tested with: rem.ll:test5, div.ll:test10
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26003 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
| -rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 716f844..26772b5 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1261,6 +1261,25 @@ Instruction *InstCombiner::visitDiv(BinaryOperator &I) { InsertNewInstBefore(Div, I); return new CastInst(Div, I.getType()); } + } else { + // Known to be an unsigned division. + 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 && + isa<ConstantUInt>(RHSI->getOperand(0))) { + unsigned C1 = cast<ConstantUInt>(RHSI->getOperand(0))->getRawValue(); + if (isPowerOf2_64(C1)) { + unsigned C2 = Log2_64(C1); + Value *Add = RHSI->getOperand(1); + if (C2) { + Constant *C2V = ConstantUInt::get(Add->getType(), C2); + Add = InsertNewInstBefore(BinaryOperator::createAdd(Add, C2V, + "tmp"), I); + } + return new ShiftInst(Instruction::Shr, Op0, Add); + } + } + } } return 0; @@ -1352,6 +1371,22 @@ Instruction *InstCombiner::visitRem(BinaryOperator &I) { if (LHS->equalsInt(0)) 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 && + isa<ConstantUInt>(RHSI->getOperand(0))) { + unsigned C1 = cast<ConstantUInt>(RHSI->getOperand(0))->getRawValue(); + if (isPowerOf2_64(C1)) { + Constant *N1 = ConstantInt::getAllOnesValue(I.getType()); + Value *Add = InsertNewInstBefore(BinaryOperator::createAdd(RHSI, N1, + "tmp"), I); + return BinaryOperator::createAnd(Op0, Add); + } + } + } + return 0; } |
