mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-09 21:32:49 +00:00
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. llvm-svn: 93097
This commit is contained in:
parent
a04ed0659f
commit
1106f03886
@ -695,6 +695,11 @@ static int CanEvaluateZExtd(Value *V, const Type *Ty,unsigned &NumCastsRemoved,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
|
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 one of the common conversion will work, do it.
|
||||||
if (Instruction *Result = commonCastTransforms(CI))
|
if (Instruction *Result = commonCastTransforms(CI))
|
||||||
return Result;
|
return Result;
|
||||||
@ -716,33 +721,25 @@ Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
|
|||||||
int BitsZExt = CanEvaluateZExtd(Src, DestTy, NumCastsRemoved, TD);
|
int BitsZExt = CanEvaluateZExtd(Src, DestTy, NumCastsRemoved, TD);
|
||||||
if (BitsZExt == -1) return 0;
|
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 SrcBitSize = SrcTy->getScalarSizeInBits();
|
||||||
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
uint32_t DestBitSize = DestTy->getScalarSizeInBits();
|
||||||
|
if (unsigned(BitsZExt) >= DestBitSize-SrcBitSize ||
|
||||||
// If this is a zero-extension, we need to do an AND to maintain the clear
|
MaskedValueIsZero(Res, APInt::getHighBitsSet(DestBitSize,
|
||||||
// top-part of the computation. If we know the result will be zero
|
DestBitSize-SrcBitSize)))
|
||||||
// extended enough already, we don't need the and.
|
return ReplaceInstUsesWith(CI, Res);
|
||||||
if (NumCastsRemoved >= 1 ||
|
|
||||||
unsigned(BitsZExt) >= DestBitSize-SrcBitSize) {
|
// We need to emit an AND to clear the high bits.
|
||||||
|
Constant *C = ConstantInt::get(CI.getContext(),
|
||||||
// Okay, we can transform this! Insert the new expression now.
|
APInt::getLowBitsSet(DestBitSize, SrcBitSize));
|
||||||
DEBUG(dbgs() << "ICE: EvaluateInDifferentType converting expression type"
|
return BinaryOperator::CreateAnd(Res, C);
|
||||||
" 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 this is a TRUNC followed by a ZEXT then we are dealing with integral
|
// 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) {
|
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))
|
if (Instruction *I = commonCastTransforms(CI))
|
||||||
return I;
|
return I;
|
||||||
|
|
||||||
|
@ -430,4 +430,30 @@ define i64 @test46(i64 %A) {
|
|||||||
; CHECK-NEXT: ret i64 %D
|
; 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
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user