[llvm] [InstCombine] Fold its select user into select (PR #83405)

via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 8 20:49:46 PST 2024


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

>From acf0d16fa7849bfbe0833567750a862dde626d22 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Fri, 8 Mar 2024 21:05:20 -0500
Subject: [PATCH 1/4] [InstCombine] Precommit tests for PR83225

---
 llvm/test/Transforms/InstCombine/select.ll | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index a84904106eced4..afdd30ca6f23cd 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3708,3 +3708,47 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
   %cond = select i1 %xor0, i32 %xor, i32 %y
   ret i32 %cond
 }
+
+define i32 @sequence_select_with_same_cond_flase (i1 %c1, i1 %c2){
+; CHECK-LABEL: @sequence_select_with_same_cond_flase(
+; 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:    ret i32 [[S3]]
+;
+  %s1 = select i1 %c1, i32 23, i32 45
+  %s2 = select i1 %c2, i32 666, i32 %s1
+  %s3 = select i1 %c1, i32 789, i32 %s2
+  ret i32 %s3
+}
+
+; https://alive2.llvm.org/ce/z/HHF-VD
+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:    ret i32 [[S3]]
+;
+  %s1 = select i1 %c1, i32 45, i32 23
+  %s2 = select i1 %c2, i32 %s1, i32 666
+  %s3 = select i1 %c1, i32 %s2, i32 789
+  ret i32 %s3
+}
+
+declare void @use32(i32)
+
+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:    [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
+; CHECK-NEXT:    ret i32 [[S3]]
+;
+  %s1 = select i1 %c1, i32 23, i32 45
+  call void @use32(i32 %s1)
+  %s2 = select i1 %c2, i32 666, i32 %s1
+  %s3 = select i1 %c1, i32 789, i32 %s2
+  ret i32 %s3
+}

>From c67620baa8527a27e45839230f1b40a6902703c8 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 2/4] [InstCombine] Fold its select user into select

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

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

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index aee18d770f729d..06a350ccb59074 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -500,6 +500,41 @@ 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 (isa<Constant>(CondVal))
+    return false;
+
+  Type *CondType = CondVal->getType();
+  SelectInst *SINext = &SI;
+  Type *SelType = SINext->getType();
+  Value *FalseVal = SINext->getFalseValue();
+  Value *CondNext;
+  while (match(FalseVal, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
+    // 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())
+      if (Value *S = simplifyWithOpReplaced(FalseVal, CondVal,
+                                            ConstantInt::getFalse(CondType), SQ,
+                                            /* AllowRefinement */ true)) {
+        IC.replaceOperand(*SINext, 2, S);
+        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,
@@ -557,6 +592,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 afdd30ca6f23cd..7c838442529ef5 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3711,9 +3711,8 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
 
 define i32 @sequence_select_with_same_cond_flase (i1 %c1, i1 %c2){
 ; CHECK-LABEL: @sequence_select_with_same_cond_flase(
-; 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
@@ -3742,7 +3741,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 e7e7885f93707454446c3939731d96a7e33f9a07 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 3/4] [InstCombine] Fold its select user into select for true
 value

---
 .../InstCombine/InstCombineSelect.cpp         | 21 +++++++++++++++++++
 llvm/test/Transforms/InstCombine/select.ll    |  5 ++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 06a350ccb59074..77ad833653c1fa 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -532,6 +532,27 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
     FalseVal = SINext->getFalseValue();
   }
 
+  // Resuming from SI
+  SINext = &SI;
+  Value *TrueVal = SINext->getTrueValue();
+  while (match(TrueVal, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
+    // 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())
+      if (Value *S = simplifyWithOpReplaced(TrueVal, CondVal,
+                                            ConstantInt::getTrue(CondType), SQ,
+                                            /* AllowRefinement */ true)) {
+        IC.replaceOperand(*SINext, 1, S);
+        return true;
+      }
+
+    SINext = cast<SelectInst>(TrueVal);
+    SelType = SINext->getType();
+    TrueVal = SINext->getTrueValue();
+  }
+
   return false;
 }
 
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 7c838442529ef5..4a461b38cfd99c 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3724,9 +3724,8 @@ define i32 @sequence_select_with_same_cond_flase (i1 %c1, i1 %c2){
 ; https://alive2.llvm.org/ce/z/HHF-VD
 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 03d2c818af2b8937ea2598cb9d3387d259f2de25 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 4/4] [InstCombine] Fold its select user into select 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.
---
 .../Transforms/InstCombine/InstCombineSelect.cpp  | 15 ++-------------
 llvm/test/Transforms/InstCombine/select.ll        | 15 +++++++++++++++
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 77ad833653c1fa..afc2c22a706036 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -511,15 +511,10 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
 
   Type *CondType = CondVal->getType();
   SelectInst *SINext = &SI;
-  Type *SelType = SINext->getType();
   Value *FalseVal = SINext->getFalseValue();
   Value *CondNext;
   while (match(FalseVal, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
-    // 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())
+    if (CondNext == CondVal)
       if (Value *S = simplifyWithOpReplaced(FalseVal, CondVal,
                                             ConstantInt::getFalse(CondType), SQ,
                                             /* AllowRefinement */ true)) {
@@ -528,7 +523,6 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
       }
 
     SINext = cast<SelectInst>(FalseVal);
-    SelType = SINext->getType();
     FalseVal = SINext->getFalseValue();
   }
 
@@ -536,11 +530,7 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
   SINext = &SI;
   Value *TrueVal = SINext->getTrueValue();
   while (match(TrueVal, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
-    // 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())
+    if (CondNext == CondVal)
       if (Value *S = simplifyWithOpReplaced(TrueVal, CondVal,
                                             ConstantInt::getTrue(CondType), SQ,
                                             /* AllowRefinement */ true)) {
@@ -549,7 +539,6 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
       }
 
     SINext = cast<SelectInst>(TrueVal);
-    SelType = SINext->getType();
     TrueVal = SINext->getTrueValue();
   }
 
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 4a461b38cfd99c..b36440f54c5f96 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3734,6 +3734,21 @@ define i32 @sequence_select_with_same_cond_true (i1 %c1, i1 %c2){
   ret i32 %s3
 }
 
+; https://alive2.llvm.org/ce/z/3Uaiis
+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:  entry:
+; 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]]
+;
+entry:
+  %s1 = select i1 %c1, double 1.0, double 0.0
+  %s2 = select i1 %c2, double %s1, double 2.0
+  %s3 = select i1 %c1, double %s2, double 3.0
+  ret double %s3
+}
+
 declare void @use32(i32)
 
 define i32 @sequence_select_with_same_cond_extra_use (i1 %c1, i1 %c2){



More information about the llvm-commits mailing list