[llvm] [InstCombine] Fold selection between less than zero and one (PR #69961)

via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 23 12:04:56 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: None (elhewaty)

<details>
<summary>Changes</summary>

- [InstCombine] Add test coverage for selection between less than zero and one(NFC)
- [InstCombine] Fold selection between less than zero and one
 Alive2: https://alive2.llvm.org/ce/z/NFLjSG
 Fixes: https://github.com/llvm/llvm-project/issues/68227


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


2 Files Affected:

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


``````````diff
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 7a15c0dee492b5a..4fd3f4f594d7a77 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3415,6 +3415,20 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
                                 TrueVal);
   }
 
+  // select (icmp eq a, 0), 1, (lshr a, 31) -> icmp sle a, 0,
+  // which is then converted to icmp sle a, 1
+  CmpInst::Predicate Pred;
+  Value *A;
+  const APInt *C;
+  if (match(CondVal, m_Cmp(Pred, m_Value(A), m_Zero())) &&
+      match(TrueVal, m_One()) &&
+      match(FalseVal, m_LShr(m_Specific(A), m_APInt(C))) &&
+      Pred == ICmpInst::ICMP_EQ && *C == 31) {
+    auto *Cond = Builder.CreateICmpSLE(A,
+                                       ConstantInt::getNullValue(A->getType()));
+    return new ZExtInst(Cond, A->getType());
+  }
+
   if (Instruction *R = foldSelectOfBools(SI))
     return R;
 
diff --git a/llvm/test/Transforms/InstCombine/icmp-select.ll b/llvm/test/Transforms/InstCombine/icmp-select.ll
index 0d723c9df32e2f4..7fe37200788dc5e 100644
--- a/llvm/test/Transforms/InstCombine/icmp-select.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-select.ll
@@ -5,6 +5,18 @@ declare void @use(i8)
 declare void @use.i1(i1)
 declare i8 @llvm.umin.i8(i8, i8)
 
+define i32 @test_icmp_select_lte_0(i32 %0) {
+; CHECK-LABEL: @test_icmp_select_lte_0(
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP0:%.*]], 1
+; CHECK-NEXT:    [[RE:%.*]] = zext i1 [[TMP2]] to i32
+; CHECK-NEXT:    ret i32 [[RE]]
+;
+  %cml = icmp eq i32 %0, 0
+  %lshr = lshr i32 %0, 31
+  %re = select i1 %cml, i32 1, i32 %lshr
+  ret i32 %re
+}
+
 define i1 @icmp_select_const(i8 %x, i8 %y) {
 ; CHECK-LABEL: @icmp_select_const(
 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], 0

``````````

</details>


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


More information about the llvm-commits mailing list