summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-10 02:39:31 +0000
committerChris Lattner <sabre@nondot.org>2010-01-10 02:39:31 +0000
commit5324d802835a677888ff020174c9eab5e86d6b15 (patch)
tree8f50f562cd230060f1d19488299366e5de39bc16
parentd26c9e183e56d09f48d7074be4cacce099338316 (diff)
downloadllvm-5324d802835a677888ff020174c9eab5e86d6b15.tar.gz
llvm-5324d802835a677888ff020174c9eab5e86d6b15.tar.bz2
llvm-5324d802835a677888ff020174c9eab5e86d6b15.tar.xz
two changes:
1) don't try to optimize a sext or zext that is only used by a trunc, let the trunc get optimized first. This avoids some pointless effort in some common cases since instcombine scans down a block in the first pass. 2) Change the cost model for zext elimination to consider an 'and' cheaper than a zext. This allows us to do it more aggressively, and for the next patch to simplify the code quite a bit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93097 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp52
-rw-r--r--test/Transforms/InstCombine/cast.ll26
2 files changed, 53 insertions, 25 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 3ad786b6bd..34937ab503 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -695,6 +695,11 @@ static int CanEvaluateZExtd(Value *V, const Type *Ty,unsigned &NumCastsRemoved,
}
Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
+ // If this zero extend is only used by a truncate, let the truncate by
+ // eliminated before we try to optimize this zext.
+ if (CI.hasOneUse() && isa<TruncInst>(CI.use_back()))
+ return 0;
+
// If one of the common conversion will work, do it.
if (Instruction *Result = commonCastTransforms(CI))
return Result;
@@ -716,33 +721,25 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
int BitsZExt = CanEvaluateZExtd(Src, DestTy, NumCastsRemoved, TD);
if (BitsZExt == -1) return 0;
+ // Okay, we can transform this! Insert the new expression now.
+ DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
+ " to avoid zero extend: " << CI);
+ Value *Res = EvaluateInDifferentType(Src, DestTy, false);
+ assert(Res->getType() == DestTy);
+
+ // If the high bits are already filled with zeros, just replace this
+ // cast with the result.
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
-
- // If this is a zero-extension, we need to do an AND to maintain the clear
- // top-part of the computation. If we know the result will be zero
- // extended enough already, we don't need the and.
- if (NumCastsRemoved >= 1 ||
- unsigned(BitsZExt) >= DestBitSize-SrcBitSize) {
-
- // Okay, we can transform this! Insert the new expression now.
- DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
- " to avoid zero extend: " << CI);
- Value *Res = EvaluateInDifferentType(Src, DestTy, false);
- assert(Res->getType() == DestTy);
-
- // If the high bits are already filled with zeros, just replace this
- // cast with the result.
- if (unsigned(BitsZExt) >= DestBitSize-SrcBitSize ||
- MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
- DestBitSize-SrcBitSize)))
- return ReplaceInstUsesWith(CI, Res);
-
- // We need to emit an AND to clear the high bits.
- Constant *C = ConstantInt::get(CI.getContext(),
- APInt::getLowBitsSet(DestBitSize, SrcBitSize));
- return BinaryOperator::CreateAnd(Res, C);
- }
+ if (unsigned(BitsZExt) >= DestBitSize-SrcBitSize ||
+ MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
+ DestBitSize-SrcBitSize)))
+ return ReplaceInstUsesWith(CI, Res);
+
+ // We need to emit an AND to clear the high bits.
+ Constant *C = ConstantInt::get(CI.getContext(),
+ APInt::getLowBitsSet(DestBitSize, SrcBitSize));
+ return BinaryOperator::CreateAnd(Res, C);
}
// If this is a TRUNC followed by a ZEXT then we are dealing with integral
@@ -951,6 +948,11 @@ static unsigned CanEvaluateSExtd(Value *V, const Type *Ty,
}
Instruction *InstCombiner::visitSExt(SExtInst &CI) {
+ // If this sign extend is only used by a truncate, let the truncate by
+ // eliminated before we try to optimize this zext.
+ if (CI.hasOneUse() && isa<TruncInst>(CI.use_back()))
+ return 0;
+
if (Instruction *I = commonCastTransforms(CI))
return I;
diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll
index 490df8fab6..de7f8c11f2 100644
--- a/test/Transforms/InstCombine/cast.ll
+++ b/test/Transforms/InstCombine/cast.ll
@@ -430,4 +430,30 @@ define i64 @test46(i64 %A) {
; CHECK-NEXT: ret i64 %D
}
+define i64 @test47(i8 %A) {
+ %B = sext i8 %A to i32
+ %C = or i32 %B, 42
+ %E = zext i32 %C to i64
+ ret i64 %E
+; CHECK: @test47
+; CHECK-NEXT: %B = sext i8 %A to i64
+; CHECK-NEXT: %C = or i64 %B, 42
+; CHECK-NEXT: %E = and i64 %C, 4294967295
+; CHECK-NEXT: ret i64 %E
+}
+
+define i64 @test48(i8 %A, i8 %a) {
+ %b = zext i8 %a to i32
+ %B = zext i8 %A to i32
+ %C = shl i32 %B, 8
+ %D = or i32 %C, %b
+ %E = zext i32 %D to i64
+ ret i64 %E
+; CHECK: @test48
+; CHECK-NEXT: %b = zext i8 %a to i64
+; CHECK-NEXT: %B = zext i8 %A to i64
+; CHECK-NEXT: %C = shl i64 %B, 8
+; CHECK-NEXT: %D = or i64 %C, %b
+; CHECK-NEXT: ret i64 %D
+}