Port SelectionDAG's ComputeNumSignBits-using code to instcombine,

now that instcombine also has ComputeNumSignBits.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51350 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2008-05-20 21:01:12 +00:00
parent f6cadc440c
commit f35c8822a3
2 changed files with 35 additions and 1 deletions

View File

@ -2085,7 +2085,7 @@ unsigned InstCombiner::ComputeNumSignBits(Value *V, unsigned Depth) const{
case Instruction::AShr:
Tmp = ComputeNumSignBits(U->getOperand(0), Depth+1);
// SRA X, C -> adds C sign bits.
// ashr X, C -> adds C sign bits.
if (ConstantInt *C = dyn_cast<ConstantInt>(U->getOperand(1))) {
Tmp += C->getZExtValue();
if (Tmp > TyBits) Tmp = TyBits;
@ -8195,6 +8195,33 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) {
}
}
}
// See if the value being truncated is already sign extended. If so, just
// eliminate the trunc/sext pair.
if (getOpcode(Src) == Instruction::Trunc) {
Value *Op = cast<User>(Src)->getOperand(0);
unsigned OpBits = cast<IntegerType>(Op->getType())->getBitWidth();
unsigned MidBits = cast<IntegerType>(Src->getType())->getBitWidth();
unsigned DestBits = cast<IntegerType>(CI.getType())->getBitWidth();
unsigned NumSignBits = ComputeNumSignBits(Op);
if (OpBits == DestBits) {
// Op is i32, Mid is i8, and Dest is i32. If Op has more than 24 sign
// bits, it is already ready.
if (NumSignBits > DestBits-MidBits)
return ReplaceInstUsesWith(CI, Op);
} else if (OpBits < DestBits) {
// Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign
// bits, just sext from i32.
if (NumSignBits > OpBits-MidBits)
return new SExtInst(Op, CI.getType(), "tmp");
} else {
// Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign
// bits, just truncate to i32.
if (NumSignBits > OpBits-MidBits)
return new TruncInst(Op, CI.getType(), "tmp");
}
}
return 0;
}

View File

@ -43,3 +43,10 @@ define i64 @voo(i32 %x) {
%s = sext i32 %u to i64
ret i64 %s
}
define i32 @woo(i8 %a, i32 %f, i1 %p, i32* %z) {
%d = ashr i32 %f, 24
%e = select i1 %p, i32 %d, i32 0
%s = trunc i32 %e to i16
%n = sext i16 %s to i32
ret i32 %n
}