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

via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 30 07:56:22 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Krishna Narayanan (Krishna-13-cyber)

<details>
<summary>Changes</summary>

Intends to solve  #<!-- -->85844

---
Full diff: https://github.com/llvm/llvm-project/pull/87157.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp (+22) 
- (modified) llvm/test/Transforms/InstCombine/icmp-select.ll (+13) 


``````````diff
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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/87157


More information about the llvm-commits mailing list