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
This commit is contained in:
David Majnemer 2014-11-22 08:57:02 +00:00
parent 082eff658e
commit 8ff39c5c44
2 changed files with 33 additions and 4 deletions

View File

@ -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

View File

@ -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
}