@@ -50,6 +50,17 @@ template <typename Class> struct bind_ty {
50
50
}
51
51
};
52
52
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
+
53
64
// / Match a specified integer value or vector of all elements of that
54
65
// / value. \p BitWidth optionally specifies the bitwidth the matched constant
55
66
// / must have. If it is 0, the matched constant can have any bitwidth.
@@ -197,6 +208,39 @@ using AllBinaryRecipe_match =
197
208
BinaryRecipe_match<Op0_t, Op1_t, Opcode, Commutative, VPWidenRecipe,
198
209
VPReplicateRecipe, VPWidenCastRecipe, VPInstruction>;
199
210
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
+
200
244
template <unsigned Opcode, typename Op0_t>
201
245
inline UnaryVPInstruction_match<Op0_t, Opcode>
202
246
m_VPInstruction (const Op0_t &Op0) {
@@ -209,6 +253,12 @@ m_VPInstruction(const Op0_t &Op0, const Op1_t &Op1) {
209
253
return BinaryVPInstruction_match<Op0_t, Op1_t, Opcode>(Op0, Op1);
210
254
}
211
255
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
+
212
262
template <typename Op0_t>
213
263
inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
214
264
m_Not (const Op0_t &Op0) {
@@ -304,6 +354,13 @@ m_LogicalAnd(const Op0_t &Op0, const Op1_t &Op1) {
304
354
return m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1);
305
355
}
306
356
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
+
307
364
struct VPCanonicalIVPHI_match {
308
365
bool match (const VPValue *V) {
309
366
auto *DefR = V->getDefiningRecipe ();
0 commit comments