summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-11-22 08:57:02 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-11-22 08:57:02 +0000
commit8ff39c5c44f6826056e728a1edad67a91875959b (patch)
treee61da4269eb2fba8730572f90a2f51c423c78432
parent082eff658ef184d7ec9b7c932680e64b192bb58b (diff)
InstCombine: Propagate NSW/NUW for X*(1<<Y) -> X<<Y
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222613 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/InstCombine/InstCombineMulDivRem.cpp21
-rw-r--r--test/Transforms/InstCombine/mul.ll16
2 files changed, 33 insertions, 4 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 78f585f6f73..010625a7157 100644
--- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/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
diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll
index a782cfd78d5..934448290e0 100644
--- a/test/Transforms/InstCombine/mul.ll
+++ b/test/Transforms/InstCombine/mul.ll
@@ -229,3 +229,19 @@ define i32 @test25(i32 %A, i32 %B) {
ret i32 %E
; CHECK: mul nsw i32 %A, %B
}
+
+define i32 @test26(i32 %A, i32 %B) {
+; CHECK-LABEL: @test26(
+ %C = shl nsw i32 1, %B
+ %D = mul nsw i32 %A, %C
+ ret i32 %D
+; CHECK: shl nsw i32 %A, %B
+}
+
+define i32 @test27(i32 %A, i32 %B) {
+; CHECK-LABEL: @test27(
+ %C = shl i32 1, %B
+ %D = mul nuw i32 %A, %C
+ ret i32 %D
+; CHECK: shl nuw i32 %A, %B
+}