From 156d6ec86b545b43070c61be1b0bcbb38577062e Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 22 Nov 2014 04:52:52 +0000 Subject: [PATCH] InstCombine: Preserve nsw/nuw for ((X << C2)*C1) -> (X * (C1 << C2)) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222605 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstCombineMulDivRem.cpp | 15 ++++++++++++--- test/Transforms/InstCombine/mul.ll | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index c96c2d62255..78442237469 100644 --- a/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -151,9 +151,18 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { const APInt *IVal; if (match(&I, m_Mul(m_Shl(m_Value(NewOp), m_Constant(C2)), m_Constant(C1))) && - match(C1, m_APInt(IVal))) - // ((X << C1)*C2) == (X * (C2 << C1)) - return BinaryOperator::CreateMul(NewOp, ConstantExpr::getShl(C1, C2)); + match(C1, m_APInt(IVal))) { + // ((X << C2)*C1) == (X * (C1 << C2)) + Constant *Shl = ConstantExpr::getShl(C1, C2); + BinaryOperator *Mul = cast(I.getOperand(0)); + BinaryOperator *BO = BinaryOperator::CreateMul(NewOp, Shl); + if (I.hasNoUnsignedWrap() && Mul->hasNoUnsignedWrap()) + BO->setHasNoUnsignedWrap(); + if (I.hasNoSignedWrap() && Mul->hasNoSignedWrap() && + Shl->isNotMinSignedValue()) + BO->setHasNoSignedWrap(); + return BO; + } if (match(&I, m_Mul(m_Value(NewOp), m_Constant(C1)))) { Constant *NewCst = nullptr; diff --git a/test/Transforms/InstCombine/mul.ll b/test/Transforms/InstCombine/mul.ll index 905c33b501f..469ca5a0b95 100644 --- a/test/Transforms/InstCombine/mul.ll +++ b/test/Transforms/InstCombine/mul.ll @@ -204,3 +204,19 @@ define i32 @test22(i32 %A) { ret i32 %B ; CHECK: sub nsw i32 0, %A } + +define i32 @test23(i32 %A) { +; CHECK-LABEL: @test23( + %B = shl nuw i32 %A, 1 + %C = mul nuw i32 %B, 3 + ret i32 %C +; CHECK: mul nuw i32 %A, 6 +} + +define i32 @test24(i32 %A) { +; CHECK-LABEL: @test24( + %B = shl nsw i32 %A, 1 + %C = mul nsw i32 %B, 3 + ret i32 %C +; CHECK: mul nsw i32 %A, 6 +} -- 2.34.1