mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
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
This commit is contained in:
parent
24e64df7ec
commit
dde5ee5d37
@ -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
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user