From 9ddff66d0c9c3e18d56e6b20aa26a2a8cdfb6d2b Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Sun, 11 Dec 2022 00:51:03 +0300 Subject: [PATCH] [InstCombine] Fold nested selects https://alive2.llvm.org/ce/z/GjCXkB https://alive2.llvm.org/ce/z/Guz2tt Fixes https://github.com/llvm/llvm-project/issues/59393 --- .../Transforms/InstCombine/InstCombineSelect.cpp | 77 +++++++++++++ llvm/test/Transforms/InstCombine/nested-select.ll | 126 +++++++++------------ .../Transforms/InstCombine/select-factorize.ll | 119 ++++++++----------- 3 files changed, 179 insertions(+), 143 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 0633388..b832857 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2669,6 +2669,80 @@ foldRoundUpIntegerWithPow2Alignment(SelectInst &SI, return R; } +/// 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 +/// %outer.sel = select i1 %outer.cond, i8 %outer.sel.t, i8 %inner.sel +/// and rewrite it as +/// %inner.sel = select i1 %cond.alternative, i8 %sel.outer.t, i8 %sel.inner.t +/// %sel.outer = select i1 %cond.inner, i8 %inner.sel, i8 %sel.inner.f +static Instruction *foldNestedSelects(SelectInst &OuterSel, + InstCombiner::BuilderTy &Builder) { + // We must start with a `select`. + Value *OuterCond, *InnerSel, *OuterSelFalseVal; + match(&OuterSel, m_Select(m_Value(OuterCond), m_Value(InnerSel), + m_Value(OuterSelFalseVal))); + + // Canonicalize inversion of the outermost `select`'s condition. + if (match(OuterCond, m_Not(m_Value(OuterCond)))) + std::swap(InnerSel, OuterSelFalseVal); + + auto m_c_LogicalOp = [](auto L, auto R) { + return m_CombineOr(m_c_LogicalAnd(L, R), m_c_LogicalOr(L, R)); + }; + + // The condition of the outermost select must be an `and`/`or`. + if (!match(OuterCond, m_c_LogicalOp(m_Value(), m_Value()))) + return nullptr; + + // To simplify logic, prefer the pattern variant with an `or`. + bool IsAndVariant = match(OuterCond, m_LogicalAnd()); + if (match(OuterCond, m_LogicalAnd())) + std::swap(InnerSel, OuterSelFalseVal); + + // Profitability check - avoid increasing instruction count. + if (none_of(ArrayRef({OuterCond, InnerSel}), + [](Value *V) { return V->hasOneUse(); })) + return nullptr; + + // The appropriate hand of the outermost `select` must be a select itself. + Value *InnerCond, *InnerSelTrueVal, *InnerSelFalseVal; + if (!match(InnerSel, m_Select(m_Value(InnerCond), m_Value(InnerSelTrueVal), + m_Value(InnerSelFalseVal)))) + return nullptr; + + // Canonicalize inversion of the innermost `select`'s condition. + if (match(InnerCond, m_Not(m_Value(InnerCond)))) + std::swap(InnerSelTrueVal, InnerSelFalseVal); + + Value *AltCond = nullptr; + auto matchOuterCond = [OuterCond, m_c_LogicalOp, &AltCond](auto m_InnerCond) { + return match(OuterCond, m_c_LogicalOp(m_InnerCond, m_Value(AltCond))); + }; + + // Finally, match the condition that was driving the outermost `select`, + // it should be a logical operation between the condition that was driving + // the innermost `select` (after accounting for the possible inversions + // of the condition), and some other condition. + if (matchOuterCond(m_Specific(InnerCond))) { + // Done! + } else if (Value * NotInnerCond; matchOuterCond(m_CombineAnd( + m_Not(m_Specific(InnerCond)), m_Value(NotInnerCond)))) { + // Done! + std::swap(InnerSelTrueVal, InnerSelFalseVal); + InnerCond = NotInnerCond; + } else // Not the pattern we were looking for. + return nullptr; + + Value *SelInner = Builder.CreateSelect( + AltCond, IsAndVariant ? OuterSelFalseVal : InnerSelFalseVal, + IsAndVariant ? InnerSelTrueVal : OuterSelFalseVal); + SelInner->takeName(InnerSel); + return SelectInst::Create(InnerCond, + IsAndVariant ? SelInner : InnerSelTrueVal, + IsAndVariant ? InnerSelFalseVal : SelInner); +} + Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) { Value *CondVal = SI.getCondition(); Value *TrueVal = SI.getTrueValue(); @@ -3292,5 +3366,8 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) { } } + if (Instruction *I = foldNestedSelects(SI, Builder)) + return I; + return nullptr; } diff --git a/llvm/test/Transforms/InstCombine/nested-select.ll b/llvm/test/Transforms/InstCombine/nested-select.ll index 6a40de6..2f4e911 100644 --- a/llvm/test/Transforms/InstCombine/nested-select.ll +++ b/llvm/test/Transforms/InstCombine/nested-select.ll @@ -8,9 +8,8 @@ declare void @use.i8(i8) define i8 @andcond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) { ; CHECK-LABEL: @andcond( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL:%.*]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond @@ -20,9 +19,8 @@ define i8 @andcond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inne } define i8 @orcond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) { ; CHECK-LABEL: @orcond( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[INNER_SEL]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond @@ -37,8 +35,8 @@ define i8 @andcond.extrause0(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval ; CHECK-LABEL: @andcond.extrause0( ; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false ; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]]) -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL:%.*]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false @@ -51,8 +49,8 @@ define i8 @orcond.extrause0(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, ; CHECK-LABEL: @orcond.extrause0( ; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]] ; CHECK-NEXT: call void @use.i1(i1 [[OUTER_COND]]) -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[INNER_SEL]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND]], i8 [[INNER_SEL_FALSEVAL:%.*]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond @@ -64,10 +62,10 @@ define i8 @orcond.extrause0(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, define i8 @andcond.extrause1(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.extrause1( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: call void @use.i8(i8 [[INNER_SEL]]) -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: call void @use.i8(i8 [[TMP1]]) +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_TRUEVAL]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false @@ -78,10 +76,10 @@ define i8 @andcond.extrause1(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval } define i8 @orcond.extrause1(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.extrause1( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: call void @use.i8(i8 [[INNER_SEL]]) -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[INNER_SEL]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: call void @use.i8(i8 [[TMP1]]) +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[INNER_SEL_FALSEVAL]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL]], i8 [[INNER_SEL]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond @@ -248,10 +246,9 @@ define i1 @orcond.different.inner.cond.inverted.in.inner.sel(i1 %inner.cond.v0, ; In %outer.sel, %outer.cond is inverted define i1 @andcond.001.inv.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.001.inv.outer.cond( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[NOT_OUTER_COND:%.*]] = xor i1 [[OUTER_COND]], true -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_OUTER_COND]], i1 [[INNER_SEL]], i1 false +; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL]], i1 [[INNER_SEL_FALSEVAL:%.*]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond @@ -262,10 +259,9 @@ define i1 @andcond.001.inv.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.se } define i1 @orcond.001.inv.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.001.inv.outer.cond( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[NOT_OUTER_COND:%.*]] = xor i1 [[OUTER_COND]], true -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_OUTER_COND]], i1 true, i1 [[INNER_SEL]] +; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 true, i1 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond @@ -278,10 +274,8 @@ define i1 @orcond.001.inv.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel ; In %inner.sel, %inner.cond is inverted define i1 @andcond.010.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.010.inv.inner.cond.in.inner.sel( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND]], true -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 false +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL]], i1 [[INNER_SEL_FALSEVAL:%.*]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond @@ -292,10 +286,8 @@ define i1 @andcond.010.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, } define i1 @orcond.010.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.010.inv.inner.cond.in.inner.sel( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND]], true -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND]], i1 true, i1 [[INNER_SEL_TRUEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[INNER_SEL]], i1 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 true, i1 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond @@ -308,10 +300,8 @@ define i1 @orcond.010.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, ; In %outer.cond, %inner.cond is inverted define i8 @andcond.100.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.100.inv.inner.cond.in.outer.cond( -; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND:%.*]], true -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[OUTER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %not.inner.cond = xor i1 %inner.cond, -1 @@ -322,10 +312,8 @@ define i8 @andcond.100.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond } define i8 @orcond.100.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i8 %inner.sel.trueval, i8 %inner.sel.falseval, i8 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.100.inv.inner.cond.in.outer.cond( -; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND:%.*]], true -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i8 [[INNER_SEL]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i8 [[INNER_SEL_TRUEVAL:%.*]], i8 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i8 [[INNER_SEL]], i8 [[INNER_SEL_FALSEVAL:%.*]] ; CHECK-NEXT: ret i8 [[OUTER_SEL]] ; %not.inner.cond = xor i1 %inner.cond, -1 @@ -339,12 +327,13 @@ define i8 @orcond.100.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, ; In %inner.sel, %inner.cond is inverted define i1 @andcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND]], true -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND]], i1 true, i1 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: [[NOT_OUTER_COND:%.*]] = xor i1 [[OUTER_COND]], true -; CHECK-NEXT: call void @use.i1(i1 [[INNER_SEL]]) -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_OUTER_COND]], i1 [[INNER_SEL]], i1 false +; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND:%.*]], true +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND]], i1 true, i1 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: call void @use.i1(i1 [[TMP1]]) +; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 [[INNER_SEL_FALSEVAL]], i1 false +; CHECK-NEXT: [[NOT_INNER_COND1:%.*]] = xor i1 [[INNER_COND]], true +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND1]], i1 true, i1 [[INNER_SEL]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false ; and %inner.cond, %alt.cond @@ -357,12 +346,13 @@ define i1 @andcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(i1 %inner.cond } define i1 @orcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel( -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[INNER_COND:%.*]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND]], true -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false -; CHECK-NEXT: call void @use.i1(i1 [[INNER_SEL]]) -; CHECK-NEXT: [[NOT_OUTER_COND:%.*]] = xor i1 [[OUTER_COND]], true -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_OUTER_COND]], i1 true, i1 [[INNER_SEL]] +; CHECK-NEXT: [[NOT_INNER_COND:%.*]] = xor i1 [[INNER_COND:%.*]], true +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_INNER_COND]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 false +; CHECK-NEXT: call void @use.i1(i1 [[TMP1]]) +; CHECK-NEXT: [[NOT_ALT_COND:%.*]] = xor i1 [[ALT_COND:%.*]], true +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_ALT_COND]], i1 true, i1 [[INNER_SEL_TRUEVAL]] +; CHECK-NEXT: [[NOT_INNER_COND1:%.*]] = xor i1 [[INNER_COND]], true +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND1]], i1 [[INNER_SEL]], i1 false ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %outer.cond = select i1 %inner.cond, i1 true, i1 %alt.cond ; or %inner.cond, %alt.cond @@ -378,11 +368,11 @@ define i1 @orcond.011.inv.outer.cond.inv.inner.cond.in.inner.sel(i1 %inner.cond, ; In %outer.cond, %inner.cond is inverted define i1 @andcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond( -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: call void @use.i1(i1 [[INNER_SEL]]) +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: call void @use.i1(i1 [[TMP1]]) ; CHECK-NEXT: [[ALT_COND_NOT:%.*]] = xor i1 [[ALT_COND:%.*]], true -; CHECK-NEXT: [[NOT_OUTER_COND:%.*]] = select i1 [[INNER_COND]], i1 true, i1 [[ALT_COND_NOT]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_OUTER_COND]], i1 [[INNER_SEL]], i1 false +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND_NOT]], i1 [[INNER_SEL_FALSEVAL]], i1 false +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i1 [[INNER_SEL_TRUEVAL]], i1 [[INNER_SEL]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %not.inner.cond = xor i1 %inner.cond, -1 @@ -395,11 +385,11 @@ define i1 @andcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(i1 %inner.con } define i1 @orcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond( -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] -; CHECK-NEXT: call void @use.i1(i1 [[INNER_SEL]]) +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[INNER_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: call void @use.i1(i1 [[TMP1]]) ; CHECK-NEXT: [[ALT_COND_NOT:%.*]] = xor i1 [[ALT_COND:%.*]], true -; CHECK-NEXT: [[NOT_OUTER_COND:%.*]] = select i1 [[INNER_COND]], i1 [[ALT_COND_NOT]], i1 false -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_OUTER_COND]], i1 true, i1 [[INNER_SEL]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND_NOT]], i1 true, i1 [[INNER_SEL_TRUEVAL]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[INNER_COND]], i1 [[INNER_SEL]], i1 [[INNER_SEL_FALSEVAL]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %not.inner.cond = xor i1 %inner.cond, -1 @@ -416,10 +406,8 @@ define i1 @orcond.101.inv.outer.cond.inv.inner.cond.in.outer.cond(i1 %inner.cond define i1 @andcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.trueval) { ; CHECK-LABEL: @andcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond( ; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND:%.*]], true -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[ALT_COND:%.*]], i1 false -; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND]], true -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 [[INNER_SEL_FALSEVAL:%.*]], i1 false -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 [[OUTER_SEL_TRUEVAL:%.*]], i1 [[INNER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 [[INNER_SEL]], i1 false ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %not.inner.cond.0 = xor i1 %inner.cond, -1 @@ -432,10 +420,8 @@ define i1 @andcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond( define i1 @orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond(i1 %inner.cond, i1 %alt.cond, i1 %inner.sel.trueval, i1 %inner.sel.falseval, i1 %outer.sel.falseval) { ; CHECK-LABEL: @orcond.110.inv.inner.cond.in.inner.sel.inv.inner.cond.in.outer.cond( ; CHECK-NEXT: [[NOT_INNER_COND_0:%.*]] = xor i1 [[INNER_COND:%.*]], true -; CHECK-NEXT: [[OUTER_COND:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 true, i1 [[ALT_COND:%.*]] -; CHECK-NEXT: [[NOT_INNER_COND_1:%.*]] = xor i1 [[INNER_COND]], true -; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[NOT_INNER_COND_1]], i1 true, i1 [[INNER_SEL_TRUEVAL:%.*]] -; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[OUTER_COND]], i1 [[INNER_SEL]], i1 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[INNER_SEL:%.*]] = select i1 [[ALT_COND:%.*]], i1 [[INNER_SEL_TRUEVAL:%.*]], i1 [[OUTER_SEL_FALSEVAL:%.*]] +; CHECK-NEXT: [[OUTER_SEL:%.*]] = select i1 [[NOT_INNER_COND_0]], i1 true, i1 [[INNER_SEL]] ; CHECK-NEXT: ret i1 [[OUTER_SEL]] ; %not.inner.cond.0 = xor i1 %inner.cond, -1 diff --git a/llvm/test/Transforms/InstCombine/select-factorize.ll b/llvm/test/Transforms/InstCombine/select-factorize.ll index bb2527f..9b86b39 100644 --- a/llvm/test/Transforms/InstCombine/select-factorize.ll +++ b/llvm/test/Transforms/InstCombine/select-factorize.ll @@ -3,13 +3,10 @@ declare void @use(i1) -; TODO: C && A || C && B --> (A || B) && C - define i1 @logic_and_logic_or_1(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_and_logic_or_1( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[BC]], i1 false ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %c, i1 %a, i1 false @@ -20,9 +17,8 @@ define i1 @logic_and_logic_or_1(i1 %c, i1 %a, i1 %b) { define i1 @logic_and_logic_or_2(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_and_logic_or_2( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[A:%.*]], i1 [[C:%.*]], i1 false -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[BC]], i1 false ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %a, i1 %c, i1 false @@ -59,9 +55,8 @@ define i1 @logic_and_logic_or_4(i1 %c, i1 %a, i1 %b) { define i1 @logic_and_logic_or_5(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_and_logic_or_5( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[BC]], i1 true, i1 [[AC]] +; CHECK-NEXT: [[AC:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[AC]], i1 false ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %c, i1 %a, i1 false @@ -98,9 +93,8 @@ define i1 @logic_and_logic_or_7(i1 %c, i1 %a, i1 %b) { define i1 @logic_and_logic_or_8(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_and_logic_or_8( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 false -; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 [[C]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[BC]], i1 true, i1 [[AC]] +; CHECK-NEXT: [[AC:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[A:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[AC]], i1 false ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %c, i1 %a, i1 false @@ -111,9 +105,8 @@ define i1 @logic_and_logic_or_8(i1 %c, i1 %a, i1 %b) { define <3 x i1> @logic_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @logic_and_logic_or_vector( -; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[A:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> , <3 x i1> [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <3 x i1> [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> zeroinitializer ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> @@ -124,9 +117,8 @@ define <3 x i1> @logic_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b define <3 x i1> @logic_and_logic_or_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @logic_and_logic_or_vector_poison1( -; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[A:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> , <3 x i1> [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <3 x i1> [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> zeroinitializer ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> @@ -150,9 +142,8 @@ define <3 x i1> @logic_and_logic_or_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 define <3 x i1> @logic_and_logic_or_vector_poison3(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @logic_and_logic_or_vector_poison3( -; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[A:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> , <3 x i1> [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <3 x i1> [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = select <3 x i1> %c, <3 x i1> %a, <3 x i1> @@ -180,9 +171,8 @@ define i1 @logic_and_logic_or_not_one_use(i1 %c, i1 %a, i1 %b) { define i1 @and_logic_and_logic_or_1(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @and_logic_and_logic_or_1( -; CHECK-NEXT: [[AC:%.*]] = and i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[BC]], i1 false ; CHECK-NEXT: ret i1 [[OR]] ; %ac = and i1 %c, %a @@ -206,9 +196,8 @@ define i1 @and_logic_and_logic_or_2(i1 %c, i1 %a, i1 %b) { define i1 @and_logic_and_logic_or_3(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @and_logic_and_logic_or_3( -; CHECK-NEXT: [[AC:%.*]] = and i1 [[A:%.*]], [[C:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 [[B:%.*]], i1 false -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 true, i1 [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[BC]], i1 false ; CHECK-NEXT: ret i1 [[OR]] ; %ac = and i1 %a, %c @@ -232,9 +221,8 @@ define i1 @and_logic_and_logic_or_4(i1 %c, i1 %a, i1 %b) { define <3 x i1> @and_logic_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @and_logic_and_logic_or_vector( -; CHECK-NEXT: [[AC:%.*]] = and <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> , <3 x i1> [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <3 x i1> [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> zeroinitializer ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = and <3 x i1> %c, %a @@ -245,9 +233,8 @@ define <3 x i1> @and_logic_and_logic_or_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1 define <3 x i1> @and_logic_and_logic_or_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @and_logic_and_logic_or_vector_poison1( -; CHECK-NEXT: [[AC:%.*]] = and <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> , <3 x i1> [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <3 x i1> [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = and <3 x i1> %c, %a @@ -258,9 +245,8 @@ define <3 x i1> @and_logic_and_logic_or_vector_poison1(<3 x i1> %c, <3 x i1> %a, define <3 x i1> @and_logic_and_logic_or_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @and_logic_and_logic_or_vector_poison2( -; CHECK-NEXT: [[AC:%.*]] = and <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> , <3 x i1> [[BC]] +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> , <3 x i1> [[B:%.*]] +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> [[BC]], <3 x i1> zeroinitializer ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = and <3 x i1> %c, %a @@ -355,13 +341,10 @@ define i1 @and_and_logic_or_not_one_use(i1 %c, i1 %a, i1 %b) { ret i1 %or } -; TODO: (C || A) && (C || B) --> (A && B) || C - define i1 @logic_or_logic_and_1(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_or_logic_and_1( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 true, i1 [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 [[BC]], i1 false +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[BC]] ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %c, i1 true, i1 %a @@ -372,9 +355,8 @@ define i1 @logic_or_logic_and_1(i1 %c, i1 %a, i1 %b) { define i1 @logic_or_logic_and_2(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_or_logic_and_2( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[A:%.*]], i1 true, i1 [[C:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 true, i1 [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 [[BC]], i1 false +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[BC]] ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %a, i1 true, i1 %c @@ -411,9 +393,8 @@ define i1 @logic_or_logic_and_4(i1 %c, i1 %a, i1 %b) { define i1 @logic_or_logic_and_5(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_or_logic_and_5( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 true, i1 [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[BC]], i1 [[AC]], i1 false +; CHECK-NEXT: [[AC:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[AC]] ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %c, i1 true, i1 %a @@ -450,9 +431,8 @@ define i1 @logic_or_logic_and_7(i1 %c, i1 %a, i1 %b) { define i1 @logic_or_logic_and_8(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @logic_or_logic_and_8( -; CHECK-NEXT: [[AC:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[B:%.*]], i1 true, i1 [[C]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[BC]], i1 [[AC]], i1 false +; CHECK-NEXT: [[AC:%.*]] = select i1 [[B:%.*]], i1 [[A:%.*]], i1 false +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[AC]] ; CHECK-NEXT: ret i1 [[OR]] ; %ac = select i1 %c, i1 true, i1 %a @@ -463,9 +443,8 @@ define i1 @logic_or_logic_and_8(i1 %c, i1 %a, i1 %b) { define <3 x i1> @logic_or_logic_and_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @logic_or_logic_and_vector( -; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[BC]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = select <3 x i1> %c, <3 x i1> , <3 x i1> %a @@ -489,9 +468,8 @@ define <3 x i1> @logic_or_logic_and_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 define <3 x i1> @logic_or_logic_and_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @logic_or_logic_and_vector_poison2( -; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[BC]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = select <3 x i1> %c, <3 x i1> , <3 x i1> %a @@ -502,9 +480,8 @@ define <3 x i1> @logic_or_logic_and_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 define <3 x i1> @logic_or_logic_and_vector_poison3(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @logic_or_logic_and_vector_poison3( -; CHECK-NEXT: [[AC:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[BC]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = select <3 x i1> %c, <3 x i1> , <3 x i1> %a @@ -532,9 +509,8 @@ define i1 @logic_or_logic_and_not_one_use(i1 %c, i1 %a, i1 %b) { define i1 @or_logic_or_logic_and_1(i1 %c, i1 %a, i1 %b) { ; CHECK-LABEL: @or_logic_or_logic_and_1( -; CHECK-NEXT: [[AC:%.*]] = or i1 [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select i1 [[C]], i1 true, i1 [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select i1 [[AC]], i1 [[BC]], i1 false +; CHECK-NEXT: [[BC:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false +; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 true, i1 [[BC]] ; CHECK-NEXT: ret i1 [[OR]] ; %ac = or i1 %c, %a @@ -584,9 +560,8 @@ define i1 @or_logic_or_logic_and_4(i1 %c, i1 %a, i1 %b) { define <3 x i1> @or_logic_or_logic_and_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @or_logic_or_logic_and_vector( -; CHECK-NEXT: [[AC:%.*]] = or <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[BC]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = or <3 x i1> %c, %a @@ -597,9 +572,8 @@ define <3 x i1> @or_logic_or_logic_and_vector(<3 x i1> %c, <3 x i1> %a, <3 x i1> define <3 x i1> @or_logic_or_logic_and_vector_poison1(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @or_logic_or_logic_and_vector_poison1( -; CHECK-NEXT: [[AC:%.*]] = or <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> zeroinitializer +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[BC]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = or <3 x i1> %c, %a @@ -610,9 +584,8 @@ define <3 x i1> @or_logic_or_logic_and_vector_poison1(<3 x i1> %c, <3 x i1> %a, define <3 x i1> @or_logic_or_logic_and_vector_poison2(<3 x i1> %c, <3 x i1> %a, <3 x i1> %b) { ; CHECK-LABEL: @or_logic_or_logic_and_vector_poison2( -; CHECK-NEXT: [[AC:%.*]] = or <3 x i1> [[C:%.*]], [[A:%.*]] -; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[C]], <3 x i1> , <3 x i1> [[B:%.*]] -; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[AC]], <3 x i1> [[BC]], <3 x i1> +; CHECK-NEXT: [[BC:%.*]] = select <3 x i1> [[A:%.*]], <3 x i1> [[B:%.*]], <3 x i1> +; CHECK-NEXT: [[OR:%.*]] = select <3 x i1> [[C:%.*]], <3 x i1> , <3 x i1> [[BC]] ; CHECK-NEXT: ret <3 x i1> [[OR]] ; %ac = or <3 x i1> %c, %a -- 2.7.4