Skip to content

Commit dd9a99f

Browse files
committed
[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
1 parent 3c3fc4c commit dd9a99f

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,8 +1548,12 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
15481548
}
15491549

15501550
// A + -B --> A - B
1551-
if (match(RHS, m_Neg(m_Value(B))))
1552-
return BinaryOperator::CreateSub(LHS, B);
1551+
if (match(RHS, m_Neg(m_Value(B)))) {
1552+
auto *Sub = BinaryOperator::CreateSub(LHS, B);
1553+
auto *OBO = cast<OverflowingBinaryOperator>(RHS);
1554+
Sub->setHasNoSignedWrap(I.hasNoSignedWrap() && OBO->hasNoSignedWrap());
1555+
return Sub;
1556+
}
15531557

15541558
if (Value *V = checkForNegativeOperand(I, Builder))
15551559
return replaceInstUsesWith(I, V);

llvm/test/Transforms/InstCombine/add.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ define i32 @test4(i32 %A, i32 %BB) {
114114
define i32 @test4_both_nsw(i32 %A, i32 %BB) {
115115
; CHECK-LABEL: @test4_both_nsw(
116116
; CHECK-NEXT: [[B:%.*]] = xor i32 [[BB:%.*]], 1
117-
; CHECK-NEXT: [[D:%.*]] = sub i32 [[B]], [[A:%.*]]
117+
; CHECK-NEXT: [[D:%.*]] = sub nsw i32 [[B]], [[A:%.*]]
118118
; CHECK-NEXT: ret i32 [[D]]
119119
;
120120
%B = xor i32 %BB, 1 ; thwart complexity-based canonicalization

0 commit comments

Comments
 (0)