Skip to content

Commit

Permalink
[InstCombine] Add fold for select of symmetric selects
Browse files Browse the repository at this point in the history
  • Loading branch information
tgymnich committed Jul 14, 2024
1 parent c8dc21d commit 12b5833
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3012,6 +3012,36 @@ struct DecomposedSelect {
};
} // namespace

/// Folds patterns like:
/// select c2 (select c1 a b) (select c1 b a)
/// into:
/// select (xor c1 c2) b a
static Instruction *
foldSelectOfSymmetricSelect(SelectInst &OuterSelVal,
InstCombiner::BuilderTy &Builder) {

DecomposedSelect OuterSel, InnerSel1, InnerSel2;

if (!match(
&OuterSelVal,
m_Select(m_Value(OuterSel.Cond),
m_Select(m_Value(InnerSel1.Cond), m_Value(InnerSel1.TrueVal),
m_Value(InnerSel1.FalseVal)),
m_Select(m_Value(InnerSel2.Cond), m_Value(InnerSel2.TrueVal),
m_Value(InnerSel2.FalseVal)))))
return nullptr;

bool InnerSelsSymmetric = InnerSel1.Cond == InnerSel2.Cond &&
InnerSel1.TrueVal == InnerSel2.FalseVal &&
InnerSel1.FalseVal == InnerSel2.TrueVal;

if (!InnerSelsSymmetric)
return nullptr;

Value *Xor = Builder.CreateXor(InnerSel1.Cond, OuterSel.Cond);
return SelectInst::Create(Xor, InnerSel1.FalseVal, InnerSel1.TrueVal);
}

/// Look for patterns like
/// %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false
/// %inner.sel = select i1 %inner.cond, i8 %inner.sel.t, i8 %inner.sel.f
Expand Down Expand Up @@ -3987,6 +4017,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
}
}

if (Instruction *I = foldSelectOfSymmetricSelect(SI, Builder))
return I;

if (Instruction *I = foldNestedSelects(SI, Builder))
return I;

Expand Down

0 comments on commit 12b5833

Please sign in to comment.