From: Chris Lattner Date: Fri, 12 Mar 2004 23:53:13 +0000 (+0000) Subject: Implement InstCombine/sub.ll:test12 & test13 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=9c2906744ab1dc5263ade61c5d376cb9bd786069;p=oota-llvm.git Implement InstCombine/sub.ll:test12 & test13 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12353 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 7d308be1f21..4f9821e6b71 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -212,6 +212,18 @@ static const Type *getSignedIntegralType(const Type *Ty) { } } +// getUnsignedIntegralType - Given an signed integral type, return the unsigned +// version of it that has the same size. +static const Type *getUnsignedIntegralType(const Type *Ty) { + switch (Ty->getPrimitiveID()) { + default: assert(0 && "Invalid signed integer type!"); abort(); + case Type::SByteTyID: return Type::UByteTy; + case Type::ShortTyID: return Type::UShortTy; + case Type::IntTyID: return Type::UIntTy; + case Type::LongTyID: return Type::ULongTy; + } +} + // getPromotedType - Return the specified type promoted as it would be to pass // though a va_arg area... static const Type *getPromotedType(const Type *Ty) { @@ -558,6 +570,30 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) { BinaryOperator::getNotArgument(cast(Op1)), ConstantExpr::get(Instruction::Add, C, ConstantInt::get(I.getType(), 1))); + // -((uint)X >> 31) -> ((int)X >> 31) + // -((int)X >> 31) -> ((uint)X >> 31) + if (C->isNullValue()) + if (ShiftInst *SI = dyn_cast(Op1)) + if (SI->getOpcode() == Instruction::Shr) + if (ConstantUInt *CU = dyn_cast(SI->getOperand(1))) { + const Type *NewTy; + if (C->getType()->isSigned()) + NewTy = getUnsignedIntegralType(C->getType()); + else + NewTy = getSignedIntegralType(C->getType()); + // Check to see if we are shifting out everything but the sign bit. + if (CU->getValue() == C->getType()->getPrimitiveSize()*8-1) { + // Ok, the transformation is safe. Insert a cast of the incoming + // value, then the new shift, then the new cast. + Instruction *FirstCast = new CastInst(SI->getOperand(0), NewTy, + SI->getOperand(0)->getName()); + Value *InV = InsertNewInstBefore(FirstCast, I); + Instruction *NewShift = new ShiftInst(Instruction::Shr, FirstCast, + CU, SI->getName()); + InV = InsertNewInstBefore(NewShift, I); + return new CastInst(NewShift, I.getType()); + } + } } if (BinaryOperator *Op1I = dyn_cast(Op1))