[llvm] [InstCombine] Improve select equiv fold for plain condition (PR #83405)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 8 04:35:40 PDT 2024
https://github.com/vfdff updated https://github.com/llvm/llvm-project/pull/83405
>From ef959d80b1dd0c291faf181d43e5b68b0555f48e 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/5] [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 9c56ff49dd9d764b5e2b8571cf11067c7a17d190 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/5] [InstCombine] Improve select equiv fold for true
condition value
Refactor with a lambda function to address both false and true value.
---
.../InstCombine/InstCombineSelect.cpp | 45 +++++++++++--------
llvm/test/Transforms/InstCombine/select.ll | 5 +--
2 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 61399d1f1fec0b..236f5570ebddf8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -509,27 +509,34 @@ 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");
+ 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 cd31b2b9953f1f5e74bf42c186e782136e17fc51 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/5] [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 236f5570ebddf8..cf3f40c5327d3f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -512,19 +512,16 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
auto trySimplifySeqSelect = [=, &SI, &IC](unsigned OpIndex) {
assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
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
>From 02acd163e0bb47719e194651f57f176ea533106c Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Sun, 7 Apr 2024 10:19:21 -0400
Subject: [PATCH 4/5] [InstCombine] Fix the cases when the inner select is used
by multi arms
---
.../InstCombine/InstCombineSelect.cpp | 33 ++++++++++++++++---
llvm/test/Transforms/InstCombine/select.ll | 15 +++++++++
2 files changed, 43 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index cf3f40c5327d3f..551a6c2eef535a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -504,24 +504,47 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
/// indicates the condition.
static bool simplifySeqSelectWithSameCond(SelectInst &SI,
const SimplifyQuery &SQ,
+ InstCombiner::BuilderTy &Builder,
InstCombinerImpl &IC) {
Value *CondVal = SI.getCondition();
if (match(CondVal, m_ImmConstant()))
return false;
- auto trySimplifySeqSelect = [=, &SI, &IC](unsigned OpIndex) {
+ auto trySimplifySeqSelect = [=, &SI, &IC, &Builder](unsigned OpIndex) {
assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
SelectInst *SINext = &SI;
Value *ValOp = SINext->getOperand(OpIndex);
Value *CondNext;
+ // Record the use chain
+ SmallVector<SelectInst *, 8> SIChain;
while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
+ SelectInst *ValSI = cast<SelectInst>(ValOp);
if (CondNext == CondVal) {
- IC.replaceOperand(*SINext, OpIndex,
- cast<SelectInst>(ValOp)->getOperand(OpIndex));
+ SelectInst *SIPre = &SI;
+ if (SIChain.empty()) {
+ IC.replaceOperand(SI, OpIndex, ValSI->getOperand(OpIndex));
+ } else {
+ // Create a new select to get around the case which SINext used in
+ // multi arms, and insert the new Select just before SINext.
+ Value *NewSI;
+ IC.Builder.SetInsertPoint(SINext);
+ if (OpIndex == 1)
+ NewSI = Builder.CreateSelect(
+ SINext->getCondition(), ValSI->getOperand(1),
+ SINext->getOperand(2), SINext->getName() + ".new", SINext);
+ else
+ NewSI = Builder.CreateSelect(
+ SINext->getCondition(), SINext->getOperand(1),
+ ValSI->getOperand(2), SINext->getName() + ".new", SINext);
+ SIPre = SIChain.back();
+ IC.replaceOperand(*SIPre, OpIndex, NewSI);
+ }
+
return true;
}
- SINext = cast<SelectInst>(ValOp);
+ SIChain.push_back(SINext);
+ SINext = ValSI;
ValOp = SINext->getOperand(OpIndex);
}
return false;
@@ -605,7 +628,7 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
if (Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal, true))
return R;
- if (simplifySeqSelectWithSameCond(SI, SQ, *this))
+ if (simplifySeqSelectWithSameCond(SI, SQ, Builder, *this))
return &SI;
return nullptr;
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 7b06cf34f8415a..d943bb64840f18 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -3759,3 +3759,18 @@ define i32 @sequence_select_with_same_cond_extra_use(i1 %c1, i1 %c2){
%s3 = select i1 %c1, i32 789, i32 %s2
ret i32 %s3
}
+
+define i8 @sequence_select_with_same_cond_multi_arms(i1 %cond0, i1 %cond1, i8 %a, i8 %b) {
+; CHECK-LABEL: @sequence_select_with_same_cond_multi_arms(
+; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[TMP1:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
+; CHECK-NEXT: [[SEL1_NEW:%.*]] = select i1 [[COND1:%.*]], i8 [[A]], i8 2
+; CHECK-NEXT: [[SEL4:%.*]] = select i1 [[COND1]], i8 [[SEL2]], i8 3
+; CHECK-NEXT: [[SEL3:%.*]] = select i1 [[TMP1]], i8 [[SEL1_NEW]], i8 [[SEL4]]
+; CHECK-NEXT: ret i8 [[SEL3]]
+;
+ %sel0 = select i1 %cond0, i8 %a, i8 %b
+ %sel1 = select i1 %cond1, i8 %sel0, i8 2; %sel1 used in multi arms
+ %sel2 = select i1 %cond1, i8 %sel1, i8 3
+ %sel3 = select i1 %cond0, i8 %sel1, i8 %sel2
+ ret i8 %sel3
+}
>From 6247957ba437117dcd2b311f19157fc7e32a8f35 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Mon, 8 Apr 2024 02:03:56 -0400
Subject: [PATCH 5/5] [InstCombine] Remove unnecessary restrictions
---
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 551a6c2eef535a..0473d6694f9678 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -507,8 +507,6 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
InstCombiner::BuilderTy &Builder,
InstCombinerImpl &IC) {
Value *CondVal = SI.getCondition();
- if (match(CondVal, m_ImmConstant()))
- return false;
auto trySimplifySeqSelect = [=, &SI, &IC, &Builder](unsigned OpIndex) {
assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
More information about the llvm-commits
mailing list