From 8ff39c5c44f6826056e728a1edad67a91875959b Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Sat, 22 Nov 2014 08:57:02 +0000 Subject: [PATCH] InstCombine: Propagate NSW/NUW for X*(1< 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(Op0)->hasNoSignedWrap(); + } + if (match(Op1, m_Shl(m_One(), m_Value(Y)))) { + BO = BinaryOperator::CreateShl(Op0, Y); + ShlNSW = cast(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 +}