Chris prefers icmp/select over udiv!

llvm-svn: 60187
This commit is contained in:
Nick Lewycky 2008-11-27 22:41:10 +00:00
parent b3dc4ad5b4
commit 4ab50b93c8
3 changed files with 19 additions and 10 deletions

View File

@ -2882,13 +2882,21 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) {
if (Instruction *Common = commonIDivTransforms(I)) if (Instruction *Common = commonIDivTransforms(I))
return Common; return Common;
// X udiv C^2 -> X >> C
// Check to see if this is an unsigned division with an exact power of 2,
// if so, convert to a right shift.
if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) { if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) {
// X udiv C^2 -> X >> C
// Check to see if this is an unsigned division with an exact power of 2,
// if so, convert to a right shift.
if (C->getValue().isPowerOf2()) // 0 not included in isPowerOf2 if (C->getValue().isPowerOf2()) // 0 not included in isPowerOf2
return BinaryOperator::CreateLShr(Op0, return BinaryOperator::CreateLShr(Op0,
ConstantInt::get(Op0->getType(), C->getValue().logBase2())); ConstantInt::get(Op0->getType(), C->getValue().logBase2()));
// X udiv C, where C >= signbit
if (C->getValue().isNegative()) {
Value *IC = InsertNewInstBefore(new ICmpInst(ICmpInst::ICMP_ULT, Op0, C),
I);
return SelectInst::Create(IC, Constant::getNullValue(I.getType()),
ConstantInt::get(I.getType(), 1));
}
} }
// X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2) // X udiv (C1 << N), where C1 is "1<<C2" --> X >> (N+C2)

View File

@ -0,0 +1,6 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep div
define i8 @test(i8 %x) readnone nounwind {
%A = udiv i8 %x, 250
ret i8 %A
}

View File

@ -1,16 +1,11 @@
; RUN: llvm-as < %s | opt -instcombine | llvm-dis > %t1.ll ; RUN: llvm-as < %s | opt -instcombine | llvm-dis > %t1.ll
; RUN: grep udiv %t1.ll | count 3 ; RUN: grep udiv %t1.ll | count 2
; RUN: grep zext %t1.ll | count 3 ; RUN: grep zext %t1.ll | count 2
; PR2274 ; PR2274
; The udiv instructions shouldn't be optimized away, and the ; The udiv instructions shouldn't be optimized away, and the
; sext instructions should be optimized to zext. ; sext instructions should be optimized to zext.
define i64 @foo(i32 %x) nounwind {
%r = udiv i32 %x, -1
%z = sext i32 %r to i64
ret i64 %z
}
define i64 @bar(i32 %x) nounwind { define i64 @bar(i32 %x) nounwind {
%y = lshr i32 %x, 30 %y = lshr i32 %x, 30
%r = udiv i32 %y, 3 %r = udiv i32 %y, 3