diff options
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp index a30bcbd64ca..c0a1df6b9a7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp @@ -715,14 +715,25 @@ Instruction *InstCombiner::visitShl(BinaryOperator &I) { unsigned ShAmt = ShAmtAPInt->getZExtValue(); unsigned BitWidth = Ty->getScalarSizeInBits(); - // shl (zext X), ShAmt --> zext (shl X, ShAmt) - // This is only valid if X would have zeros shifted out. Value *X; if (match(Op0, m_OneUse(m_ZExt(m_Value(X))))) { unsigned SrcWidth = X->getType()->getScalarSizeInBits(); + // shl (zext X), ShAmt --> zext (shl X, ShAmt) + // This is only valid if X would have zeros shifted out. if (ShAmt < SrcWidth && MaskedValueIsZero(X, APInt::getHighBitsSet(SrcWidth, ShAmt), 0, &I)) return new ZExtInst(Builder.CreateShl(X, ShAmt), Ty); + + // shl (zext (mul MulOp, C2)), ShAmt --> mul (zext MulOp), (C2 << ShAmt) + // This is valid if the high bits of the wider multiply are shifted out. + Value *MulOp; + const APInt *C2; + if (ShAmt >= (BitWidth - SrcWidth) && + match(X, m_Mul(m_Value(MulOp), m_APInt(C2)))) { + Value *Zext = Builder.CreateZExt(MulOp, Ty); + Constant *NewMulC = ConstantInt::get(Ty, C2->zext(BitWidth).shl(ShAmt)); + return BinaryOperator::CreateMul(Zext, NewMulC); + } } // (X >> C) << C --> X & (-1 << C) |

