@@ -3012,6 +3012,32 @@ struct DecomposedSelect {
3012
3012
};
3013
3013
} // namespace
3014
3014
3015
+ // / Folds patterns like:
3016
+ // / select c2 (select c1 a b) (select c1 b a)
3017
+ // / into:
3018
+ // / select (xor c1 c2) b a
3019
+ static Instruction *
3020
+ foldSelectOfSymmetricSelect (SelectInst &OuterSelVal,
3021
+ InstCombiner::BuilderTy &Builder) {
3022
+
3023
+ DecomposedSelect OuterSel, InnerSel;
3024
+ if (!match (&OuterSelVal,
3025
+ m_Select (m_Value (OuterSel.Cond ),
3026
+ m_OneUse (m_Select (m_Value (InnerSel.Cond ),
3027
+ m_Value (InnerSel.TrueVal ),
3028
+ m_Value (InnerSel.FalseVal ))),
3029
+ m_OneUse (m_Select (m_Deferred (InnerSel.Cond ),
3030
+ m_Deferred (InnerSel.FalseVal ),
3031
+ m_Deferred (InnerSel.TrueVal ))))))
3032
+ return nullptr ;
3033
+
3034
+ if (OuterSel.Cond ->getType () != InnerSel.Cond ->getType ())
3035
+ return nullptr ;
3036
+
3037
+ Value *Xor = Builder.CreateXor (InnerSel.Cond , OuterSel.Cond );
3038
+ return SelectInst::Create (Xor, InnerSel.FalseVal , InnerSel.TrueVal );
3039
+ }
3040
+
3015
3041
// / Look for patterns like
3016
3042
// / %outer.cond = select i1 %inner.cond, i1 %alt.cond, i1 false
3017
3043
// / %inner.sel = select i1 %inner.cond, i8 %inner.sel.t, i8 %inner.sel.f
@@ -3987,6 +4013,9 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
3987
4013
}
3988
4014
}
3989
4015
4016
+ if (Instruction *I = foldSelectOfSymmetricSelect (SI, Builder))
4017
+ return I;
4018
+
3990
4019
if (Instruction *I = foldNestedSelects (SI, Builder))
3991
4020
return I;
3992
4021
0 commit comments