Skip to content

Commit 2b4c13f

Browse files
committed
VPlan Pattern match for Instruction::Select
1 parent 62e853a commit 2b4c13f

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
205249
template <unsigned Opcode, typename Op0_t>
206250
inline UnaryVPInstruction_match<Op0_t, Opcode>
207251
m_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+
217267
template <typename Op0_t>
218268
inline UnaryVPInstruction_match<Op0_t, VPInstruction::Not>
219269
m_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+
312369
struct VPCanonicalIVPHI_match {
313370
bool match(const VPValue *V) {
314371
auto *DefR = V->getDefiningRecipe();

0 commit comments

Comments
 (0)