Turn stuff like:

icmp slt i32 %X, 0              ; <i1>:0 [#uses=1]
        sext i1 %0 to i32               ; <i32>:1 [#uses=1]

into:

        %X.lobit = ashr i32 %X, 31              ; <i32> [#uses=1]

This implements InstCombine/icmp.ll:test[34]


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35891 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-04-11 06:57:46 +00:00
parent a2e2c9bbf3
commit 8a9f571052

View File

@ -193,9 +193,9 @@ namespace {
BinaryOperator &I);
Instruction *commonCastTransforms(CastInst &CI);
Instruction *commonIntCastTransforms(CastInst &CI);
Instruction *visitTrunc(CastInst &CI);
Instruction *visitZExt(CastInst &CI);
Instruction *visitSExt(CastInst &CI);
Instruction *visitTrunc(TruncInst &CI);
Instruction *visitZExt(ZExtInst &CI);
Instruction *visitSExt(SExtInst &CI);
Instruction *visitFPTrunc(CastInst &CI);
Instruction *visitFPExt(CastInst &CI);
Instruction *visitFPToUI(CastInst &CI);
@ -6471,7 +6471,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
return 0;
}
Instruction *InstCombiner::visitTrunc(CastInst &CI) {
Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
if (Instruction *Result = commonIntCastTransforms(CI))
return Result;
@ -6528,7 +6528,7 @@ Instruction *InstCombiner::visitTrunc(CastInst &CI) {
return 0;
}
Instruction *InstCombiner::visitZExt(CastInst &CI) {
Instruction *InstCombiner::visitZExt(ZExtInst &CI) {
// If one of the common conversion will work ..
if (Instruction *Result = commonIntCastTransforms(CI))
return Result;
@ -6653,13 +6653,44 @@ Instruction *InstCombiner::visitZExt(CastInst &CI) {
return 0;
}
Instruction *InstCombiner::visitSExt(CastInst &CI) {
Instruction *InstCombiner::visitSExt(SExtInst &CI) {
if (Instruction *I = commonIntCastTransforms(CI))
return I;
// (x <s 0) ? -1 : 0 -> ashr x, 31
// (x >u 2147483647) ? -1 : 0 -> ashr x, 31
Value *Src = CI.getOperand(0);
// sext (x <s 0) -> ashr x, 31 -> all ones if signed
// sext (x >s -1) -> ashr x, 31 -> all ones if not signed
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Src)) {
// If we are just checking for a icmp eq of a single bit and zext'ing it
// to an integer, then shift the bit to the appropriate place and then
// cast to integer to avoid the comparison.
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(ICI->getOperand(1))) {
const APInt &Op1CV = Op1C->getValue();
// sext (x <s 0) to i32 --> x>>s31 true if signbit set.
// sext (x >s -1) to i32 --> (x>>s31)^-1 true if signbit clear.
if ((ICI->getPredicate() == ICmpInst::ICMP_SLT && Op1CV == 0) ||
(ICI->getPredicate() == ICmpInst::ICMP_SGT &&Op1CV.isAllOnesValue())){
Value *In = ICI->getOperand(0);
Value *Sh = ConstantInt::get(In->getType(),
In->getType()->getPrimitiveSizeInBits()-1);
In = InsertNewInstBefore(BinaryOperator::createAShr(In, Sh,
In->getName()+".lobit"),
CI);
if (In->getType() != CI.getType())
In = CastInst::createIntegerCast(In, CI.getType(),
true/*SExt*/, "tmp", &CI);
if (ICI->getPredicate() == ICmpInst::ICMP_SGT)
In = InsertNewInstBefore(BinaryOperator::createNot(In,
In->getName()+".not"), CI);
return ReplaceInstUsesWith(CI, In);
}
}
}
return 0;
}