return I->getOperand(0);
// Otherwise, must be the same type of cast, so just reinsert a new one.
- Res = CastInst::Create(cast<CastInst>(I)->getOpcode(), I->getOperand(0),Ty);
+ // This also handles the case of zext(trunc(x)) -> zext(x).
+ Res = CastInst::CreateIntegerCast(I->getOperand(0), Ty,
+ Opc == Instruction::SExt);
break;
case Instruction::Select: {
Value *True = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned);
unsigned Opc = I->getOpcode();
switch (Opc) {
+ case Instruction::ZExt: // zext(zext(x)) -> zext(x).
+ case Instruction::SExt: // zext(sext(x)) -> sext(x).
+ case Instruction::Trunc: // zext(trunc(x)) -> trunc(x) or zext(x)
+ return true;
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
CanEvaluateZExtd(I->getOperand(1), Ty, TD);
//case Instruction::LShr:
- case Instruction::ZExt: // zext(zext(x)) -> zext(x).
- case Instruction::SExt: // zext(sext(x)) -> sext(x).
- return true;
case Instruction::Select:
return CanEvaluateZExtd(I->getOperand(1), Ty, TD) &&
return ReplaceInstUsesWith(CI, Res);
// We need to emit an AND to clear the high bits.
- Constant *C = ConstantInt::get(CI.getContext(),
+ Constant *C = ConstantInt::get(Res->getType(),
APInt::getLowBitsSet(DestBitSize, SrcBitSize));
return BinaryOperator::CreateAnd(Res, C);
}
//case Instruction::LShr: TODO
//case Instruction::Trunc: TODO
- case Instruction::SExt:
- case Instruction::ZExt: {
- // sext(sext(x)) -> sext(x)
- // sext(zext(x)) -> zext(x)
+ case Instruction::SExt: // sext(sext(x)) -> sext(x)
+ case Instruction::ZExt: // sext(zext(x)) -> zext(x)
return true;
- }
case Instruction::Select:
return CanEvaluateSExtd(I->getOperand(1), Ty, TD) &&
CanEvaluateSExtd(I->getOperand(2), Ty, TD);
+
case Instruction::PHI: {
// We can change a phi if we can change all operands. Note that we never
// get into trouble with cyclic PHIs here because we only consider
// instructions with a single use.
PHINode *PN = cast<PHINode>(I);
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (!CanEvaluateSExtd(PN->getIncomingValue(i), Ty, TD)) return false;
- }
return true;
}
default:
; CHECK-NEXT: %sext = shl i64 %E, 32
; CHECK-NEXT: %F = ashr i64 %sext, 32
; CHECK-NEXT: ret i64 %F
-
}
+define i32 @test52(i64 %A) {
+ %B = trunc i64 %A to i16
+ %C = or i16 %B, -32574
+ %D = and i16 %C, -25350
+ %E = zext i16 %D to i32
+ ret i32 %E
+; CHECK: @test52
+; CHECK-NEXT: %B = trunc i64 %A to i32
+; CHECK-NEXT: %C = or i32 %B, 32962
+; CHECK-NEXT: %D = and i32 %C, 40186
+; CHECK-NEXT: ret i32 %D
+}
+
+define i64 @test53(i32 %A) {
+ %B = trunc i32 %A to i16
+ %C = or i16 %B, -32574
+ %D = and i16 %C, -25350
+ %E = zext i16 %D to i64
+ ret i64 %E
+; CHECK: @test53
+; CHECK-NEXT: %B = zext i32 %A to i64
+; CHECK-NEXT: %C = or i64 %B, 32962
+; CHECK-NEXT: %D = and i64 %C, 40186
+; CHECK-NEXT: ret i64 %D
+}