[llvm] [InstCombine] Fold icmp in select to smin (PR #87157)

Krishna Narayanan via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 30 07:57:21 PDT 2024


https://github.com/Krishna-13-cyber updated https://github.com/llvm/llvm-project/pull/87157

>From 394befb5213028ce41aecf94e7e9725e7c22a7a5 Mon Sep 17 00:00:00 2001
From: Krishna-13-cyber <krishnanarayanan132002 at gmail.com>
Date: Sat, 30 Mar 2024 20:21:29 +0530
Subject: [PATCH 1/2] Fold icmp in select to smin

---
 .../InstCombine/InstCombineSelect.cpp         | 22 +++++++++++++++++++
 .../Transforms/InstCombine/icmp-select.ll     | 13 +++++++++++
 2 files changed, 35 insertions(+)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 9ab2bd8f70aa15..4e58ba5f01df1c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1687,6 +1687,25 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI,
   return nullptr;
 }
 
+static Value *foldSelectInstWithICmpOr(SelectInst &SI, ICmpInst *ICI,
+                                       InstCombiner::BuilderTy &Builder) {
+  /* a > -1 ? 1 : (a | 3) --> smin(1, a | 3) */
+  Type *Ty = SI.getType();
+  Value *TVal = SI.getTrueValue();
+  Value *FVal = SI.getFalseValue();
+  Constant *One = ConstantInt::get(Ty, 1);
+  CmpInst::Predicate Pred = ICI->getPredicate();
+  Value *A = ICI->getOperand(0);
+  const APInt *Cmp;
+
+  if (!match(TVal, m_One()) || !match(FVal, m_Or(m_Value(A), m_SpecificInt(3))))
+    return nullptr;
+
+  if (Pred == ICmpInst::ICMP_SGT && *Cmp == -1 && match(TVal, m_One()) &&
+      match(FVal, m_Or(m_Value(A), m_SpecificInt(3))))
+    return Builder.CreateBinaryIntrinsic(Intrinsic::smin, One, FVal);
+}
+
 /// Visit a SelectInst that has an ICmpInst as its first operand.
 Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
                                                       ICmpInst *ICI) {
@@ -1700,6 +1719,9 @@ Instruction *InstCombinerImpl::foldSelectInstWithICmp(SelectInst &SI,
   if (Value *V = foldSelectInstWithICmpConst(SI, ICI, Builder))
     return replaceInstUsesWith(SI, V);
 
+  if (Value *V = foldSelectInstWithICmpOr(SI, ICI, Builder))
+    return replaceInstUsesWith(SI, V);
+
   if (Value *V = canonicalizeClampLike(SI, *ICI, Builder))
     return replaceInstUsesWith(SI, V);
 
diff --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index 59d2a1b165c0f8..80341278b58f3a 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -628,3 +628,16 @@ define i1 @icmp_slt_select(i1 %cond, i32 %a, i32 %b) {
   %res = icmp slt i32 %lhs, %rhs
   ret i1 %res
 }
+
+define i8 @icmp_slt_select_or(i8 %inl) {
+; CHECK-LABEL: @icmp_slt_select_or(
+; CHECK-NEXT:    [[OR:%.*]] = or i8 [[INL:%.*]], 3
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[INL]], -1
+; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i8 1, i8 [[OR]]
+; CHECK-NEXT:    ret i8 [[S]]
+;
+  %or = or i8 %inl, 3
+  %cmp = icmp sgt i8 %inl, -1
+  %s = select i1 %cmp, i8 1, i8 %or
+  ret i8 %s
+}

>From bf96ccc14d711c5083dac748005d6ca846d01662 Mon Sep 17 00:00:00 2001
From: Krishna-13-cyber <krishnanarayanan132002 at gmail.com>
Date: Sat, 30 Mar 2024 20:26:46 +0530
Subject: [PATCH 2/2] Update test diffs

---
 llvm/test/Transforms/InstCombine/icmp-select.ll | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index 80341278b58f3a..3c1a7adcc463f1 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -632,8 +632,7 @@ define i1 @icmp_slt_select(i1 %cond, i32 %a, i32 %b) {
 define i8 @icmp_slt_select_or(i8 %inl) {
 ; CHECK-LABEL: @icmp_slt_select_or(
 ; CHECK-NEXT:    [[OR:%.*]] = or i8 [[INL:%.*]], 3
-; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[INL]], -1
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[CMP]], i8 1, i8 [[OR]]
+; CHECK-NEXT:    [[S:%.*]] = call i8 @llvm.smin.i8(i8 [[OR]], i8 1)
 ; CHECK-NEXT:    ret i8 [[S]]
 ;
   %or = or i8 %inl, 3



More information about the llvm-commits mailing list