@@ -33,6 +33,12 @@ template <typename Pattern>
33
33
return P.match (MRI, &MI);
34
34
}
35
35
36
+ template <typename Pattern>
37
+ [[nodiscard]] bool mi_match (const MachineInstr &MI,
38
+ const MachineRegisterInfo &MRI, Pattern &&P) {
39
+ return P.match (MRI, &MI);
40
+ }
41
+
36
42
// TODO: Extend for N use.
37
43
template <typename SubPatternT> struct OneUse_match {
38
44
SubPatternT SubPat;
@@ -337,6 +343,19 @@ template <> struct bind_helper<MachineInstr *> {
337
343
}
338
344
};
339
345
346
+ template <> struct bind_helper <const MachineInstr *> {
347
+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
348
+ Register Reg) {
349
+ MI = MRI.getVRegDef (Reg);
350
+ return MI;
351
+ }
352
+ static bool bind (const MachineRegisterInfo &MRI, const MachineInstr *&MI,
353
+ const MachineInstr *Inst) {
354
+ MI = Inst;
355
+ return MI;
356
+ }
357
+ };
358
+
340
359
template <> struct bind_helper <LLT> {
341
360
static bool bind (const MachineRegisterInfo &MRI, LLT &Ty, Register Reg) {
342
361
Ty = MRI.getType (Reg);
@@ -368,6 +387,9 @@ template <typename Class> struct bind_ty {
368
387
369
388
inline bind_ty<Register> m_Reg (Register &R) { return R; }
370
389
inline bind_ty<MachineInstr *> m_MInstr (MachineInstr *&MI) { return MI; }
390
+ inline bind_ty<const MachineInstr *> m_MInstr (const MachineInstr *&MI) {
391
+ return MI;
392
+ }
371
393
inline bind_ty<LLT> m_Type (LLT &Ty) { return Ty; }
372
394
inline bind_ty<CmpInst::Predicate> m_Pred (CmpInst::Predicate &P) { return P; }
373
395
inline operand_type_match m_Pred () { return operand_type_match (); }
@@ -418,26 +440,28 @@ inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
418
440
419
441
// General helper for all the binary generic MI such as G_ADD/G_SUB etc
420
442
template <typename LHS_P, typename RHS_P, unsigned Opcode,
421
- bool Commutable = false >
443
+ bool Commutable = false , unsigned Flags = MachineInstr::NoFlags >
422
444
struct BinaryOp_match {
423
445
LHS_P L;
424
446
RHS_P R;
425
447
426
448
BinaryOp_match (const LHS_P &LHS, const RHS_P &RHS) : L(LHS), R(RHS) {}
427
449
template <typename OpTy>
428
450
bool match (const MachineRegisterInfo &MRI, OpTy &&Op) {
429
- MachineInstr *TmpMI;
451
+ const MachineInstr *TmpMI;
430
452
if (mi_match (Op, MRI, m_MInstr (TmpMI))) {
431
453
if (TmpMI->getOpcode () == Opcode && TmpMI->getNumOperands () == 3 ) {
432
- return (L.match (MRI, TmpMI->getOperand (1 ).getReg ()) &&
433
- R.match (MRI, TmpMI->getOperand (2 ).getReg ())) ||
434
- // NOTE: When trying the alternative operand ordering
435
- // with a commutative operation, it is imperative to always run
436
- // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
437
- // (i.e. `R`). Otherwsie, m_DeferredReg/Type will not work as
438
- // expected.
439
- (Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
440
- R.match (MRI, TmpMI->getOperand (1 ).getReg ())));
454
+ if ((!L.match (MRI, TmpMI->getOperand (1 ).getReg ()) ||
455
+ !R.match (MRI, TmpMI->getOperand (2 ).getReg ())) &&
456
+ // NOTE: When trying the alternative operand ordering
457
+ // with a commutative operation, it is imperative to always run
458
+ // the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
459
+ // (i.e. `R`). Otherwise, m_DeferredReg/Type will not work as
460
+ // expected.
461
+ (!Commutable || !L.match (MRI, TmpMI->getOperand (2 ).getReg ()) ||
462
+ !R.match (MRI, TmpMI->getOperand (1 ).getReg ())))
463
+ return false ;
464
+ return (TmpMI->getFlags () & Flags) == Flags;
441
465
}
442
466
}
443
467
return false ;
@@ -464,7 +488,7 @@ struct BinaryOpc_match {
464
488
// NOTE: When trying the alternative operand ordering
465
489
// with a commutative operation, it is imperative to always run
466
490
// the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
467
- // (i.e. `R`). Otherwsie , m_DeferredReg/Type will not work as
491
+ // (i.e. `R`). Otherwise , m_DeferredReg/Type will not work as
468
492
// expected.
469
493
(Commutable && (L.match (MRI, TmpMI->getOperand (2 ).getReg ()) &&
470
494
R.match (MRI, TmpMI->getOperand (1 ).getReg ())));
@@ -559,6 +583,19 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true> m_GOr(const LHS &L,
559
583
return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true >(L, R);
560
584
}
561
585
586
+ template <typename LHS, typename RHS>
587
+ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
588
+ MachineInstr::Disjoint>
589
+ m_GDisjointOr (const LHS &L, const RHS &R) {
590
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true ,
591
+ MachineInstr::Disjoint>(L, R);
592
+ }
593
+
594
+ template <typename LHS, typename RHS>
595
+ inline auto m_GAddLike (const LHS &L, const RHS &R) {
596
+ return m_any_of (m_GAdd (L, R), m_GDisjointOr (L, R));
597
+ }
598
+
562
599
template <typename LHS, typename RHS>
563
600
inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false >
564
601
m_GShl (const LHS &L, const RHS &R) {
@@ -717,7 +754,7 @@ struct CompareOp_match {
717
754
// NOTE: When trying the alternative operand ordering
718
755
// with a commutative operation, it is imperative to always run
719
756
// the LHS sub-pattern (i.e. `L`) before the RHS sub-pattern
720
- // (i.e. `R`). Otherwsie , m_DeferredReg/Type will not work as expected.
757
+ // (i.e. `R`). Otherwise , m_DeferredReg/Type will not work as expected.
721
758
if (Commutable && L.match (MRI, RHS) && R.match (MRI, LHS) &&
722
759
P.match (MRI, CmpInst::getSwappedPredicate (TmpPred)))
723
760
return true ;
0 commit comments