[llvm] [InstCombine] Improve select equiv fold for plain condition (PR #83405)

via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 27 00:45:29 PDT 2024


https://github.com/vfdff updated https://github.com/llvm/llvm-project/pull/83405

>From 04ddb96d9114786901bb8778181f457443ec013f Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Wed, 28 Feb 2024 23:21:30 -0500
Subject: [PATCH 1/3] [InstCombine] Improve select equiv fold for plain
 condition

Fold select if the user of its select user indicates the condition

Fix https://github.com/llvm/llvm-project/issues/83225
---
 .../InstCombine/InstCombineSelect.cpp         | 37 +++++++++++++++++++
 llvm/test/Transforms/InstCombine/select.ll    |  7 ++--
 2 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 9ab2bd8f70aa15..61399d1f1fec0b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -500,6 +500,40 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
   return C1I.isOne() || C1I.isAllOnes() || C2I.isOne() || C2I.isAllOnes();
 }
 
+/// Try to simplify a select instruction when the user of its select user
+/// indicates the condition.
+static bool simplifySeqSelectWithSameCond(SelectInst &SI,
+                                          const SimplifyQuery &SQ,
+                                          InstCombinerImpl &IC) {
+  Value *CondVal = SI.getCondition();
+  if (match(CondVal, m_ImmConstant()))
+    return false;
+
+  Type *CondType = CondVal->getType();
+  SelectInst *SINext = &SI;
+  Type *SelType = SINext->getType();
+  Value *FalseVal = SINext->getFalseValue();
+  Value *CondNext;
+  Value *FalseNext;
+  while (match(FalseVal,
+               m_Select(m_Value(CondNext), m_Value(), m_Value(FalseNext)))) {
+    // If the type of select is not an integer type or if the condition and
+    // the selection type are not both scalar nor both vector types, there is no
+    // point in attempting to match these patterns.
+    if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
+        CondType->isVectorTy() == SelType->isVectorTy()) {
+      IC.replaceOperand(*SINext, 2, FalseNext);
+      return true;
+    }
+
+    SINext = cast<SelectInst>(FalseVal);
+    SelType = SINext->getType();
+    FalseVal = SINext->getFalseValue();
+  }
+
+  return false;
+}
+
 /// Try to fold the select into one of the operands to allow further
 /// optimization.
 Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
@@ -567,6 +601,9 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
   if (Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal, true))
     return R;
 
+  if (simplifySeqSelectWithSameCond(SI, SQ, *this))
+    return &SI;
+
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 278cabdff9ed3e..4c7bfd3ba85409 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3709,9 +3709,8 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
 
 define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
 ; CHECK-LABEL: @sequence_select_with_same_cond_false(
-; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
-; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
-; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
+; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
+; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]]
 ; CHECK-NEXT:    ret i32 [[S3]]
 ;
   %s1 = select i1 %c1, i32 23, i32 45
@@ -3752,7 +3751,7 @@ define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){
 ; CHECK-LABEL: @sequence_select_with_same_cond_extra_use(
 ; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
 ; CHECK-NEXT:    call void @use32(i32 [[S1]])
-; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
+; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
 ; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
 ; CHECK-NEXT:    ret i32 [[S3]]
 ;

>From d761d6b44651bd6ed031b7eebaa1faf52f1f69fb Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Fri, 8 Mar 2024 20:57:54 -0500
Subject: [PATCH 2/3] [InstCombine] Improve select equiv fold for true
 condition value

Refactor with a lambda function to address both false and true value.
---
 .../InstCombine/InstCombineSelect.cpp         | 46 +++++++++++--------
 llvm/test/Transforms/InstCombine/select.ll    |  5 +-
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 61399d1f1fec0b..704aa2eafa9129 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -509,27 +509,35 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
   if (match(CondVal, m_ImmConstant()))
     return false;
 
-  Type *CondType = CondVal->getType();
-  SelectInst *SINext = &SI;
-  Type *SelType = SINext->getType();
-  Value *FalseVal = SINext->getFalseValue();
-  Value *CondNext;
-  Value *FalseNext;
-  while (match(FalseVal,
-               m_Select(m_Value(CondNext), m_Value(), m_Value(FalseNext)))) {
-    // If the type of select is not an integer type or if the condition and
-    // the selection type are not both scalar nor both vector types, there is no
-    // point in attempting to match these patterns.
-    if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
-        CondType->isVectorTy() == SelType->isVectorTy()) {
-      IC.replaceOperand(*SINext, 2, FalseNext);
-      return true;
+  auto TrysimplifySeqSelect = [=, &SI, &IC](unsigned OpIndex) {
+    assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
+    Type *CondType = CondVal->getType();
+    SelectInst *SINext = &SI;
+    Type *SelType = SINext->getType();
+    Value *ValOp = SINext->getOperand(OpIndex);
+    Value *CondNext;
+    while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
+      if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
+          CondType->isVectorTy() == SelType->isVectorTy()) {
+        IC.replaceOperand(*SINext, OpIndex,
+                          cast<SelectInst>(ValOp)->getOperand(OpIndex));
+        return true;
+      }
+
+      SINext = cast<SelectInst>(ValOp);
+      SelType = SINext->getType();
+      ValOp = SINext->getOperand(OpIndex);
     }
+    return false;
+  };
 
-    SINext = cast<SelectInst>(FalseVal);
-    SelType = SINext->getType();
-    FalseVal = SINext->getFalseValue();
-  }
+  // Try to simplify the true value of select.
+  if (TrysimplifySeqSelect(/*OpIndex=*/1))
+    return true;
+
+  // Try to simplify the false value of select.
+  if (TrysimplifySeqSelect(/*OpIndex=*/2))
+    return true;
 
   return false;
 }
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 4c7bfd3ba85409..5c03e03e140ff3 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3721,9 +3721,8 @@ define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
 
 define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
 ; CHECK-LABEL: @sequence_select_with_same_cond_true(
-; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1:%.*]], i32 45, i32 23
-; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 [[S1]], i32 666
-; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], i32 [[S2]], i32 789
+; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], i32 45, i32 666
+; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1:%.*]], i32 [[S2]], i32 789
 ; CHECK-NEXT:    ret i32 [[S3]]
 ;
   %s1 = select i1 %c1, i32 45, i32 23

>From 711fcc12547ba9d5ab63e24db804d1071b7b665c Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Fri, 8 Mar 2024 22:19:36 -0500
Subject: [PATCH 3/3] [InstCombine] Improve select equiv fold for float type

The pattern matcher checks the operand of the select is also a select
instruction, so the condition and the selection type must be both scalar
nor both vector types.
---
 llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 5 +----
 llvm/test/Transforms/InstCombine/select.ll            | 5 ++---
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 704aa2eafa9129..b9d35a4e17b7e0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -513,19 +513,16 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
     assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
     Type *CondType = CondVal->getType();
     SelectInst *SINext = &SI;
-    Type *SelType = SINext->getType();
     Value *ValOp = SINext->getOperand(OpIndex);
     Value *CondNext;
     while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
-      if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
-          CondType->isVectorTy() == SelType->isVectorTy()) {
+      if (CondNext == CondVal) {
         IC.replaceOperand(*SINext, OpIndex,
                           cast<SelectInst>(ValOp)->getOperand(OpIndex));
         return true;
       }
 
       SINext = cast<SelectInst>(ValOp);
-      SelType = SINext->getType();
       ValOp = SINext->getOperand(OpIndex);
     }
     return false;
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 5c03e03e140ff3..7b06cf34f8415a 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3733,9 +3733,8 @@ define i32 @sequence_select_with_same_cond_true(i1 %c1, i1 %c2){
 
 define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2, double %r1, double %r2){
 ; CHECK-LABEL: @sequence_select_with_same_cond_double(
-; CHECK-NEXT:    [[S1:%.*]] = select i1 [[C1:%.*]], double 1.000000e+00, double 0.000000e+00
-; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], double [[S1]], double 2.000000e+00
-; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1]], double [[S2]], double 3.000000e+00
+; CHECK-NEXT:    [[S2:%.*]] = select i1 [[C2:%.*]], double 1.000000e+00, double 2.000000e+00
+; CHECK-NEXT:    [[S3:%.*]] = select i1 [[C1:%.*]], double [[S2]], double 3.000000e+00
 ; CHECK-NEXT:    ret double [[S3]]
 ;
   %s1 = select i1 %c1, double 1.0, double 0.0



More information about the llvm-commits mailing list