diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-11-22 08:57:02 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-11-22 08:57:02 +0000 |
commit | 546f81064cfea4669afe8923d81ed822aa04d6c2 (patch) | |
tree | 2e6a60b2163a9e1f0a0b904898214333217623d0 /llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | |
parent | 8279a7506dad974fd2ce164d4e45984573ebcd2c (diff) | |
download | llvm-546f81064cfea4669afe8923d81ed822aa04d6c2.zip llvm-546f81064cfea4669afe8923d81ed822aa04d6c2.tar.gz llvm-546f81064cfea4669afe8923d81ed822aa04d6c2.tar.bz2 |
InstCombine: Propagate NSW/NUW for X*(1<<Y) -> X<<Y
llvm-svn: 222613
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 78f585f..010625a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -295,10 +295,23 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { // (1 << Y)*X --> X << Y { Value *Y; - if (match(Op0, m_Shl(m_One(), m_Value(Y)))) - return BinaryOperator::CreateShl(Op1, Y); - if (match(Op1, m_Shl(m_One(), m_Value(Y)))) - return BinaryOperator::CreateShl(Op0, Y); + BinaryOperator *BO = nullptr; + bool ShlNSW = false; + if (match(Op0, m_Shl(m_One(), m_Value(Y)))) { + BO = BinaryOperator::CreateShl(Op1, Y); + ShlNSW = cast<BinaryOperator>(Op0)->hasNoSignedWrap(); + } + if (match(Op1, m_Shl(m_One(), m_Value(Y)))) { + BO = BinaryOperator::CreateShl(Op0, Y); + ShlNSW = cast<BinaryOperator>(Op1)->hasNoSignedWrap(); + } + if (BO) { + if (I.hasNoUnsignedWrap()) + BO->setHasNoUnsignedWrap(); + if (I.hasNoSignedWrap() && ShlNSW) + BO->setHasNoSignedWrap(); + return BO; + } } // If one of the operands of the multiply is a cast from a boolean value, then |