[llvm] [InstCombine] Improve select equiv fold for plain condition (PR #83405)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 13 02:46:25 PDT 2024
https://github.com/vfdff updated https://github.com/llvm/llvm-project/pull/83405
>From c89def841011bedc9d87f306e4ac7634204f9178 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Sun, 12 May 2024 21:48:07 -0400
Subject: [PATCH 1/4] [InstCombine] Add test for #83225 (NFC)
---
llvm/test/Transforms/InstCombine/select.ll | 46 +++++++++++++++++++++-
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 2ade6faa99be3..cb66a9fa8d0bf 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4564,19 +4564,46 @@ define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2,
ret double %s3
}
+; Confirm the FMF flag is propagated
+define float @sequence_select_with_same_cond_float_and_fmf_flag1(i1 %c1, i1 %c2){
+; CHECK-LABEL: @sequence_select_with_same_cond_float_and_fmf_flag1(
+; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], float 2.300000e+01, float 4.500000e+01
+; CHECK-NEXT: [[S2:%.*]] = select fast i1 [[C2:%.*]], float 6.660000e+02, float [[S1]]
+; CHECK-NEXT: [[S3:%.*]] = select fast i1 [[C1]], float 7.890000e+02, float [[S2]]
+; CHECK-NEXT: ret float [[S3]]
+;
+ %s1 = select i1 %c1, float 23.0, float 45.0
+ %s2 = select fast i1 %c2, float 666.0, float %s1 ; has fast flag
+ %s3 = select fast i1 %c1, float 789.0, float %s2
+ ret float %s3
+}
+
+define float @sequence_select_with_same_cond_float_and_fmf_flag2(i1 %c1, i1 %c2){
+; CHECK-LABEL: @sequence_select_with_same_cond_float_and_fmf_flag2(
+; CHECK-NEXT: [[S1:%.*]] = select fast i1 [[C1:%.*]], float 2.300000e+01, float 4.500000e+01
+; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], float 6.660000e+02, float [[S1]]
+; CHECK-NEXT: [[S3:%.*]] = select fast i1 [[C1]], float 7.890000e+02, float [[S2]]
+; CHECK-NEXT: ret float [[S3]]
+;
+ %s1 = select fast i1 %c1, float 23.0, float 45.0
+ %s2 = select i1 %c2, float 666.0, float %s1 ; has no fast flag
+ %s3 = select fast i1 %c1, float 789.0, float %s2
+ ret float %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: call void @use32(i32 [[S2]])
; 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
+ call void @use32(i32 %s2)
%s3 = select i1 %c1, i32 789, i32 %s2
ret i32 %s3
}
@@ -4612,3 +4639,18 @@ define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
%sel = select i1 %x, i8 0, i8 %shl.fr
ret i8 %sel
}
+
+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: [[SEL0:%.*]] = select i1 [[COND0:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND1:%.*]], i8 [[SEL0]], i8 2
+; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND1]], i8 [[SEL0]], i8 3
+; CHECK-NEXT: [[SEL3:%.*]] = select i1 [[COND0]], i8 [[SEL1]], i8 [[SEL2]]
+; 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 a4e61fac417e0d15cf2ebe09877b60f5ca5ff9d3 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] 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 | 38 +++++++++++++++++++
llvm/test/Transforms/InstCombine/select.ll | 5 +--
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index a3ddb402bf662..cf4e654908d55 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 seletion chain with partially identical conditions, eg:
+/// %s1 = select i1 %c1, i32 23, i32 45
+/// %s2 = select i1 %c2, i32 666, i32 %s1
+/// %s3 = select i1 %c1, i32 789, i32 %s2
+/// -->
+/// %s2 = select i1 %c2, i32 666, i32 45
+/// %s3 = select i1 %c1, i32 789, i32 %s2
+static bool simplifySeqSelectWithSameCond(SelectInst &SI,
+ const SimplifyQuery &SQ,
+ InstCombinerImpl &IC) {
+ Value *CondVal = SI.getCondition();
+ 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)))) {
+ // Only support the type of select is an integer type as float type need
+ // address FMF flag.
+ if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
+ SINext->hasOneUse()) {
+ 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 +602,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 cb66a9fa8d0bf..e7f3fa0fdc6c3 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4527,9 +4527,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
>From da2d545ad970779244ecb605fff8f0f6da0dcab5 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] Improve select equiv fold for true
condition value
Refactor with a lambda function to address both false and true value.
---
.../InstCombine/InstCombineSelect.cpp | 42 ++++++++++++-------
llvm/test/Transforms/InstCombine/select.ll | 9 ++--
2 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index cf4e654908d55..e33c9256f0a0e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -511,26 +511,36 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
const SimplifyQuery &SQ,
InstCombinerImpl &IC) {
Value *CondVal = SI.getCondition();
- 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)))) {
+ 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;
// Only support the type of select is an integer type as float type need
// address FMF flag.
- if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
- SINext->hasOneUse()) {
- IC.replaceOperand(*SINext, 2, FalseNext);
- return true;
+ while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
+ if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
+ SINext->hasOneUse()) {
+ 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 e7f3fa0fdc6c3..1572b5539eaf6 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4539,9 +4539,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
@@ -4639,10 +4638,12 @@ define i8 @test_replace_freeze_oneuse(i1 %x, i8 %y) {
ret i8 %sel
}
+; first, %sel2 change into select i1 %cond1, i8 %sel0, i8 3, the the %sel1 is OneUse
+; second, %sel1 change into select i1 %cond1, i8 %a, i8 2
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: [[SEL0:%.*]] = select i1 [[COND0:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]
-; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND1:%.*]], i8 [[SEL0]], i8 2
+; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[COND1:%.*]], i8 [[A]], i8 2
; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[COND1]], i8 [[SEL0]], i8 3
; CHECK-NEXT: [[SEL3:%.*]] = select i1 [[COND0]], i8 [[SEL1]], i8 [[SEL2]]
; CHECK-NEXT: ret i8 [[SEL3]]
>From 2187df8114a5333bec6a5f4d24d0b52eef81fed3 Mon Sep 17 00:00:00 2001
From: zhongyunde 00443407 <zhongyunde at huawei.com>
Date: Mon, 13 May 2024 04:10:37 -0400
Subject: [PATCH 4/4] [InstCombine] Improve select equiv fold for float type
---
.../Transforms/InstCombine/InstCombineSelect.cpp | 8 ++++----
llvm/test/Transforms/InstCombine/select.ll | 15 ++++++---------
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index e33c9256f0a0e..bb3c03a843542 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -517,11 +517,11 @@ static bool simplifySeqSelectWithSameCond(SelectInst &SI,
Type *SelType = SINext->getType();
Value *ValOp = SINext->getOperand(OpIndex);
Value *CondNext;
- // Only support the type of select is an integer type as float type need
- // address FMF flag.
+ // Don't need propagate FMF flag because we update the operand of SINext
+ // directly.
+ // It is not profitable to build a new select for SINext with multi-arms.
while (match(ValOp, m_Select(m_Value(CondNext), m_Value(), m_Value()))) {
- if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
- SINext->hasOneUse()) {
+ if (CondNext == CondVal && SINext->hasOneUse()) {
IC.replaceOperand(*SINext, OpIndex,
cast<SelectInst>(ValOp)->getOperand(OpIndex));
return true;
diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 1572b5539eaf6..9f84d50a04950 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -4551,9 +4551,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
@@ -4565,9 +4564,8 @@ define double @sequence_select_with_same_cond_double(double %a, i1 %c1, i1 %c2,
; Confirm the FMF flag is propagated
define float @sequence_select_with_same_cond_float_and_fmf_flag1(i1 %c1, i1 %c2){
; CHECK-LABEL: @sequence_select_with_same_cond_float_and_fmf_flag1(
-; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], float 2.300000e+01, float 4.500000e+01
-; CHECK-NEXT: [[S2:%.*]] = select fast i1 [[C2:%.*]], float 6.660000e+02, float [[S1]]
-; CHECK-NEXT: [[S3:%.*]] = select fast i1 [[C1]], float 7.890000e+02, float [[S2]]
+; CHECK-NEXT: [[S2:%.*]] = select fast i1 [[C2:%.*]], float 6.660000e+02, float 4.500000e+01
+; CHECK-NEXT: [[S3:%.*]] = select fast i1 [[C1:%.*]], float 7.890000e+02, float [[S2]]
; CHECK-NEXT: ret float [[S3]]
;
%s1 = select i1 %c1, float 23.0, float 45.0
@@ -4578,9 +4576,8 @@ define float @sequence_select_with_same_cond_float_and_fmf_flag1(i1 %c1, i1 %c2)
define float @sequence_select_with_same_cond_float_and_fmf_flag2(i1 %c1, i1 %c2){
; CHECK-LABEL: @sequence_select_with_same_cond_float_and_fmf_flag2(
-; CHECK-NEXT: [[S1:%.*]] = select fast i1 [[C1:%.*]], float 2.300000e+01, float 4.500000e+01
-; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], float 6.660000e+02, float [[S1]]
-; CHECK-NEXT: [[S3:%.*]] = select fast i1 [[C1]], float 7.890000e+02, float [[S2]]
+; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], float 6.660000e+02, float 4.500000e+01
+; CHECK-NEXT: [[S3:%.*]] = select fast i1 [[C1:%.*]], float 7.890000e+02, float [[S2]]
; CHECK-NEXT: ret float [[S3]]
;
%s1 = select fast i1 %c1, float 23.0, float 45.0
More information about the llvm-commits
mailing list