@@ -75,8 +75,8 @@ template <unsigned BitWidth = 0> struct specific_intval {
75
75
if (!CI)
76
76
return false ;
77
77
78
- assert (( BitWidth == 0 || CI->getBitWidth () == BitWidth) &&
79
- " Trying the match constant with unexpected bitwidth. " ) ;
78
+ if ( BitWidth != 0 && CI->getBitWidth () != BitWidth)
79
+ return false ;
80
80
return APInt::isSameValue (CI->getValue (), Val);
81
81
}
82
82
};
@@ -87,6 +87,8 @@ inline specific_intval<0> m_SpecificInt(uint64_t V) {
87
87
88
88
inline specific_intval<1 > m_False () { return specific_intval<1 >(APInt (64 , 0 )); }
89
89
90
+ inline specific_intval<1 > m_True () { return specific_intval<1 >(APInt (64 , 1 )); }
91
+
90
92
// / Matching combinators
91
93
template <typename LTy, typename RTy> struct match_combine_or {
92
94
LTy L;
@@ -122,7 +124,8 @@ struct MatchRecipeAndOpcode<Opcode, RecipeTy> {
122
124
auto *DefR = dyn_cast<RecipeTy>(R);
123
125
// Check for recipes that do not have opcodes.
124
126
if constexpr (std::is_same<RecipeTy, VPScalarIVStepsRecipe>::value ||
125
- std::is_same<RecipeTy, VPCanonicalIVPHIRecipe>::value)
127
+ std::is_same<RecipeTy, VPCanonicalIVPHIRecipe>::value ||
128
+ std::is_same<RecipeTy, VPWidenSelectRecipe>::value)
126
129
return DefR;
127
130
else
128
131
return DefR && DefR->getOpcode () == Opcode;
@@ -322,10 +325,34 @@ m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1) {
322
325
return m_BinaryOr<Op0_t, Op1_t, /* Commutative*/ true >(Op0, Op1);
323
326
}
324
327
328
+ template <typename Op0_t, typename Op1_t, typename Op2_t, unsigned Opcode>
329
+ using AllTernaryRecipe_match =
330
+ Recipe_match<std::tuple<Op0_t, Op1_t, Op2_t>, Opcode, false ,
331
+ VPReplicateRecipe, VPInstruction, VPWidenSelectRecipe>;
332
+
333
+ template <typename Op0_t, typename Op1_t, typename Op2_t>
334
+ inline AllTernaryRecipe_match<Op0_t, Op1_t, Op2_t, Instruction::Select>
335
+ m_Select (const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
336
+ return AllTernaryRecipe_match<Op0_t, Op1_t, Op2_t, Instruction::Select>(
337
+ {Op0, Op1, Op2});
338
+ }
339
+
325
340
template <typename Op0_t, typename Op1_t>
326
- inline BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::LogicalAnd>
341
+ inline match_combine_or<
342
+ BinaryVPInstruction_match<Op0_t, Op1_t, VPInstruction::LogicalAnd>,
343
+ AllTernaryRecipe_match<Op0_t, Op1_t, specific_intval<1 >,
344
+ Instruction::Select>>
327
345
m_LogicalAnd (const Op0_t &Op0, const Op1_t &Op1) {
328
- return m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1);
346
+ return m_CombineOr (
347
+ m_VPInstruction<VPInstruction::LogicalAnd, Op0_t, Op1_t>(Op0, Op1),
348
+ m_Select (Op0, Op1, m_False ()));
349
+ }
350
+
351
+ template <typename Op0_t, typename Op1_t>
352
+ inline AllTernaryRecipe_match<Op0_t, specific_intval<1 >, Op1_t,
353
+ Instruction::Select>
354
+ m_LogicalOr (const Op0_t &Op0, const Op1_t &Op1) {
355
+ return m_Select (Op0, m_True (), Op1);
329
356
}
330
357
331
358
using VPCanonicalIVPHI_match =
@@ -344,7 +371,6 @@ inline VPScalarIVSteps_match<Op0_t, Op1_t> m_ScalarIVSteps(const Op0_t &Op0,
344
371
const Op1_t &Op1) {
345
372
return VPScalarIVSteps_match<Op0_t, Op1_t>(Op0, Op1);
346
373
}
347
-
348
374
} // namespace VPlanPatternMatch
349
375
} // namespace llvm
350
376
0 commit comments