- // If this is just a bitcast changing the sign of the operation, we can
- // convert if the operand can be converted.
- if (V->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
- return CanEvaluateInDifferentType(I->getOperand(0), Ty, NumCastsRemoved);
+ if (!I->hasOneUse()) return false;
+ // 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.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
+ if (Ty->getBitWidth() < OrigTy->getBitWidth() &&
+ CI->getZExtValue() < Ty->getBitWidth())
+ return CanEvaluateInDifferentType(I->getOperand(0), Ty,NumCastsRemoved);
+ }
+ break;
+ case Instruction::LShr:
+ if (!I->hasOneUse()) return false;
+ // If this is a truncate of a logical shr, we can truncate it to a smaller
+ // lshr iff we know that the bits we would otherwise be shifting in are
+ // already zeros.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
+ if (Ty->getBitWidth() < OrigTy->getBitWidth() &&
+ MaskedValueIsZero(I->getOperand(0),
+ OrigTy->getBitMask() & ~Ty->getBitMask()) &&
+ CI->getZExtValue() < Ty->getBitWidth()) {
+ return CanEvaluateInDifferentType(I->getOperand(0), Ty, NumCastsRemoved);
+ }
+ }