summaryrefslogtreecommitdiff
path: root/lib/Transforms/InstCombine
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/InstCombine')
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp5
-rw-r--r--lib/Transforms/InstCombine/InstCombineCasts.cpp13
-rw-r--r--lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp9
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp2
-rw-r--r--lib/Transforms/InstCombine/InstCombineShifts.cpp24
-rw-r--r--lib/Transforms/InstCombine/Makefile1
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