diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2009-07-13 22:46:01 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2009-07-13 22:46:01 +0000 |
| commit | 4b95026194ff577a7bdaedc6ed28b54a850a12a5 (patch) | |
| tree | 60bb118f4b5c39f15f51caffc66509df39524e48 | |
| parent | 85f86dc05877ad0691ab2e9b700a4f44f83c4d9f (diff) | |
| download | bcm5719-llvm-4b95026194ff577a7bdaedc6ed28b54a850a12a5.tar.gz bcm5719-llvm-4b95026194ff577a7bdaedc6ed28b54a850a12a5.zip | |
PR4548: optimize zext+udiv+trunc to udiv.
llvm-svn: 75539
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 21 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/udivrem-change-width.ll | 19 |
2 files changed, 39 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index c93994ff56d..838b33cb23c 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/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/llvm/test/Transforms/InstCombine/udivrem-change-width.ll b/llvm/test/Transforms/InstCombine/udivrem-change-width.ll new file mode 100644 index 00000000000..eb4ba662375 --- /dev/null +++ b/llvm/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 +} + |

