[llvm] dd9a99f - [InstCombine] Preserve nsw in A + -B fold

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 07:33:25 PDT 2024


Author: Nikita Popov
Date: 2024-08-16T16:33:12+02:00
New Revision: dd9a99f2b634d95072ae49ebcbe5598877de4985

URL: https://github.com/llvm/llvm-project/commit/dd9a99f2b634d95072ae49ebcbe5598877de4985
DIFF: https://github.com/llvm/llvm-project/commit/dd9a99f2b634d95072ae49ebcbe5598877de4985.diff

LOG: [InstCombine] Preserve nsw in A + -B fold

This was already done for -B + A, but not for A + -B.

Proof: https://alive2.llvm.org/ce/z/F3V2yZ

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
    llvm/test/Transforms/InstCombine/add.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 3bd086230cbec..123f810bacfb6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1548,8 +1548,12 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
   }
 
   // A + -B  -->  A - B
-  if (match(RHS, m_Neg(m_Value(B))))
-    return BinaryOperator::CreateSub(LHS, B);
+  if (match(RHS, m_Neg(m_Value(B)))) {
+    auto *Sub = BinaryOperator::CreateSub(LHS, B);
+    auto *OBO = cast<OverflowingBinaryOperator>(RHS);
+    Sub->setHasNoSignedWrap(I.hasNoSignedWrap() && OBO->hasNoSignedWrap());
+    return Sub;
+  }
 
   if (Value *V = checkForNegativeOperand(I, Builder))
     return replaceInstUsesWith(I, V);

diff  --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index c61a9006e020d..b1f21e58de1e2 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -114,7 +114,7 @@ define i32 @test4(i32 %A, i32 %BB) {
 define i32 @test4_both_nsw(i32 %A, i32 %BB) {
 ; CHECK-LABEL: @test4_both_nsw(
 ; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BB:%.*]], 1
-; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B]], [[A:%.*]]
+; CHECK-NEXT:    [[D:%.*]] = sub nsw i32 [[B]], [[A:%.*]]
 ; CHECK-NEXT:    ret i32 [[D]]
 ;
   %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization


        


More information about the llvm-commits mailing list