Skip to content

Commit a4e61fa

Browse files
committed
[InstCombine] Improve select equiv fold for plain condition
Fold select if the user of its select user indicates the condition Fix #83225
1 parent c89def8 commit a4e61fa

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,41 @@ static bool isSelect01(const APInt &C1I, const APInt &C2I) {
500500
return C1I.isOne() || C1I.isAllOnes() || C2I.isOne() || C2I.isAllOnes();
501501
}
502502

503+
/// Try to simplify seletion chain with partially identical conditions, eg:
504+
/// %s1 = select i1 %c1, i32 23, i32 45
505+
/// %s2 = select i1 %c2, i32 666, i32 %s1
506+
/// %s3 = select i1 %c1, i32 789, i32 %s2
507+
/// -->
508+
/// %s2 = select i1 %c2, i32 666, i32 45
509+
/// %s3 = select i1 %c1, i32 789, i32 %s2
510+
static bool simplifySeqSelectWithSameCond(SelectInst &SI,
511+
const SimplifyQuery &SQ,
512+
InstCombinerImpl &IC) {
513+
Value *CondVal = SI.getCondition();
514+
Type *CondType = CondVal->getType();
515+
SelectInst *SINext = &SI;
516+
Type *SelType = SINext->getType();
517+
Value *FalseVal = SINext->getFalseValue();
518+
Value *CondNext;
519+
Value *FalseNext;
520+
while (match(FalseVal,
521+
m_Select(m_Value(CondNext), m_Value(), m_Value(FalseNext)))) {
522+
// Only support the type of select is an integer type as float type need
523+
// address FMF flag.
524+
if (CondNext == CondVal && SelType->isIntOrIntVectorTy() &&
525+
SINext->hasOneUse()) {
526+
IC.replaceOperand(*SINext, 2, FalseNext);
527+
return true;
528+
}
529+
530+
SINext = cast<SelectInst>(FalseVal);
531+
SelType = SINext->getType();
532+
FalseVal = SINext->getFalseValue();
533+
}
534+
535+
return false;
536+
}
537+
503538
/// Try to fold the select into one of the operands to allow further
504539
/// optimization.
505540
Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
@@ -567,6 +602,9 @@ Instruction *InstCombinerImpl::foldSelectIntoOp(SelectInst &SI, Value *TrueVal,
567602
if (Instruction *R = TryFoldSelectIntoOp(SI, FalseVal, TrueVal, true))
568603
return R;
569604

605+
if (simplifySeqSelectWithSameCond(SI, SQ, *this))
606+
return &SI;
607+
570608
return nullptr;
571609
}
572610

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4527,9 +4527,8 @@ define i32 @src_select_xxory_eq0_xorxy_y(i32 %x, i32 %y) {
45274527

45284528
define i32 @sequence_select_with_same_cond_false(i1 %c1, i1 %c2){
45294529
; CHECK-LABEL: @sequence_select_with_same_cond_false(
4530-
; CHECK-NEXT: [[S1:%.*]] = select i1 [[C1:%.*]], i32 23, i32 45
4531-
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 [[S1]]
4532-
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1]], i32 789, i32 [[S2]]
4530+
; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], i32 666, i32 45
4531+
; CHECK-NEXT: [[S3:%.*]] = select i1 [[C1:%.*]], i32 789, i32 [[S2]]
45334532
; CHECK-NEXT: ret i32 [[S3]]
45344533
;
45354534
%s1 = select i1 %c1, i32 23, i32 45

0 commit comments

Comments
 (0)