[PATCH] D140798: [InstCombine] Fold zero check followed by decrement to usub.sat

Jamie Hill-Daniel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 30 22:44:44 PST 2022


clubby789 created this revision.
clubby789 added a reviewer: nikic.
Herald added a subscriber: hiraditya.
Herald added a project: All.
clubby789 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Fold `(a == 0) : 0 ? a - 1` into `usub.sat(a, 1)`


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140798

Files:
  llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
  llvm/test/Transforms/InstCombine/saturating-add-sub.ll


Index: llvm/test/Transforms/InstCombine/saturating-add-sub.ll
===================================================================
--- llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -520,6 +520,18 @@
   ret i8 %x2
 }
 
+; Can simplify zero check followed by decrement
+define i8 @test_simplify_decrement(i8 %a) {
+; CHECK-LABEL: @test_simplify_decrement(
+; CHECK-NEXT:    [[I2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 1)
+; CHECK-NEXT:    ret i8 [[I2]]
+;
+  %i = icmp eq i8 %a, 0
+  %i1 = sub i8 %a, 1
+  %i2 = select i1 %i, i8 0, i8 %i1
+  ret i8 %i2
+}
+
 define <2 x i8> @test_vector_usub_combine(<2 x i8> %a) {
 ; CHECK-LABEL: @test_vector_usub_combine(
 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[A:%.*]], <2 x i8> <i8 30, i8 30>)
Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -853,6 +853,39 @@
   return Result;
 }
 
+/// Transform (a == 0) : 0 : a - 1 into usub.sat(a, 1)
+static Value *canonicalizeSaturatedDecrement(const ICmpInst *ICI,
+                                             const Value *TrueVal,
+                                             const Value *FalseVal,
+                                             InstCombiner::BuilderTy &Builder) {
+  ICmpInst::Predicate Pred = ICI->getPredicate();
+  if (Pred != ICmpInst::ICMP_EQ)
+    return nullptr;
+
+  Value *A = ICI->getOperand(0);
+  Value *B = ICI->getOperand(1);
+
+  if (match(A, m_Zero()))
+    std::swap(A, B);
+
+  if (!match(B, m_Zero()))
+    return nullptr;
+
+  if (match(FalseVal, m_Zero()))
+    std::swap(TrueVal, FalseVal);
+
+  if (!match(TrueVal, m_Zero()))
+    return nullptr;
+
+  Value *One = ConstantInt::get(A->getType(), 1);
+  Value *NegOne = Builder.CreateNeg(One);
+  if (match(FalseVal, m_Sub(m_Specific(A), m_Specific(One))) ||
+      match(FalseVal, m_Add(m_Specific(A), m_Specific(NegOne)))) {
+    return Builder.CreateBinaryIntrinsic(Intrinsic::usub_sat, A, One);
+  }
+  return nullptr;
+}
+
 static Value *canonicalizeSaturatedAdd(ICmpInst *Cmp, Value *TVal, Value *FVal,
                                        InstCombiner::BuilderTy &Builder) {
   if (!Cmp->hasOneUse())
@@ -1741,6 +1774,10 @@
   if (Value *V = canonicalizeSaturatedSubtract(ICI, TrueVal, FalseVal, Builder))
     return replaceInstUsesWith(SI, V);
 
+  if (Value *V =
+          canonicalizeSaturatedDecrement(ICI, TrueVal, FalseVal, Builder))
+    return replaceInstUsesWith(SI, V);
+
   if (Value *V = canonicalizeSaturatedAdd(ICI, TrueVal, FalseVal, Builder))
     return replaceInstUsesWith(SI, V);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140798.485752.patch
Type: text/x-patch
Size: 2803 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221231/a6dce600/attachment.bin>


More information about the llvm-commits mailing list