|
16 | 16 | #include "llvm/ADT/APInt.h"
|
17 | 17 | #include "llvm/CodeGen/GlobalISel/Utils.h"
|
18 | 18 | #include "llvm/CodeGen/MachineRegisterInfo.h"
|
| 19 | +#include "llvm/IR/InstrTypes.h" |
19 | 20 |
|
20 | 21 | namespace llvm {
|
21 | 22 | namespace MIPatternMatch {
|
@@ -163,6 +164,8 @@ template <typename Class> struct bind_ty {
|
163 | 164 | inline bind_ty<Register> m_Reg(Register &R) { return R; }
|
164 | 165 | inline bind_ty<MachineInstr *> m_MInstr(MachineInstr *&MI) { return MI; }
|
165 | 166 | inline bind_ty<LLT> m_Type(LLT &Ty) { return Ty; }
|
| 167 | +inline bind_ty<CmpInst::Predicate> m_Pred(CmpInst::Predicate &P) { return P; } |
| 168 | +inline operand_type_match m_Pred() { return operand_type_match(); } |
166 | 169 |
|
167 | 170 | // Helper for matching G_FCONSTANT
|
168 | 171 | inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
|
@@ -320,6 +323,45 @@ inline UnaryOp_match<SrcTy, TargetOpcode::COPY> m_Copy(SrcTy &&Src) {
|
320 | 323 | return UnaryOp_match<SrcTy, TargetOpcode::COPY>(std::forward<SrcTy>(Src));
|
321 | 324 | }
|
322 | 325 |
|
| 326 | +// General helper for generic MI compares, i.e. G_ICMP and G_FCMP |
| 327 | +// TODO: Allow checking a specific predicate. |
| 328 | +template <typename Pred_P, typename LHS_P, typename RHS_P, unsigned Opcode> |
| 329 | +struct CompareOp_match { |
| 330 | + Pred_P P; |
| 331 | + LHS_P L; |
| 332 | + RHS_P R; |
| 333 | + |
| 334 | + CompareOp_match(const Pred_P &Pred, const LHS_P &LHS, const RHS_P &RHS) |
| 335 | + : P(Pred), L(LHS), R(RHS) {} |
| 336 | + |
| 337 | + template <typename OpTy> |
| 338 | + bool match(const MachineRegisterInfo &MRI, OpTy &&Op) { |
| 339 | + MachineInstr *TmpMI; |
| 340 | + if (!mi_match(Op, MRI, m_MInstr(TmpMI)) || TmpMI->getOpcode() != Opcode) |
| 341 | + return false; |
| 342 | + |
| 343 | + auto TmpPred = |
| 344 | + static_cast<CmpInst::Predicate>(TmpMI->getOperand(1).getPredicate()); |
| 345 | + if (!P.match(MRI, TmpPred)) |
| 346 | + return false; |
| 347 | + |
| 348 | + return L.match(MRI, TmpMI->getOperand(2).getReg()) && |
| 349 | + R.match(MRI, TmpMI->getOperand(3).getReg()); |
| 350 | + } |
| 351 | +}; |
| 352 | + |
| 353 | +template <typename Pred, typename LHS, typename RHS> |
| 354 | +inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP> |
| 355 | +m_GICmp(const Pred &P, const LHS &L, const RHS &R) { |
| 356 | + return CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP>(P, L, R); |
| 357 | +} |
| 358 | + |
| 359 | +template <typename Pred, typename LHS, typename RHS> |
| 360 | +inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP> |
| 361 | +m_GFCmp(const Pred &P, const LHS &L, const RHS &R) { |
| 362 | + return CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP>(P, L, R); |
| 363 | +} |
| 364 | + |
323 | 365 | // Helper for checking if a Reg is of specific type.
|
324 | 366 | struct CheckType {
|
325 | 367 | LLT Ty;
|
|
0 commit comments