diff options
Diffstat (limited to 'lib/Transforms/InstCombine')
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 5 | ||||
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineCasts.cpp | 13 | ||||
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 9 | ||||
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 2 | ||||
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineShifts.cpp | 24 | ||||
| -rw-r--r-- | lib/Transforms/InstCombine/Makefile | 1 |
6 files changed, 42 insertions, 12 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index af300fc3577b..fa7bb12ff218 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1751,6 +1751,11 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { return BinaryOperator::CreateOr(NotX, NotY); return BinaryOperator::CreateAnd(NotX, NotY); } + + } else if (Op0I->getOpcode() == Instruction::AShr) { + // ~(~X >>s Y) --> (X >>s Y) + if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) + return BinaryOperator::CreateAShr(Op0NotVal, Op0I->getOperand(1)); } } } diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index e018b351082a..f25dd3582b2e 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -955,6 +955,19 @@ Instruction *InstCombiner::visitSExt(SExtInst &CI) { ShAmt); } + // If this input is a trunc from our destination, then turn sext(trunc(x)) + // into shifts. + if (TruncInst *TI = dyn_cast<TruncInst>(Src)) + if (TI->hasOneUse() && TI->getOperand(0)->getType() == DestTy) { + uint32_t SrcBitSize = SrcTy->getScalarSizeInBits(); + uint32_t DestBitSize = DestTy->getScalarSizeInBits(); + + // We need to emit a shl + ashr to do the sign extend. + Value *ShAmt = ConstantInt::get(DestTy, DestBitSize-SrcBitSize); + Value *Res = Builder->CreateShl(TI->getOperand(0), ShAmt, "sext"); + return BinaryOperator::CreateAShr(Res, ShAmt); + } + // If the input is a shl/ashr pair of a same constant, then this is a sign // extension from a smaller value. If we could trust arbitrary bitwidth // integers, we could turn this into a truncate to the smaller bit and then diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 6c0ecc9f9358..ae728ddecfda 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -366,7 +366,7 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { // alloca dead. // If the RHS is an alloca with a two uses, the other one being a // llvm.dbg.declare, zapify the store and the declare, making the - // alloca dead. We must do this to prevent declare's from affecting + // alloca dead. We must do this to prevent declares from affecting // codegen. if (!SI.isVolatile()) { if (Ptr->hasOneUse()) { @@ -408,8 +408,6 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { --BBI; // Don't count debug info directives, lest they affect codegen, // and we skip pointer-to-pointer bitcasts, which are NOPs. - // It is necessary for correctness to skip those that feed into a - // llvm.dbg.declare, as these are not present when debugging is off. if (isa<DbgInfoIntrinsic>(BBI) || (isa<BitCastInst>(BBI) && isa<PointerType>(BBI->getType()))) { ScanInsts++; @@ -475,9 +473,8 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { // If this store is the last instruction in the basic block (possibly - // excepting debug info instructions and the pointer bitcasts that feed - // into them), and if the block ends with an unconditional branch, try - // to move it to the successor block. + // excepting debug info instructions), and if the block ends with an + // unconditional branch, try to move it to the successor block. BBI = &SI; do { ++BBI; diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 6afc0cdf5360..2e26a75b2ad2 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -407,7 +407,7 @@ Instruction *InstCombiner::visitUDiv(BinaryOperator &I) { return Common; if (ConstantInt *C = dyn_cast<ConstantInt>(Op1)) { - // X udiv C^2 -> X >> C + // X udiv 2^C -> X >> C // Check to see if this is an unsigned division with an exact power of 2, // if so, convert to a right shift. if (C->getValue().isPowerOf2()) // 0 not included in isPowerOf2 diff --git a/lib/Transforms/InstCombine/InstCombineShifts.cpp b/lib/Transforms/InstCombine/InstCombineShifts.cpp index fe91da1b6af4..321c91d57d2f 100644 --- a/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -404,12 +404,26 @@ Instruction *InstCombiner::visitAShr(BinaryOperator &I) { if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) { // If the input is a SHL by the same constant (ashr (shl X, C), C), then we - // have a sign-extend idiom. If the input value is known to already be sign - // extended enough, delete the extension. + // have a sign-extend idiom. Value *X; - if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1))) && - ComputeNumSignBits(X) > Op1C->getZExtValue()) - return ReplaceInstUsesWith(I, X); + if (match(Op0, m_Shl(m_Value(X), m_Specific(Op1)))) { + // If the input value is known to already be sign extended enough, delete + // the extension. + if (ComputeNumSignBits(X) > Op1C->getZExtValue()) + return ReplaceInstUsesWith(I, X); + + // If the input is an extension from the shifted amount value, e.g. + // %x = zext i8 %A to i32 + // %y = shl i32 %x, 24 + // %z = ashr %y, 24 + // then turn this into "z = sext i8 A to i32". + if (ZExtInst *ZI = dyn_cast<ZExtInst>(X)) { + uint32_t SrcBits = ZI->getOperand(0)->getType()->getScalarSizeInBits(); + uint32_t DestBits = ZI->getType()->getScalarSizeInBits(); + if (Op1C->getZExtValue() == DestBits-SrcBits) + return new SExtInst(ZI->getOperand(0), ZI->getType()); + } + } } // See if we can turn a signed shr into an unsigned shr. diff --git a/lib/Transforms/InstCombine/Makefile b/lib/Transforms/InstCombine/Makefile index 0c488e78b6d9..f9de42afb0c0 100644 --- a/lib/Transforms/InstCombine/Makefile +++ b/lib/Transforms/InstCombine/Makefile @@ -10,6 +10,7 @@ LEVEL = ../../.. LIBRARYNAME = LLVMInstCombine BUILD_ARCHIVE = 1 +CXXFLAGS = -fno-rtti include $(LEVEL)/Makefile.common |
