mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
Port SelectionDAG's ComputeNumSignBits-using code to instcombine,
now that instcombine also has ComputeNumSignBits. llvm-svn: 51350
This commit is contained in:
parent
807c2df887
commit
b48d4a75f6
@ -2085,7 +2085,7 @@ unsigned InstCombiner::ComputeNumSignBits(Value *V, unsigned Depth) const{
|
|||||||
|
|
||||||
case Instruction::AShr:
|
case Instruction::AShr:
|
||||||
Tmp = ComputeNumSignBits(U->getOperand(0), Depth+1);
|
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))) {
|
if (ConstantInt *C = dyn_cast<ConstantInt>(U->getOperand(1))) {
|
||||||
Tmp += C->getZExtValue();
|
Tmp += C->getZExtValue();
|
||||||
if (Tmp > TyBits) Tmp = TyBits;
|
if (Tmp > TyBits) Tmp = TyBits;
|
||||||
@ -8196,6 +8196,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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,3 +43,10 @@ define i64 @voo(i32 %x) {
|
|||||||
%s = sext i32 %u to i64
|
%s = sext i32 %u to i64
|
||||||
ret i64 %s
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user