[llvm] dfe1d35 - [InstCombine] Propagate NSW/NUW flags for `(X - Y) - Z -> X - (Y + Z)` (#72693)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 19 08:02:28 PST 2023
Author: Yingwei Zheng
Date: 2023-11-20T00:02:23+08:00
New Revision: dfe1d35c629f2948c0e8cf29d926729b1dbc1709
URL: https://github.com/llvm/llvm-project/commit/dfe1d35c629f2948c0e8cf29d926729b1dbc1709
DIFF: https://github.com/llvm/llvm-project/commit/dfe1d35c629f2948c0e8cf29d926729b1dbc1709.diff
LOG: [InstCombine] Propagate NSW/NUW flags for `(X - Y) - Z -> X - (Y + Z)` (#72693)
Alive2: https://alive2.llvm.org/ce/z/gqeaVo
Related patch:
https://github.com/llvm/llvm-project/commit/31d219d2997fed1b7dc97e0adf170d5aaf65883e
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
llvm/test/Transforms/InstCombine/sub-from-sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index 318992b55e4f9f8..90b1c133461a408 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -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
diff --git a/llvm/test/Transforms/InstCombine/sub-from-sub.ll b/llvm/test/Transforms/InstCombine/sub-from-sub.ll
index 7976cdc970b9c5b..7b9e2fe4e6cdf2d 100644
--- a/llvm/test/Transforms/InstCombine/sub-from-sub.ll
+++ b/llvm/test/Transforms/InstCombine/sub-from-sub.ll
@@ -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
}
More information about the llvm-commits
mailing list