[PATCH] D157598: [InstCombine] Transform sub(sext(add(X, Y)), sext(add(X, Z))) to sub(Y, Z) given nsw adds

Dave Green via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 10 03:34:32 PDT 2023


dmgreen created this revision.
dmgreen added reviewers: nikic, spatel, goldstein.w.n.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
dmgreen requested review of this revision.
Herald added a project: LLVM.

This adds combines for `sext(X +nsw Y) - sext(X +nsw Z) -> sext(Y) - sext(Z)` and `zext(X +nuw Y) - zext(X +nuw Z) -> zext(Y) - zext(Z)`. This is especially useful when Y and Z are constants.

See https://alive2.llvm.org/ce/z/XEazaS and https://alive2.llvm.org/ce/z/kHGPtU.


https://reviews.llvm.org/D157598

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
  llvm/test/Transforms/InstCombine/sub-ext-add.ll


Index: llvm/test/Transforms/InstCombine/sub-ext-add.ll
===================================================================
--- llvm/test/Transforms/InstCombine/sub-ext-add.ll
+++ llvm/test/Transforms/InstCombine/sub-ext-add.ll
@@ -5,11 +5,9 @@
 
 define i32 @subaddnuw(i8 %a, i8 %C1, i8 %C2) {
 ; CHECK-LABEL: @subaddnuw(
-; CHECK-NEXT:    [[L3619:%.*]] = add nuw i8 [[A:%.*]], [[C1:%.*]]
-; CHECK-NEXT:    [[L3620:%.*]] = zext i8 [[L3619]] to i32
-; CHECK-NEXT:    [[L3621:%.*]] = add nuw i8 [[A]], [[C2:%.*]]
-; CHECK-NEXT:    [[L3622:%.*]] = zext i8 [[L3621]] to i32
-; CHECK-NEXT:    [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]]
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[C2:%.*]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[C1:%.*]] to i32
+; CHECK-NEXT:    [[L3623:%.*]] = sub nsw i32 [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    ret i32 [[L3623]]
 ;
   %l3619 = add nuw i8 %a, %C1
@@ -22,12 +20,7 @@
 
 define i32 @subaddnuw_c(i8 %a) {
 ; CHECK-LABEL: @subaddnuw_c(
-; CHECK-NEXT:    [[L3619:%.*]] = add nuw i8 [[A:%.*]], 1
-; CHECK-NEXT:    [[L3620:%.*]] = zext i8 [[L3619]] to i32
-; CHECK-NEXT:    [[L3621:%.*]] = add nuw i8 [[A]], 2
-; CHECK-NEXT:    [[L3622:%.*]] = zext i8 [[L3621]] to i32
-; CHECK-NEXT:    [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]]
-; CHECK-NEXT:    ret i32 [[L3623]]
+; CHECK-NEXT:    ret i32 1
 ;
   %l3619 = add nuw i8 %a, 1
   %l3620 = zext i8 %l3619 to i32
@@ -39,11 +32,9 @@
 
 define i32 @subaddnsw(i8 %a, i8 %C1, i8 %C2) {
 ; CHECK-LABEL: @subaddnsw(
-; CHECK-NEXT:    [[L3619:%.*]] = add nsw i8 [[A:%.*]], [[C1:%.*]]
-; CHECK-NEXT:    [[L3620:%.*]] = sext i8 [[L3619]] to i32
-; CHECK-NEXT:    [[L3621:%.*]] = add nsw i8 [[A]], [[C2:%.*]]
-; CHECK-NEXT:    [[L3622:%.*]] = sext i8 [[L3621]] to i32
-; CHECK-NEXT:    [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]]
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[C2:%.*]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = sext i8 [[C1:%.*]] to i32
+; CHECK-NEXT:    [[L3623:%.*]] = sub nsw i32 [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    ret i32 [[L3623]]
 ;
   %l3619 = add nsw i8 %a, %C1
@@ -56,12 +47,7 @@
 
 define i32 @subaddnsw_c(i8 %a) {
 ; CHECK-LABEL: @subaddnsw_c(
-; CHECK-NEXT:    [[L3619:%.*]] = add nsw i8 [[A:%.*]], 1
-; CHECK-NEXT:    [[L3620:%.*]] = sext i8 [[L3619]] to i32
-; CHECK-NEXT:    [[L3621:%.*]] = add nsw i8 [[A]], 2
-; CHECK-NEXT:    [[L3622:%.*]] = sext i8 [[L3621]] to i32
-; CHECK-NEXT:    [[L3623:%.*]] = sub nsw i32 [[L3622]], [[L3620]]
-; CHECK-NEXT:    ret i32 [[L3623]]
+; CHECK-NEXT:    ret i32 1
 ;
   %l3619 = add nsw i8 %a, 1
   %l3620 = sext i8 %l3619 to i32
Index: llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2469,6 +2469,20 @@
     }
   }
 
+  // sext(X + Y) - sext(X + Z) -> sext(Y) - sext(Z)
+  if (match(Op0, m_SExt(m_NSWAdd(m_Value(X), m_Value(Y)))) &&
+      match(Op1, m_SExt(m_NSWAdd(m_Specific(X), m_Value(Z))))) {
+    Value *S1 = Builder.CreateSExt(Y, Ty);
+    Value *S2 = Builder.CreateSExt(Z, Ty);
+    return BinaryOperator::CreateSub(S1, S2);
+  }
+  if (match(Op0, m_ZExt(m_NUWAdd(m_Value(X), m_Value(Y)))) &&
+      match(Op1, m_ZExt(m_NUWAdd(m_Specific(X), m_Value(Z))))) {
+    Value *S1 = Builder.CreateZExt(Y, Ty);
+    Value *S2 = Builder.CreateZExt(Z, Ty);
+    return BinaryOperator::CreateSub(S1, S2);
+  }
+
   if (Instruction *Res = foldBinOpOfSelectAndCastOfSelectCondition(I))
     return Res;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157598.548951.patch
Type: text/x-patch
Size: 3545 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230810/e25c4547/attachment.bin>


More information about the llvm-commits mailing list