[llvm] [InstCombine] Improve select equiv fold for plain condition (PR #83405)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Mar 24 02:13:24 PDT 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/5] [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/5] [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 248a3549e50956a8a43ab7aa7df12334449c98dd 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/5] [InstCombine] Fold its select user into select for true
value
Refactor with a lambda function to address both false and true value.
---
.../InstCombine/InstCombineSelect.cpp | 52 +++++++++++--------
llvm/test/Transforms/InstCombine/select.ll | 5 +-
2 files changed, 33 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 06a350ccb59074..89269dc4248b00 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -509,28 +509,38 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
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;
- }
+ auto TrysimplifySeqSelect = [=, &SI, &IC](unsigned OpIndex) {
+ assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
+ Type *CondType = CondVal->getType();
+ Value *RepOp = OpIndex == 1 ? ConstantInt::getTrue(CondType)
+ : ConstantInt::getFalse(CondType);
+ 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 (Value *S = simplifyWithOpReplaced(ValOp, CondVal, RepOp, SQ,
+ /* AllowRefinement */ true)) {
+ IC.replaceOperand(*SINext, OpIndex, S);
+ return true;
+ }
- SINext = cast<SelectInst>(FalseVal);
- SelType = SINext->getType();
- FalseVal = SINext->getFalseValue();
- }
+ SINext = cast<SelectInst>(ValOp);
+ SelType = SINext->getType();
+ ValOp = SINext->getOperand(OpIndex);
+ }
+ return false;
+ };
+
+ // Try to simplify the true value of select.
+ if (TrysimplifySeqSelect(1))
+ return true;
+
+ // Try to simplify the false value of select.
+ if (TrysimplifySeqSelect(2))
+ return true;
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 abd849e9142593d03d2fc37f423e66d8c7476e4b 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/5] [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 | 5 +----
llvm/test/Transforms/InstCombine/select.ll | 15 +++++++++++++++
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 89269dc4248b00..1b1e4f133b9991 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -515,12 +515,10 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
Value *RepOp = OpIndex == 1 ? ConstantInt::getTrue(CondType)
: ConstantInt::getFalse(CondType);
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)
if (Value *S = simplifyWithOpReplaced(ValOp, CondVal, RepOp, SQ,
/* AllowRefinement */ true)) {
IC.replaceOperand(*SINext, OpIndex, S);
@@ -528,7 +526,6 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
}
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 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){
>From 8168b99aaca69d1a25f08e8d53194075ccccaba2 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Mon, 18 Mar 2024 00:53:22 -0400
Subject: [PATCH 5/5] [InstCombine] Fix comment
---
.../InstCombine/InstCombineSelect.cpp | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 1b1e4f133b9991..aa11565f8877be 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -512,18 +512,15 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
auto TrysimplifySeqSelect = [=, &SI, &IC](unsigned OpIndex) {
assert((OpIndex == 1 || OpIndex == 2) && "Unexpected operand index");
Type *CondType = CondVal->getType();
- Value *RepOp = OpIndex == 1 ? ConstantInt::getTrue(CondType)
- : ConstantInt::getFalse(CondType);
SelectInst *SINext = &SI;
Value *ValOp = SINext->getOperand(OpIndex);
Value *CondNext;
while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
- if (CondNext == CondVal)
- if (Value *S = simplifyWithOpReplaced(ValOp, CondVal, RepOp, SQ,
- /* AllowRefinement */ true)) {
- IC.replaceOperand(*SINext, OpIndex, S);
- return true;
- }
+ if (CondNext == CondVal) {
+ IC.replaceOperand(*SINext, OpIndex,
+ cast<SelectInst>(ValOp)->getOperand(OpIndex));
+ return true;
+ }
SINext = cast<SelectInst>(ValOp);
ValOp = SINext->getOperand(OpIndex);
@@ -532,11 +529,11 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
};
// Try to simplify the true value of select.
- if (TrysimplifySeqSelect(1))
+ if (TrysimplifySeqSelect(/*OpIndex=*/1))
return true;
// Try to simplify the false value of select.
- if (TrysimplifySeqSelect(2))
+ if (TrysimplifySeqSelect(/*OpIndex=*/2))
return true;
return false;
More information about the llvm-commits
mailing list