@@ -392,24 +392,32 @@ m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1) {
392392 return m_c_Binary<Instruction::Or, Op0_t, Op1_t>(Op0, Op1);
393393}
394394
395- // / ICmp_match is a variant of BinaryRecipe_match that also binds the comparison
396- // / predicate.
397- template <typename Op0_t, typename Op1_t> struct ICmp_match {
395+ // / Cmp_match is a variant of BinaryRecipe_match that also binds the comparison
396+ // / predicate. Opcodes must either be Instruction::ICmp or Instruction::FCmp, or
397+ // / both.
398+ template <typename Op0_t, typename Op1_t, unsigned ... Opcodes>
399+ struct Cmp_match {
400+ static_assert ((sizeof ...(Opcodes) == 1 || sizeof ...(Opcodes) == 2 ) &&
401+ " Expected one or two opcodes" );
402+ static_assert (
403+ ((Opcodes == Instruction::ICmp || Opcodes == Instruction::FCmp) && ...) &&
404+ " Expected a compare instruction opcode" );
405+
398406 CmpPredicate *Predicate = nullptr ;
399407 Op0_t Op0;
400408 Op1_t Op1;
401409
402- ICmp_match (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
410+ Cmp_match (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1)
403411 : Predicate(&Pred), Op0(Op0), Op1(Op1) {}
404- ICmp_match (const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
412+ Cmp_match (const Op0_t &Op0, const Op1_t &Op1) : Op0(Op0), Op1(Op1) {}
405413
406414 bool match (const VPValue *V) const {
407415 auto *DefR = V->getDefiningRecipe ();
408416 return DefR && match (DefR);
409417 }
410418
411419 bool match (const VPRecipeBase *V) const {
412- if (m_Binary<Instruction::ICmp >(Op0, Op1).match (V)) {
420+ if (( m_Binary<Opcodes >(Op0, Op1).match (V) || ... )) {
413421 if (Predicate)
414422 *Predicate = cast<VPRecipeWithIRFlags>(V)->getPredicate ();
415423 return true ;
@@ -418,38 +426,63 @@ template <typename Op0_t, typename Op1_t> struct ICmp_match {
418426 }
419427};
420428
421- // / SpecificICmp_match is a variant of ICmp_match that matches the comparison
429+ // / SpecificCmp_match is a variant of Cmp_match that matches the comparison
422430// / predicate, instead of binding it.
423- template <typename Op0_t, typename Op1_t> struct SpecificICmp_match {
431+ template <typename Op0_t, typename Op1_t, unsigned ... Opcodes>
432+ struct SpecificCmp_match {
424433 const CmpPredicate Predicate;
425434 Op0_t Op0;
426435 Op1_t Op1;
427436
428- SpecificICmp_match (CmpPredicate Pred, const Op0_t &LHS, const Op1_t &RHS)
437+ SpecificCmp_match (CmpPredicate Pred, const Op0_t &LHS, const Op1_t &RHS)
429438 : Predicate(Pred), Op0(LHS), Op1(RHS) {}
430439
431440 bool match (const VPValue *V) const {
432441 CmpPredicate CurrentPred;
433- return ICmp_match<Op0_t, Op1_t>(CurrentPred, Op0, Op1).match (V) &&
442+ return Cmp_match<Op0_t, Op1_t, Opcodes...>(CurrentPred, Op0, Op1)
443+ .match (V) &&
434444 CmpPredicate::getMatching (CurrentPred, Predicate);
435445 }
436446};
437447
438448template <typename Op0_t, typename Op1_t>
439- inline ICmp_match<Op0_t, Op1_t> m_ICmp (const Op0_t &Op0, const Op1_t &Op1) {
440- return ICmp_match<Op0_t, Op1_t>(Op0, Op1);
449+ inline Cmp_match<Op0_t, Op1_t, Instruction::ICmp> m_ICmp (const Op0_t &Op0,
450+ const Op1_t &Op1) {
451+ return Cmp_match<Op0_t, Op1_t, Instruction::ICmp>(Op0, Op1);
441452}
442453
443454template <typename Op0_t, typename Op1_t>
444- inline ICmp_match <Op0_t, Op1_t> m_ICmp (CmpPredicate &Pred, const Op0_t &Op0,
445- const Op1_t &Op1) {
446- return ICmp_match <Op0_t, Op1_t>(Pred, Op0, Op1);
455+ inline Cmp_match <Op0_t, Op1_t, Instruction::ICmp>
456+ m_ICmp (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1) {
457+ return Cmp_match <Op0_t, Op1_t, Instruction::ICmp >(Pred, Op0, Op1);
447458}
448459
449460template <typename Op0_t, typename Op1_t>
450- inline SpecificICmp_match <Op0_t, Op1_t>
461+ inline SpecificCmp_match <Op0_t, Op1_t, Instruction::ICmp >
451462m_SpecificICmp (CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
452- return SpecificICmp_match<Op0_t, Op1_t>(MatchPred, Op0, Op1);
463+ return SpecificCmp_match<Op0_t, Op1_t, Instruction::ICmp>(MatchPred, Op0,
464+ Op1);
465+ }
466+
467+ template <typename Op0_t, typename Op1_t>
468+ inline Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>
469+ m_Cmp (const Op0_t &Op0, const Op1_t &Op1) {
470+ return Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>(Op0,
471+ Op1);
472+ }
473+
474+ template <typename Op0_t, typename Op1_t>
475+ inline Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>
476+ m_Cmp (CmpPredicate &Pred, const Op0_t &Op0, const Op1_t &Op1) {
477+ return Cmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>(
478+ Pred, Op0, Op1);
479+ }
480+
481+ template <typename Op0_t, typename Op1_t>
482+ inline SpecificCmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>
483+ m_SpecificCmp (CmpPredicate MatchPred, const Op0_t &Op0, const Op1_t &Op1) {
484+ return SpecificCmp_match<Op0_t, Op1_t, Instruction::ICmp, Instruction::FCmp>(
485+ MatchPred, Op0, Op1);
453486}
454487
455488template <typename Op0_t, typename Op1_t>
0 commit comments