aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/InstCombine/InstCombineCasts.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-10 20:25:54 +0000
committerChris Lattner <sabre@nondot.org>2010-01-10 20:25:54 +0000
commit9ee947c224a157a5fb2c921a0e194fddedef2f9f (patch)
tree216fdd4c47294d32953b52bd75c44f52e3b68e43 /lib/Transforms/InstCombine/InstCombineCasts.cpp
parent859c372e04f053daa85812f8b790d2b0d1645fee (diff)
teach zext optimization how to deal with truncs that don't come from
the zext dest type. This allows us to handle test52/53 in cast.ll, and allows llvm-gcc to generate much better code for PR4216 in -m64 mode: _test_bitfield: ## @test_bitfield orl $32962, %edi movl %edi, %eax andl $-25350, %eax ret This also fixes a bug handling vector extends, ensuring that the mask produced is a vector constant, not an integer constant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93127 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineCasts.cpp')
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp24
1 files changed, 12 insertions, 12 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 771ab23be3..e2e74c1e5d 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -192,7 +192,9 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, const Type *Ty,
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);
@@ -597,6 +599,10 @@ static bool CanEvaluateZExtd(Value *V, const Type *Ty, const TargetData *TD) {
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:
@@ -608,9 +614,6 @@ static bool CanEvaluateZExtd(Value *V, const Type *Ty, const TargetData *TD) {
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) &&
@@ -671,7 +674,7 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
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);
}
@@ -810,23 +813,20 @@ static bool CanEvaluateSExtd(Value *V, const Type *Ty, TargetData *TD) {
//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: