From 8a9f57105207da1d4fc6ec4026ac9b586ed86976 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 11 Apr 2007 06:57:46 +0000 Subject: [PATCH] Turn stuff like: icmp slt i32 %X, 0 ; :0 [#uses=1] sext i1 %0 to i32 ; :1 [#uses=1] into: %X.lobit = ashr i32 %X, 31 ; [#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 --- .../Scalar/InstructionCombining.cpp | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 00b1bca656b..ec27055f72e 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -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 ashr x, 31 - // (x >u 2147483647) ? -1 : 0 -> ashr x, 31 - + Value *Src = CI.getOperand(0); + + // sext (x ashr x, 31 -> all ones if signed + // sext (x >s -1) -> ashr x, 31 -> all ones if not signed + if (ICmpInst *ICI = dyn_cast(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(ICI->getOperand(1))) { + const APInt &Op1CV = Op1C->getValue(); + + // sext (x 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; }