From: Eli Friedman Date: Mon, 13 Jul 2009 22:46:01 +0000 (+0000) Subject: PR4548: optimize zext+udiv+trunc to udiv. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=070a981ab7c9b1ba82af9acf5c3b94da8af48646;p=oota-llvm.git PR4548: optimize zext+udiv+trunc to udiv. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75539 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index c93994ff56d..838b33cb23c 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7974,6 +7974,23 @@ bool InstCombiner::CanEvaluateInDifferentType(Value *V, const Type *Ty, CanEvaluateInDifferentType(I->getOperand(1), Ty, CastOpc, NumCastsRemoved); + case Instruction::UDiv: + case Instruction::URem: { + // UDiv and URem can be truncated if all the truncated bits are zero. + uint32_t OrigBitWidth = OrigTy->getScalarSizeInBits(); + uint32_t BitWidth = Ty->getScalarSizeInBits(); + if (BitWidth < OrigBitWidth) { + APInt Mask = APInt::getHighBitsSet(OrigBitWidth, OrigBitWidth-BitWidth); + if (MaskedValueIsZero(I->getOperand(0), Mask) && + MaskedValueIsZero(I->getOperand(1), Mask)) { + return CanEvaluateInDifferentType(I->getOperand(0), Ty, CastOpc, + NumCastsRemoved) && + CanEvaluateInDifferentType(I->getOperand(1), Ty, CastOpc, + NumCastsRemoved); + } + } + break; + } case Instruction::Shl: // If we are truncating the result of this SHL, and if it's a shift of a // constant amount, we can always perform a SHL in a smaller type. @@ -8060,7 +8077,9 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty, case Instruction::Xor: case Instruction::AShr: case Instruction::LShr: - case Instruction::Shl: { + case Instruction::Shl: + case Instruction::UDiv: + case Instruction::URem: { Value *LHS = EvaluateInDifferentType(I->getOperand(0), Ty, isSigned); Value *RHS = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned); Res = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); diff --git a/test/Transforms/InstCombine/udivrem-change-width.ll b/test/Transforms/InstCombine/udivrem-change-width.ll new file mode 100644 index 00000000000..eb4ba662375 --- /dev/null +++ b/test/Transforms/InstCombine/udivrem-change-width.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep zext +; PR4548 + +define i8 @udiv_i8(i8 %a, i8 %b) nounwind { + %conv = zext i8 %a to i32 + %conv2 = zext i8 %b to i32 + %div = udiv i32 %conv, %conv2 + %conv3 = trunc i32 %div to i8 + ret i8 %conv3 +} + +define i8 @urem_i8(i8 %a, i8 %b) nounwind { + %conv = zext i8 %a to i32 + %conv2 = zext i8 %b to i32 + %div = urem i32 %conv, %conv2 + %conv3 = trunc i32 %div to i8 + ret i8 %conv3 +} +