Skip to content

Commit

Permalink
[InstCombine] Propagate NSW/NUW flags for (X - Y) - Z -> X - (Y + Z) (
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw authored and zahiraam committed Nov 20, 2023
1 parent db50bf3 commit 6bdd8d0
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
11 changes: 9 additions & 2 deletions llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2191,8 +2191,15 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {

// ((X - Y) - Op1) --> X - (Y + Op1)
if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y))))) {
Value *Add = Builder.CreateAdd(Y, Op1);
return BinaryOperator::CreateSub(X, Add);
OverflowingBinaryOperator *LHSSub = cast<OverflowingBinaryOperator>(Op0);
bool HasNUW = I.hasNoUnsignedWrap() && LHSSub->hasNoUnsignedWrap();
bool HasNSW = HasNUW && I.hasNoSignedWrap() && LHSSub->hasNoSignedWrap();
Value *Add = Builder.CreateAdd(Y, Op1, "", /* HasNUW */ HasNUW,
/* HasNSW */ HasNSW);
BinaryOperator *Sub = BinaryOperator::CreateSub(X, Add);
Sub->setHasNoUnsignedWrap(HasNUW);
Sub->setHasNoSignedWrap(HasNSW);
return Sub;
}

// (~X) - (~Y) --> Y - X
Expand Down
70 changes: 69 additions & 1 deletion llvm/test/Transforms/InstCombine/sub-from-sub.ll
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,82 @@ define i8 @t0(i8 %x, i8 %y, i8 %z) {
ret i8 %r
}

; No flags are propagated
; NSW/NUW flags are propagated
define i8 @t1_flags(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags(
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub nuw nsw i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub nuw nsw i8 %x, %y
%r = sub nuw nsw i8 %o0, %z
ret i8 %r
}

; NUW flags are propagated
define i8 @t1_flags_nuw_only(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags_nuw_only(
; CHECK-NEXT: [[TMP1:%.*]] = add nuw i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub nuw i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub nuw i8 %x, %y
%r = sub nuw i8 %o0, %z
ret i8 %r
}

; Negative tests
define i8 @t1_flags_sub_nsw_sub(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags_sub_nsw_sub(
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub nsw i8 %x, %y
%r = sub i8 %o0, %z
ret i8 %r
}

define i8 @t1_flags_nuw_first(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags_nuw_first(
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub nuw i8 %x, %y
%r = sub i8 %o0, %z
ret i8 %r
}

define i8 @t1_flags_nuw_second(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags_nuw_second(
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub i8 %x, %y
%r = sub nuw i8 %o0, %z
ret i8 %r
}

define i8 @t1_flags_nuw_nsw_first(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags_nuw_nsw_first(
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub nuw nsw i8 %x, %y
%r = sub i8 %o0, %z
ret i8 %r
}

define i8 @t1_flags_nuw_nsw_second(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @t1_flags_nuw_nsw_second(
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[Y:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[R:%.*]] = sub i8 [[X:%.*]], [[TMP1]]
; CHECK-NEXT: ret i8 [[R]]
;
%o0 = sub i8 %x, %y
%r = sub nuw nsw i8 %o0, %z
ret i8 %r
}
Expand Down

0 comments on commit 6bdd8d0

Please sign in to comment.