diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 0f96377f3629f8..779d298da7a403 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -107,14 +107,19 @@ static Value *foldMulSelectToNegate(BinaryOperator &I, // mul (select Cond, 1, -1), OtherOp --> select Cond, OtherOp, -OtherOp // mul OtherOp, (select Cond, 1, -1) --> select Cond, OtherOp, -OtherOp if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_One(), m_AllOnes())), - m_Value(OtherOp)))) - return Builder.CreateSelect(Cond, OtherOp, Builder.CreateNeg(OtherOp)); - + m_Value(OtherOp)))) { + bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap(); + Value *Neg = Builder.CreateNeg(OtherOp, "", false, HasAnyNoWrap); + return Builder.CreateSelect(Cond, OtherOp, Neg); + } // mul (select Cond, -1, 1), OtherOp --> select Cond, -OtherOp, OtherOp // mul OtherOp, (select Cond, -1, 1) --> select Cond, -OtherOp, OtherOp if (match(&I, m_c_Mul(m_OneUse(m_Select(m_Value(Cond), m_AllOnes(), m_One())), - m_Value(OtherOp)))) - return Builder.CreateSelect(Cond, Builder.CreateNeg(OtherOp), OtherOp); + m_Value(OtherOp)))) { + bool HasAnyNoWrap = I.hasNoSignedWrap() || I.hasNoUnsignedWrap(); + Value *Neg = Builder.CreateNeg(OtherOp, "", false, HasAnyNoWrap); + return Builder.CreateSelect(Cond, Neg, OtherOp); + } // fmul (select Cond, 1.0, -1.0), OtherOp --> select Cond, OtherOp, -OtherOp // fmul OtherOp, (select Cond, 1.0, -1.0) --> select Cond, OtherOp, -OtherOp diff --git a/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll b/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll index 5c66ea07211509..7d2038ece44d04 100644 --- a/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll +++ b/llvm/test/Transforms/InstCombine/mul-inseltpoison.ll @@ -720,7 +720,7 @@ define i32 @negate_if_false(i32 %x, i1 %cond) { define i32 @negate_if_true_nsw(i32 %x, i1 %cond) { ; CHECK-LABEL: @negate_if_true_nsw( -; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[X]] ; CHECK-NEXT: ret i32 [[TMP2]] ; @@ -731,7 +731,7 @@ define i32 @negate_if_true_nsw(i32 %x, i1 %cond) { define i32 @negate_if_true_nuw(i32 %x, i1 %cond) { ; CHECK-LABEL: @negate_if_true_nuw( -; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[X]] ; CHECK-NEXT: ret i32 [[TMP2]] ; @@ -742,7 +742,7 @@ define i32 @negate_if_true_nuw(i32 %x, i1 %cond) { define i32 @negate_if_false_nsw(i32 %x, i1 %cond) { ; CHECK-LABEL: @negate_if_false_nsw( -; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[X]], i32 [[TMP1]] ; CHECK-NEXT: ret i32 [[TMP2]] ; @@ -753,7 +753,7 @@ define i32 @negate_if_false_nsw(i32 %x, i1 %cond) { define i32 @negate_if_false_nuw(i32 %x, i1 %cond) { ; CHECK-LABEL: @negate_if_false_nuw( -; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[X:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = sub nsw i32 0, [[X:%.*]] ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[COND:%.*]], i32 [[X]], i32 [[TMP1]] ; CHECK-NEXT: ret i32 [[TMP2]] ;