@@ -50,6 +50,17 @@ template <typename Class> struct bind_ty {
5050 }
5151};
5252
53+ // / Match a specified VPValue.
54+ struct specificval_ty {
55+ const VPValue *Val;
56+
57+ specificval_ty (const VPValue *V) : Val(V) {} // std::move?
58+
59+ bool match (VPValue *VPV) { return VPV == Val; }
60+ };
61+
62+ inline specificval_ty m_Specific (const VPValue *VPV) { return VPV; }
63+
5364// / Match a specified integer value or vector of all elements of that
5465// / value. \p BitWidth optionally specifies the bitwidth the matched constant
5566// / must have. If it is 0, the matched constant can have any bitwidth.
@@ -197,6 +208,39 @@ using AllBinaryRecipe_match =
197208 BinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative, VPWidenRecipe,
198209 VPReplicateRecipe, VPWidenCastRecipe, VPInstruction>;
199210
211+ template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode,
212+ typename ... RecipeTys>
213+ struct TernaryRecipe_match {
214+ Op0_t Op0;
215+ Op1_t Op1;
216+ Op2_t Op2;
217+
218+ TernaryRecipe_match (Op0_t Op0, Op1_t Op1, Op2_t Op2)
219+ : Op0(Op0), Op1(Op1), Op2(Op2) {}
220+
221+ bool match (const VPValue *V) {
222+ auto *DefR = V->getDefiningRecipe ();
223+ return DefR && match (DefR);
224+ }
225+
226+ bool match (const VPSingleDefRecipe *R) {
227+ return match (static_cast <const VPRecipeBase *>(R));
228+ }
229+
230+ bool match (const VPRecipeBase *R) {
231+ if (!detail::MatchRecipeAndOpcode<Opcode, RecipeTys...>::match (R))
232+ return false ;
233+ assert (R->getNumOperands () == 3 &&
234+ " recipe with matched opcode does not have 3 operands" );
235+ return Op0.match (R->getOperand (0 )) && Op1.match (R->getOperand (1 )) &&
236+ Op2.match (R->getOperand (2 ));
237+ }
238+ };
239+
240+ template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode>
241+ using TernaryVPInstruction_match =
242+ TernaryRecipe_match<Op0_t, Op1_t, Op2_t, Opcode, VPInstruction>;
243+
200244template <unsigned Opcode, typename Op0_t>
201245inline UnaryVPInstruction_match<Op0_t, Opcode>
202246m_VPInstruction (const Op0_t &Op0) {
@@ -209,6 +253,12 @@ m_VPInstruction(const Op0_t &Op0, const Op1_t &Op1) {
209253 return BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>(Op0, Op1);
210254}
211255
256+ template <unsigned Opcode, typename Op0_t, typename Op1_t, typename Op2_t>
257+ inline TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Opcode>
258+ m_VPInstruction (const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
259+ return TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Opcode>(Op0, Op1, Op2);
260+ }
261+
212262template <typename Op0_t>
213263inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
214264m_Not (const Op0_t &Op0) {
@@ -304,6 +354,13 @@ m_LogicalAnd(const Op0_t &Op0, const Op1_t &Op1) {
304354 return m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1);
305355}
306356
357+ template <typename Op0_t, typename Op1_t, typename Op2_t>
358+ inline TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Instruction::Select>
359+ m_Select (const Op0_t &Cond, const Op1_t &LHS, const Op2_t &RHS) {
360+ return m_VPInstruction<Instruction::Select, Op0_t, Op1_t, Op2_t>(Cond, LHS,
361+ RHS);
362+ }
363+
307364struct VPCanonicalIVPHI_match {
308365 bool match (const VPValue *V) {
309366 auto *DefR = V->getDefiningRecipe ();
0 commit comments