diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index d88bc2c4901c7..1b78acea62bd6 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1830,10 +1830,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { bool IntMinIsPoison = cast(II->getArgOperand(1))->isOneValue(); // abs(-x) -> abs(x) - // TODO: Copy nsw if it was present on the neg? Value *X; - if (match(IIOperand, m_Neg(m_Value(X)))) + if (match(IIOperand, m_Neg(m_Value(X)))) { + if (cast(IIOperand)->hasNoSignedWrap() || IntMinIsPoison) + replaceOperand(*II, 1, Builder.getTrue()); return replaceOperand(*II, 0, X); + } if (match(IIOperand, m_c_Select(m_Neg(m_Value(X)), m_Deferred(X)))) return replaceOperand(*II, 0, X); diff --git a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll index 022d60d2f501b..d32f0e4690502 100644 --- a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll +++ b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll @@ -229,7 +229,7 @@ define i32 @abs_of_neg(i32 %x) { define <4 x i32> @abs_of_neg_vec(<4 x i32> %x) { ; CHECK-LABEL: @abs_of_neg_vec( -; CHECK-NEXT: [[B:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false) +; CHECK-NEXT: [[B:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 true) ; CHECK-NEXT: ret <4 x i32> [[B]] ; %a = sub nsw <4 x i32> zeroinitializer, %x