@@ -55,6 +55,17 @@ template <typename Class> struct bind_ty {
5555 }
5656};
5757
58+ // / Match a specified VPValue.
59+ struct specificval_ty {
60+ const VPValue *Val;
61+
62+ specificval_ty (const VPValue *V) : Val(V) {} // std::move?
63+
64+ bool match (VPValue *VPV) { return VPV == Val; }
65+ };
66+
67+ inline specificval_ty m_Specific (const VPValue *VPV) { return VPV; }
68+
5869// / Match a specified integer value or vector of all elements of that
5970// / value. \p BitWidth optionally specifies the bitwidth the matched constant
6071// / must have. If it is 0, the matched constant can have any bitwidth.
@@ -202,6 +213,39 @@ using AllBinaryRecipe_match =
202213 BinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative, VPWidenRecipe,
203214 VPReplicateRecipe, VPWidenCastRecipe, VPInstruction>;
204215
216+ template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode,
217+ typename ... RecipeTys>
218+ struct TernaryRecipe_match {
219+ Op0_t Op0;
220+ Op1_t Op1;
221+ Op2_t Op2;
222+
223+ TernaryRecipe_match (Op0_t Op0, Op1_t Op1, Op2_t Op2)
224+ : Op0(Op0), Op1(Op1), Op2(Op2) {}
225+
226+ bool match (const VPValue *V) {
227+ auto *DefR = V->getDefiningRecipe ();
228+ return DefR && match (DefR);
229+ }
230+
231+ bool match (const VPSingleDefRecipe *R) {
232+ return match (static_cast <const VPRecipeBase *>(R));
233+ }
234+
235+ bool match (const VPRecipeBase *R) {
236+ if (!detail::MatchRecipeAndOpcode<Opcode, RecipeTys...>::match (R))
237+ return false ;
238+ assert (R->getNumOperands () == 3 &&
239+ " recipe with matched opcode does not have 3 operands" );
240+ return Op0.match (R->getOperand (0 )) && Op1.match (R->getOperand (1 )) &&
241+ Op2.match (R->getOperand (2 ));
242+ }
243+ };
244+
245+ template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode>
246+ using TernaryVPInstruction_match =
247+ TernaryRecipe_match<Op0_t, Op1_t, Op2_t, Opcode, VPInstruction>;
248+
205249template <unsigned Opcode, typename Op0_t>
206250inline UnaryVPInstruction_match<Op0_t, Opcode>
207251m_VPInstruction (const Op0_t &Op0) {
@@ -214,6 +258,12 @@ m_VPInstruction(const Op0_t &Op0, const Op1_t &Op1) {
214258 return BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>(Op0, Op1);
215259}
216260
261+ template <unsigned Opcode, typename Op0_t, typename Op1_t, typename Op2_t>
262+ inline TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Opcode>
263+ m_VPInstruction (const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
264+ return TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Opcode>(Op0, Op1, Op2);
265+ }
266+
217267template <typename Op0_t>
218268inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
219269m_Not (const Op0_t &Op0) {
@@ -309,6 +359,13 @@ m_LogicalAnd(const Op0_t &Op0, const Op1_t &Op1) {
309359 return m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1);
310360}
311361
362+ template <typename Op0_t, typename Op1_t, typename Op2_t>
363+ inline TernaryVPInstruction_match<Op0_t, Op1_t, Op2_t, Instruction::Select>
364+ m_Select (const Op0_t &Cond, const Op1_t &LHS, const Op2_t &RHS) {
365+ return m_VPInstruction<Instruction::Select, Op0_t, Op1_t, Op2_t>(Cond, LHS,
366+ RHS);
367+ }
368+
312369struct VPCanonicalIVPHI_match {
313370 bool match (const VPValue *V) {
314371 auto *DefR = V->getDefiningRecipe ();
0 commit comments