Skip to content

Commit 5585be4

Browse files
committed
[InstCombine] Propagate NSW/NUW flags for (X - Y) - Z -> X - (Y + Z)
1 parent ef55640 commit 5585be4

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,8 +2191,15 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
21912191

21922192
// ((X - Y) - Op1) --> X - (Y + Op1)
21932193
if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y))))) {
2194-
Value *Add = Builder.CreateAdd(Y, Op1);
2195-
return BinaryOperator::CreateSub(X, Add);
2194+
OverflowingBinaryOperator *LHSSub = cast<OverflowingBinaryOperator>(Op0);
2195+
bool HasNUW = I.hasNoUnsignedWrap() && LHSSub->hasNoUnsignedWrap();
2196+
bool HasNSW = HasNUW && I.hasNoSignedWrap() && LHSSub->hasNoSignedWrap();
2197+
Value *Add = Builder.CreateAdd(Y, Op1, "", /* HasNUW */ HasNUW,
2198+
/* HasNSW */ HasNSW);
2199+
BinaryOperator *Sub = BinaryOperator::CreateSub(X, Add);
2200+
Sub->setHasNoUnsignedWrap(HasNUW);
2201+
Sub->setHasNoSignedWrap(HasNSW);
2202+
return Sub;
21962203
}
21972204

21982205
// (~X) - (~Y) --> Y - X

llvm/test/Transforms/InstCombine/sub-from-sub.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ define i8 @t0(i8 %x, i8 %y, i8 %z) {
2020
; NSW/NUW flags are propagated
2121
define i8 @t1_flags(i8 %x, i8 %y, i8 %z) {
2222
; CHECK-LABEL: @t1_flags(
23-
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
24-
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
23+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[Y:%.*]], [[Z:%.*]]
24+
; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i8 [[X:%.*]], [[TMP1]]
2525
; CHECK-NEXT: ret i8 [[R]]
2626
;
2727
%o0 = sub nuw nsw i8 %x, %y
@@ -32,8 +32,8 @@ define i8 @t1_flags(i8 %x, i8 %y, i8 %z) {
3232
; NUW flags are propagated
3333
define i8 @t1_flags_nuw_only(i8 %x, i8 %y, i8 %z) {
3434
; CHECK-LABEL: @t1_flags_nuw_only(
35-
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
36-
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
35+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[Y:%.*]], [[Z:%.*]]
36+
; CHECK-NEXT: [[R:%.*]] = sub nuw i8 [[X:%.*]], [[TMP1]]
3737
; CHECK-NEXT: ret i8 [[R]]
3838
;
3939
%o0 = sub nuw i8 %x, %y

0 commit comments

Comments
 (0)