summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-01-10 07:40:50 +0000
committerChris Lattner <sabre@nondot.org>2010-01-10 07:40:50 +0000
commitdde5ee5d37d05c326d33497e1dbd16f77191a1ae (patch)
treeac2a5ce8f9abe8d76c346ff77d8755071bc08d60
parent24e64df7ec25b55aa872c2ef33728dfbb8c353c4 (diff)
downloadllvm-dde5ee5d37d05c326d33497e1dbd16f77191a1ae.tar.gz
llvm-dde5ee5d37d05c326d33497e1dbd16f77191a1ae.tar.bz2
llvm-dde5ee5d37d05c326d33497e1dbd16f77191a1ae.tar.xz
now that the cost model has changed, we can always consider
elimination of a sign extend to be a win, which simplifies the client of CanEvaluateSExtd, and allows us to eliminate more casts (examples taken from real code). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93109 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp41
-rw-r--r--test/Transforms/InstCombine/cast.ll46
2 files changed, 60 insertions, 27 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp
index b0d017e062..13f60716f2 100644
--- a/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -919,34 +919,25 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
if (NumBitsSExt == 0)
return 0;
+ // Okay, we can transform this! Insert the new expression now.
+ DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
+ " to avoid sign extend: " << CI);
+ Value *Res = EvaluateInDifferentType(Src, DestTy, true);
+ assert(Res->getType() == DestTy);
+
uint32_t SrcBitSize = SrcTy->getScalarSizeInBits();
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
+
+ // If the high bits are already filled with sign bit, just replace this
+ // cast with the result.
+ if (NumBitsSExt > DestBitSize - SrcBitSize ||
+ ComputeNumSignBits(Res) > DestBitSize - SrcBitSize)
+ return ReplaceInstUsesWith(CI, Res);
- // Because this is a sign extension, we can always transform it by inserting
- // two new shifts (to do the extension). However, this is only profitable
- // if we've eliminated two or more casts from the input. If we know the
- // result will be sign-extended enough to not require these shifts, we can
- // always do the transformation.
- if (NumCastsRemoved >= 2 ||
- NumBitsSExt > DestBitSize-SrcBitSize) {
-
- // Okay, we can transform this! Insert the new expression now.
- DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
- " to avoid sign extend: " << CI);
- Value *Res = EvaluateInDifferentType(Src, DestTy, true);
- assert(Res->getType() == DestTy);
-
- // If the high bits are already filled with sign bit, just replace this
- // cast with the result.
- if (NumBitsSExt > DestBitSize - SrcBitSize ||
- ComputeNumSignBits(Res) > DestBitSize - SrcBitSize)
- return ReplaceInstUsesWith(CI, Res);
-
- // We need to emit a shl + ashr to do the sign extend.
- Value *ShAmt = ConstantInt::get(DestTy, DestBitSize-SrcBitSize);
- return BinaryOperator::CreateAShr(Builder->CreateShl(Res, ShAmt, "sext"),
- ShAmt);
- }
+ // We need to emit a shl + ashr to do the sign extend.
+ Value *ShAmt = ConstantInt::get(DestTy, DestBitSize-SrcBitSize);
+ return BinaryOperator::CreateAShr(Builder->CreateShl(Res, ShAmt, "sext"),
+ ShAmt);
}
// If the input is a shl/ashr pair of a same constant, then this is a sign
diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll
index de7f8c11f2..4f0475ac59 100644
--- a/test/Transforms/InstCombine/cast.ll
+++ b/test/Transforms/InstCombine/cast.ll
@@ -185,8 +185,8 @@ define i32 @test22(i32 %X) {
%c2 = sext i8 %c1 to i32 ; <i32> [#uses=1]
%RV = shl i32 %c2, 24 ; <i32> [#uses=1]
ret i32 %RV
-; CHECK: %RV = shl i32 %X, 24
-; CHECK: ret i32 %RV
+; CHECK: shl i32 %X, 24
+; CHECK-NEXT: ret i32
}
define i32 @test23(i32 %X) {
@@ -457,3 +457,45 @@ define i64 @test48(i8 %A, i8 %a) {
; CHECK-NEXT: ret i64 %D
}
+define i64 @test49(i64 %A) {
+ %B = trunc i64 %A to i32
+ %C = or i32 %B, 1
+ %D = sext i32 %C to i64
+ ret i64 %D
+; CHECK: @test49
+; CHECK-NEXT: %C = shl i64 %A, 32
+; CHECK-NEXT: ashr i64 %C, 32
+; CHECK-NEXT: %D = or i64 {{.*}}, 1
+; CHECK-NEXT: ret i64 %D
+}
+
+define i64 @test50(i64 %A) {
+ %a = lshr i64 %A, 2
+ %B = trunc i64 %a to i32
+ %D = add i32 %B, -1
+ %E = sext i32 %D to i64
+ ret i64 %E
+; CHECK: @test50
+; CHECK-NEXT: shl i64 %A, 30
+; CHECK-NEXT: add i64 {{.*}}, -4294967296
+; CHECK-NEXT: %E = ashr i64 {{.*}}, 32
+; CHECK-NEXT: ret i64 %E
+}
+
+define i64 @test51(i64 %A, i1 %cond) {
+ %B = trunc i64 %A to i32
+ %C = and i32 %B, -2
+ %D = or i32 %B, 1
+ %E = select i1 %cond, i32 %C, i32 %D
+ %F = sext i32 %E to i64
+ ret i64 %F
+; CHECK: @test51
+; CHECK-NEXT: %C = and i64 %A, 4294967294
+; CHECK-NEXT: %D = or i64 %A, 1
+; CHECK-NEXT: %E = select i1 %cond, i64 %C, i64 %D
+; CHECK-NEXT: %sext = shl i64 %E, 32
+; CHECK-NEXT: %F = ashr i64 %sext, 32
+; CHECK-NEXT: ret i64 %F
+
+}
+