@@ -397,24 +397,32 @@ m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1) {
397397 return m_c_Binary<Instruction::Or, Op0_t, Op1_t>(Op0, Op1);
398398}
399399
400- // / ICmp_match is a variant of BinaryRecipe_match that also binds the comparison
401- // / predicate.
402- template <typename Op0_t, typename Op1_t> struct ICmp_match {
400+ // / Cmp_match is a variant of BinaryRecipe_match that also binds the comparison
401+ // / predicate. Opcodes must either be Instruction::ICmp or Instruction::FCmp, or
402+ // / both.
403+ template <typename Op0_t, typename Op1_t, unsigned ... Opcodes>
404+ struct Cmp_match {
405+ static_assert ((sizeof ...(Opcodes) == 1 || sizeof ...(Opcodes) == 2 ) &&
406+ " Expected one or two opcodes" );
407+ static_assert (
408+ ((Opcodes == Instruction::ICmp || Opcodes == Instruction::FCmp) && ...) &&
409+ " Expected a compare instruction opcode" );
410+
403411 CmpPredicate *Predicate = nullptr ;
404412 Op0_t Op0;
405413 Op1_t Op1;
406414
407- ICmp_match (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
415+ Cmp_match (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
408416 : Predicate(&Pred), Op0(Op0), Op1(Op1) {}
409- ICmp_match (const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
417+ Cmp_match (const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
410418
411419 bool match (const VPValue *V) const {
412420 auto *DefR = V->getDefiningRecipe ();
413421 return DefR && match (DefR);
414422 }
415423
416424 bool match (const VPRecipeBase *V) const {
417- if (m_Binary<Instruction::ICmp >(Op0, Op1).match (V)) {
425+ if (( m_Binary<Opcodes >(Op0, Op1).match (V) || ... )) {
418426 if (Predicate)
419427 *Predicate = cast<VPRecipeWithIRFlags>(V)->getPredicate ();
420428 return true ;
@@ -423,38 +431,63 @@ template <typename Op0_t, typename Op1_t> struct ICmp_match {
423431 }
424432};
425433
426- // / SpecificICmp_match is a variant of ICmp_match that matches the comparison
434+ // / SpecificCmp_match is a variant of Cmp_match that matches the comparison
427435// / predicate, instead of binding it.
428- template <typename Op0_t, typename Op1_t> struct SpecificICmp_match {
436+ template <typename Op0_t, typename Op1_t, unsigned ... Opcodes>
437+ struct SpecificCmp_match {
429438 const CmpPredicate Predicate;
430439 Op0_t Op0;
431440 Op1_t Op1;
432441
433- SpecificICmp_match (CmpPredicate Pred, const Op0_t &LHS, const Op1_t &RHS)
442+ SpecificCmp_match (CmpPredicate Pred, const Op0_t &LHS, const Op1_t &RHS)
434443 : Predicate(Pred), Op0(LHS), Op1(RHS) {}
435444
436445 bool match (const VPValue *V) const {
437446 CmpPredicate CurrentPred;
438- return ICmp_match<Op0_t, Op1_t>(CurrentPred, Op0, Op1).match (V) &&
447+ return Cmp_match<Op0_t, Op1_t, Opcodes...>(CurrentPred, Op0, Op1)
448+ .match (V) &&
439449 CmpPredicate::getMatching (CurrentPred, Predicate);
440450 }
441451};
442452
443453template <typename Op0_t, typename Op1_t>
444- inline ICmp_match<Op0_t, Op1_t> m_ICmp (const Op0_t &Op0, const Op1_t &Op1) {
445- return ICmp_match<Op0_t, Op1_t>(Op0, Op1);
454+ inline Cmp_match<Op0_t, Op1_t, Instruction::ICmp> m_ICmp (const Op0_t &Op0,
455+ const Op1_t &Op1) {
456+ return Cmp_match<Op0_t, Op1_t, Instruction::ICmp>(Op0, Op1);
446457}
447458
448459template <typename Op0_t, typename Op1_t>
449- inline ICmp_match <Op0_t, Op1_t> m_ICmp (CmpPredicate &Pred, const Op0_t &Op0,
450- const Op1_t &Op1) {
451- return ICmp_match <Op0_t, Op1_t>(Pred, Op0, Op1);
460+ inline Cmp_match <Op0_t, Op1_t, Instruction::ICmp>
461+ m_ICmp (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1) {
462+ return Cmp_match <Op0_t, Op1_t, Instruction::ICmp >(Pred, Op0, Op1);
452463}
453464
454465template <typename Op0_t, typename Op1_t>
455- inline SpecificICmp_match <Op0_t, Op1_t>
466+ inline SpecificCmp_match <Op0_t, Op1_t, Instruction::ICmp >
456467m_SpecificICmp (CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
457- return SpecificICmp_match<Op0_t, Op1_t>(MatchPred, Op0, Op1);
468+ return SpecificCmp_match<Op0_t, Op1_t, Instruction::ICmp>(MatchPred, Op0,
469+ Op1);
470+ }
471+
472+ template <typename Op0_t, typename Op1_t>
473+ inline Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>
474+ m_Cmp (const Op0_t &Op0, const Op1_t &Op1) {
475+ return Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>(Op0,
476+ Op1);
477+ }
478+
479+ template <typename Op0_t, typename Op1_t>
480+ inline Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>
481+ m_Cmp (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1) {
482+ return Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>(
483+ Pred, Op0, Op1);
484+ }
485+
486+ template <typename Op0_t, typename Op1_t>
487+ inline SpecificCmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>
488+ m_SpecificCmp (CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
489+ return SpecificCmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>(
490+ MatchPred, Op0, Op1);
458491}
459492
460493template <typename Op0_t, typename Op1_t>
0 commit comments