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 /llvm/lib/Transforms | |
| parent | 85f86dc05877ad0691ab2e9b700a4f44f83c4d9f (diff) | |
| download | bcm5719-llvm-4b95026194ff577a7bdaedc6ed28b54a850a12a5.tar.gz bcm5719-llvm-4b95026194ff577a7bdaedc6ed28b54a850a12a5.zip | |
PR4548: optimize zext+udiv+trunc to udiv.
llvm-svn: 75539
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 21 |
1 files changed, 20 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); |

