diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1321,7 +1321,8 @@ if (match(LHS, m_Neg(m_Value(A)))) { // -A + -B --> -(A + B) if (match(RHS, m_Neg(m_Value(B)))) - return BinaryOperator::CreateNeg(Builder.CreateAdd(A, B)); + return BinaryOperator::CreateNeg(Builder.CreateAdd( + A, B, "", I.hasNoUnsignedWrap(), I.hasNoSignedWrap())); // -A + B --> B - A return BinaryOperator::CreateSub(RHS, A); diff --git a/llvm/test/Transforms/InstCombine/add5.ll b/llvm/test/Transforms/InstCombine/add5.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/add5.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +;; -A + -B --> -(A + B) +define dso_local i32 @test_neg_add_nsw(i32 %A, i32 %B) #0 { +; CHECK-LABEL: @test_neg_add_nsw( +; CHECK-NEXT:entry: +; CHECK-NEXT: %0 = add nsw i32 %A, %B +; CHECK-NEXT: %add = sub i32 0, %0 +; CHECK-NEXT: ret i32 %add +entry: + %B.addr = alloca i32, align 4 + %A.addr = alloca i32, align 4 + store i32 %B, i32* %B.addr, align 4 + store i32 %A, i32* %A.addr, align 4 + %0 = load i32, i32* %A.addr, align 4 + %sub = sub nsw i32 0, %0 + %1 = load i32, i32* %B.addr, align 4 + %sub1 = sub nsw i32 0, %1 + %add = add nsw i32 %sub, %sub1 + ret i32 %add +}