[llvm] GlobalISel: Migrate misc. CombinerHelper def checks to MIPatternMatch (PR #216671)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 17 02:44:43 PDT 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/216671

Replace getVRegDef + cast/opcode-check idioms across CombinerHelper
with mi_match, adding named instruction binders and operand-form matchers
as needed.

Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>

>From 5696ae15d825614264a85dd119e7df128a67c962 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sun, 16 Aug 2026 21:49:54 +0200
Subject: [PATCH] GlobalISel: Migrate misc. CombinerHelper def checks to
 MIPatternMatch

Replace getVRegDef + cast/opcode-check idioms across CombinerHelper
with mi_match, adding named instruction binders and operand-form matchers
as needed.

Co-authored-by: Claude (Opus 4.8) <noreply at anthropic.com>
---
 .../llvm/CodeGen/GlobalISel/MIPatternMatch.h  |  54 ++-
 .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 365 ++++++++++--------
 .../GlobalISel/CombinerHelperCasts.cpp        |  10 +-
 .../GlobalISel/CombinerHelperVectorOps.cpp    |  42 +-
 4 files changed, 285 insertions(+), 186 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index e6c6f69d3e0a1..a4312d48ae5cf 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -480,13 +480,12 @@ struct ImplicitDefMatch {
 
 inline ImplicitDefMatch m_GImplicitDef() { return ImplicitDefMatch(); }
 
-/// Matches a G_CONSTANT and binds the defining instruction. Unlike m_ICst, this
-/// returns the instruction (not the value) and does not look through vector
-/// splats.
-template <typename Class> struct GConstantMatch {
+/// Binds the defining instruction of \p Reg if it is a \p Class. Prefer the
+/// named helpers below so the opcode is spelled out at the call site.
+template <typename Class> struct GInstrBind {
   Class *&Inst;
 
-  GConstantMatch(Class *&Inst) : Inst(Inst) {}
+  GInstrBind(Class *&Inst) : Inst(Inst) {}
   bool match(const MachineRegisterInfo &MRI, Register Reg) {
     MachineInstr *TmpMI;
     if (mi_match(Reg, MRI, m_MInstr(TmpMI))) {
@@ -499,8 +498,43 @@ template <typename Class> struct GConstantMatch {
   }
 };
 
-inline GConstantMatch<GConstant> m_GConstant(GConstant *&Inst) { return Inst; }
-inline GConstantMatch<const GConstant> m_GConstant(const GConstant *&Inst) {
+/// Match a literal G_CONSTANT instruction (no look-through of splats or
+/// copies).
+inline GInstrBind<GConstant> m_GConstant(GConstant *&Inst) { return Inst; }
+inline GInstrBind<const GConstant> m_GConstant(const GConstant *&Inst) {
+  return Inst;
+}
+
+/// Match a literal G_CONSTANT or G_FCONSTANT, binding its raw bits to \p Bits
+/// (the integer value, or the float reinterpreted as an integer).
+struct GConstantBitsMatch {
+  APInt &Bits;
+  bool match(const MachineRegisterInfo &MRI, Register Reg) {
+    MachineInstr *MI = MRI.getVRegDef(Reg);
+    if (MI->getOpcode() == TargetOpcode::G_CONSTANT) {
+      Bits = MI->getOperand(1).getCImm()->getValue();
+      return true;
+    }
+    if (MI->getOpcode() == TargetOpcode::G_FCONSTANT) {
+      Bits = MI->getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
+      return true;
+    }
+    return false;
+  }
+};
+
+inline GConstantBitsMatch m_GConstantOrFConstantBits(APInt &Bits) {
+  return {Bits};
+}
+
+/// Instruction binders for ops with no operand-form matcher (constant-immediate
+/// or variadic-source ops).
+inline GInstrBind<GUnmerge> m_GUnmerge(GUnmerge *&Inst) { return Inst; }
+inline GInstrBind<GVScale> m_GVScale(GVScale *&Inst) { return Inst; }
+inline GInstrBind<GBuildVector> m_GBuildVector(GBuildVector *&Inst) {
+  return Inst;
+}
+inline GInstrBind<GConcatVectors> m_GConcatVectors(GConcatVectors *&Inst) {
   return Inst;
 }
 
@@ -624,6 +658,12 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB> m_GSub(const LHS &L,
   return BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>(L, R);
 }
 
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>
+m_GSub(const LHS &L, const RHS &R, MIFlagsRef Flags) {
+  return BinaryOp_match<LHS, RHS, TargetOpcode::G_SUB>(L, R, Flags);
+}
+
 template <typename LHS, typename RHS>
 inline BinaryOp_match<LHS, RHS, TargetOpcode::G_MUL, true>
 m_GMul(const LHS &L, const RHS &R) {
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b8f5f840d5cff..92e3e8e4c1d5b 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -261,7 +261,9 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
   if (!MRI.hasOneNonDBGUse(OrigOp))
     return false;
 
-  MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
+  MachineInstr *OrigDef;
+  if (!mi_match(OrigOp, MRI, m_MInstr(OrigDef)))
+    return false;
   // Even if only a single operand of the PHI is not guaranteed non-poison,
   // moving freeze() backwards across a PHI can cause optimization issues for
   // other users of that operand.
@@ -338,8 +340,9 @@ bool CombinerHelper::matchCombineConcatVectors(
   // Then collect their operands in Ops.
   for (const MachineOperand &MO : MI.uses()) {
     Register Reg = MO.getReg();
-    MachineInstr *Def = MRI.getVRegDef(Reg);
-    assert(Def && "Operand not defined");
+    MachineInstr *Def;
+    if (!mi_match(Reg, MRI, m_MInstr(Def)))
+      return false;
     if (!MRI.hasOneNonDBGUse(Reg))
       return false;
     switch (Def->getOpcode()) {
@@ -414,10 +417,10 @@ bool CombinerHelper::matchCombineBuildVectorOfBitcast(
   GUnmerge *Unmerge = getOpcodeDef<GUnmerge>(BV.getSourceReg(0), MRI);
   if (!Unmerge || Unmerge->getReg(0) != BV.getSourceReg(0))
     return false;
-  MachineInstr *BC = MRI.getVRegDef(Unmerge->getSourceReg());
-  if (BC->getOpcode() != TargetOpcode::G_BITCAST)
+  Register BCSrc;
+  if (!mi_match(Unmerge->getSourceReg(), MRI, m_GBitcast(m_Reg(BCSrc))))
     return false;
-  LLT InputTy = MRI.getType(BC->getOperand(1).getReg());
+  LLT InputTy = MRI.getType(BCSrc);
   unsigned Factor = Unmerge->getNumDefs();
   if (!InputTy.isScalar() || BV.getNumSources() % Factor != 0)
     return false;
@@ -431,8 +434,7 @@ bool CombinerHelper::matchCombineBuildVectorOfBitcast(
   for (unsigned Idx = 0; Idx < BV.getNumSources(); Idx += Factor) {
     GUnmerge *Unmerge = getOpcodeDef<GUnmerge>(BV.getSourceReg(Idx), MRI);
     if (!all_of(iota_range<unsigned>(0, Factor, false), [&](unsigned J) {
-          MachineInstr *Src = MRI.getVRegDef(BV.getSourceReg(Idx + J));
-          if (Src->getOpcode() == TargetOpcode::G_IMPLICIT_DEF)
+          if (mi_match(BV.getSourceReg(Idx + J), MRI, m_GImplicitDef()))
             return true;
           return Unmerge && BV.getSourceReg(Idx + J) == Unmerge->getReg(J);
         }))
@@ -440,11 +442,12 @@ bool CombinerHelper::matchCombineBuildVectorOfBitcast(
     if (!Unmerge)
       Ops.push_back(0);
     else {
-      MachineInstr *BC = MRI.getVRegDef(Unmerge->getSourceReg());
-      if (BC->getOpcode() != TargetOpcode::G_BITCAST ||
-          MRI.getType(BC->getOperand(1).getReg()) != InputTy)
+      Register BCSrc;
+      if (!mi_match(
+              Unmerge->getSourceReg(), MRI,
+              m_GBitcast(m_all_of(m_Reg(BCSrc), m_SpecificType(InputTy)))))
         return false;
-      Ops.push_back(BC->getOperand(1).getReg());
+      Ops.push_back(BCSrc);
     }
   }
 
@@ -502,11 +505,9 @@ void CombinerHelper::applyCombineShuffleToBuildVector(MachineInstr &MI) const {
 bool CombinerHelper::matchCombineShuffleConcat(
     MachineInstr &MI, SmallVector<Register> &Ops) const {
   ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
-  auto ConcatMI1 =
-      dyn_cast<GConcatVectors>(MRI.getVRegDef(MI.getOperand(1).getReg()));
-  auto ConcatMI2 =
-      dyn_cast<GConcatVectors>(MRI.getVRegDef(MI.getOperand(2).getReg()));
-  if (!ConcatMI1 || !ConcatMI2)
+  GConcatVectors *ConcatMI1, *ConcatMI2;
+  if (!mi_match(MI.getOperand(1).getReg(), MRI, m_GConcatVectors(ConcatMI1)) ||
+      !mi_match(MI.getOperand(2).getReg(), MRI, m_GConcatVectors(ConcatMI2)))
     return false;
 
   // Check that the sources of the Concat instructions have the same type
@@ -1285,7 +1286,9 @@ bool CombinerHelper::findPostIndexCandidate(GLoadStore &LdSt, Register &Addr,
     return false;
 
   MachineInstr *StoredValDef = getDefIgnoringCopies(LdSt.getReg(0), MRI);
-  auto *PtrDef = MRI.getVRegDef(Ptr);
+  MachineInstr *PtrDef;
+  if (!mi_match(Ptr, MRI, m_MInstr(PtrDef)))
+    return false;
 
   unsigned NumUsesChecked = 0;
   for (auto &Use : MRI.use_nodbg_instructions(Ptr)) {
@@ -1310,7 +1313,9 @@ bool CombinerHelper::findPostIndexCandidate(GLoadStore &LdSt, Register &Addr,
       continue;
 
     // Make sure the offset calculation is before the potentially indexed op.
-    MachineInstr *OffsetDef = MRI.getVRegDef(Offset);
+    MachineInstr *OffsetDef;
+    if (!mi_match(Offset, MRI, m_MInstr(OffsetDef)))
+      continue;
     RematOffset = false;
     if (!dominates(*OffsetDef, LdSt)) {
       // If the offset however is just a G_CONSTANT, we can always just
@@ -1540,7 +1545,7 @@ bool CombinerHelper::matchCombineIndexedLoadStore(
 
 void CombinerHelper::applyCombineIndexedLoadStore(
     MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo) const {
-  MachineInstr &AddrDef = *MRI.getUniqueVRegDef(MatchInfo.Addr);
+  MachineInstr &AddrDef = *MRI.getVRegDef(MatchInfo.Addr);
   unsigned Opcode = MI.getOpcode();
   bool IsStore = Opcode == TargetOpcode::G_STORE;
   unsigned NewOpcode = getIndexedOpc(Opcode);
@@ -1946,8 +1951,8 @@ bool CombinerHelper::matchShiftImmedChain(MachineInstr &MI,
   if (!MaybeImmVal)
     return false;
 
-  MachineInstr *Shl2Def = MRI.getUniqueVRegDef(Shl2);
-  if (Shl2Def->getOpcode() != Opcode)
+  MachineInstr *Shl2Def;
+  if (!mi_match(Shl2, MRI, m_MInstr(Shl2Def)) || Shl2Def->getOpcode() != Opcode)
     return false;
 
   Register Base = Shl2Def->getOperand(1).getReg();
@@ -2027,7 +2032,9 @@ bool CombinerHelper::matchShiftOfShiftedLogic(
   if (!MRI.hasOneNonDBGUse(LogicDest))
     return false;
 
-  MachineInstr *LogicMI = MRI.getUniqueVRegDef(LogicDest);
+  MachineInstr *LogicMI;
+  if (!mi_match(LogicDest, MRI, m_MInstr(LogicMI)))
+    return false;
   unsigned LogicOpcode = LogicMI->getOpcode();
   if (LogicOpcode != TargetOpcode::G_AND && LogicOpcode != TargetOpcode::G_OR &&
       LogicOpcode != TargetOpcode::G_XOR)
@@ -2059,9 +2066,12 @@ bool CombinerHelper::matchShiftOfShiftedLogic(
 
   // Logic ops are commutative, so check each operand for a match.
   Register LogicMIReg1 = LogicMI->getOperand(1).getReg();
-  MachineInstr *LogicMIOp1 = MRI.getUniqueVRegDef(LogicMIReg1);
+  MachineInstr *LogicMIOp1;
   Register LogicMIReg2 = LogicMI->getOperand(2).getReg();
-  MachineInstr *LogicMIOp2 = MRI.getUniqueVRegDef(LogicMIReg2);
+  MachineInstr *LogicMIOp2;
+  if (!mi_match(LogicMIReg1, MRI, m_MInstr(LogicMIOp1)) ||
+      !mi_match(LogicMIReg2, MRI, m_MInstr(LogicMIOp2)))
+    return false;
   uint64_t C0Val;
 
   if (matchFirstShift(LogicMIOp1, C0Val)) {
@@ -2136,9 +2146,11 @@ bool CombinerHelper::matchCommuteShift(MachineInstr &MI,
   if (!getTargetLowering().isDesirableToCommuteWithShift(MI, !isPreLegalize()))
     return false;
 
+  MachineInstr *SrcDef;
   if (!mi_match(SrcReg, MRI,
                 m_OneNonDBGUse(m_any_of(m_GAdd(m_Reg(X), m_Reg(C1)),
-                                        m_GOr(m_Reg(X), m_Reg(C1))))))
+                                        m_GOr(m_Reg(X), m_Reg(C1))))) ||
+      !mi_match(SrcReg, MRI, m_MInstr(SrcDef)))
     return false;
 
   APInt C1Val, C2Val;
@@ -2146,14 +2158,12 @@ bool CombinerHelper::matchCommuteShift(MachineInstr &MI,
       !mi_match(ShiftReg, MRI, m_ICstOrSplat(C2Val)))
     return false;
 
-  auto *SrcDef = MRI.getVRegDef(SrcReg);
-  assert((SrcDef->getOpcode() == TargetOpcode::G_ADD ||
-          SrcDef->getOpcode() == TargetOpcode::G_OR) && "Unexpected op");
+  unsigned SrcOpc = SrcDef->getOpcode();
   LLT SrcTy = MRI.getType(SrcReg);
   MatchInfo = [=](MachineIRBuilder &B) {
     auto S1 = B.buildShl(SrcTy, X, ShiftReg);
     auto S2 = B.buildShl(SrcTy, C1, ShiftReg);
-    B.buildInstr(SrcDef->getOpcode(), {DstReg}, {S1, S2});
+    B.buildInstr(SrcOpc, {DstReg}, {S1, S2});
   };
   return true;
 }
@@ -2412,15 +2422,10 @@ bool CombinerHelper::matchCombineUnmergeConstant(
     MachineInstr &MI, SmallVectorImpl<APInt> &Csts) const {
   unsigned SrcIdx = MI.getNumOperands() - 1;
   Register SrcReg = MI.getOperand(SrcIdx).getReg();
-  MachineInstr *SrcInstr = MRI.getVRegDef(SrcReg);
-  if (SrcInstr->getOpcode() != TargetOpcode::G_CONSTANT &&
-      SrcInstr->getOpcode() != TargetOpcode::G_FCONSTANT)
-    return false;
   // Break down the big constant in smaller ones.
-  const MachineOperand &CstVal = SrcInstr->getOperand(1);
-  APInt Val = SrcInstr->getOpcode() == TargetOpcode::G_CONSTANT
-                  ? CstVal.getCImm()->getValue()
-                  : CstVal.getFPImm()->getValueAPF().bitcastToAPInt();
+  APInt Val;
+  if (!mi_match(SrcReg, MRI, m_GConstantOrFConstantBits(Val)))
+    return false;
 
   LLT Dst0Ty = MRI.getType(MI.getOperand(0).getReg());
   unsigned ShiftAmt = Dst0Ty.getSizeInBits();
@@ -2518,12 +2523,9 @@ void CombinerHelper::applyCombineUnmergeZExtToZExt(MachineInstr &MI) const {
 
   Register Dst0Reg = MI.getOperand(0).getReg();
 
-  MachineInstr *ZExtInstr =
-      MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg());
-  assert(ZExtInstr && ZExtInstr->getOpcode() == TargetOpcode::G_ZEXT &&
-         "Expecting a G_ZEXT");
-
-  Register ZExtSrcReg = ZExtInstr->getOperand(1).getReg();
+  GZext *ZExtInstr =
+      cast<GZext>(MRI.getVRegDef(MI.getOperand(MI.getNumDefs()).getReg()));
+  Register ZExtSrcReg = ZExtInstr->getSrcReg();
   LLT Dst0Ty = MRI.getType(Dst0Reg);
   LLT ZExtSrcTy = MRI.getType(ZExtSrcReg);
 
@@ -3282,8 +3284,8 @@ bool CombinerHelper::matchBinopWithNegInner(Register MInner, Register Other,
                                             BuildFnTy &MatchInfo) const {
   /// Helper function for matchBinopWithNeg: tries to match one commuted form
   /// of `a bitwiseop (~b +/- c)` -> `a bitwiseop ~(b -/+ c)`.
-  MachineInstr *InnerDef = MRI.getVRegDef(MInner);
-  if (!InnerDef)
+  MachineInstr *InnerDef;
+  if (!mi_match(MInner, MRI, m_MInstr(InnerDef)))
     return false;
 
   unsigned InnerOpc = InnerDef->getOpcode();
@@ -3750,49 +3752,41 @@ bool CombinerHelper::matchUseVectorTruncate(MachineInstr &MI,
 
   // Check the G_BUILD_VECTOR sources
   unsigned I;
-  MachineInstr *UnmergeMI = nullptr;
+  GUnmerge *UnmergeMI = nullptr;
 
   // Check all source TRUNCs come from the same UNMERGE instruction
   // and that the element order matches (BUILD_VECTOR position I
   // corresponds to UNMERGE result I)
   for (I = 0; I < NumOperands; ++I) {
-    auto SrcMI = MRI.getVRegDef(BuildMI->getSourceReg(I));
-    auto SrcMIOpc = SrcMI->getOpcode();
-
     // Check if the G_TRUNC instructions all come from the same MI
-    if (SrcMIOpc == TargetOpcode::G_TRUNC) {
-      Register TruncSrcReg = SrcMI->getOperand(1).getReg();
-      if (!UnmergeMI) {
-        UnmergeMI = MRI.getVRegDef(TruncSrcReg);
-        if (UnmergeMI->getOpcode() != TargetOpcode::G_UNMERGE_VALUES)
-          return false;
-      } else {
-        auto UnmergeSrcMI = MRI.getVRegDef(TruncSrcReg);
-        if (UnmergeMI != UnmergeSrcMI)
-          return false;
-      }
-      // Verify element ordering: BUILD_VECTOR position I must use
-      // UNMERGE result I, otherwise the fold would lose element reordering
-      if (UnmergeMI->getOperand(I).getReg() != TruncSrcReg)
+    Register TruncSrcReg;
+    if (!mi_match(BuildMI->getSourceReg(I), MRI, m_GTrunc(m_Reg(TruncSrcReg))))
+      break;
+
+    if (!UnmergeMI) {
+      if (!mi_match(TruncSrcReg, MRI, m_GUnmerge(UnmergeMI)))
         return false;
     } else {
-      break;
+      MachineInstr *UnmergeSrcMI;
+      if (!mi_match(TruncSrcReg, MRI, m_MInstr(UnmergeSrcMI)) ||
+          UnmergeMI != UnmergeSrcMI)
+        return false;
     }
+    // Element order must match: position I must use UNMERGE result I.
+    if (UnmergeMI->getOperand(I).getReg() != TruncSrcReg)
+      return false;
   }
   if (I < 2)
     return false;
 
   // Check the remaining source elements are only G_IMPLICIT_DEF
   for (; I < NumOperands; ++I) {
-    auto SrcMI = MRI.getVRegDef(BuildMI->getSourceReg(I));
-    auto SrcMIOpc = SrcMI->getOpcode();
-
-    if (SrcMIOpc != TargetOpcode::G_IMPLICIT_DEF)
+    if (!mi_match(BuildMI->getSourceReg(I), MRI, m_GImplicitDef()))
       return false;
   }
 
   // Check the size of unmerge source
-  MatchInfo = cast<GUnmerge>(UnmergeMI)->getSourceReg();
+  MatchInfo = UnmergeMI->getSourceReg();
   LLT UnmergeSrcTy = MRI.getType(MatchInfo);
   if (!DstTy.getElementCount().isKnownMultipleOf(UnmergeSrcTy.getNumElements()))
     return false;
@@ -3872,7 +3866,9 @@ bool CombinerHelper::matchNotCmp(
     Register Reg = RegsToNegate[I];
     if (!MRI.hasOneNonDBGUse(Reg))
       return false;
-    MachineInstr *Def = MRI.getVRegDef(Reg);
+    MachineInstr *Def;
+    if (!mi_match(Reg, MRI, m_MInstr(Def)))
+      return false;
     switch (Def->getOpcode()) {
     default:
       // Don't match if the tree contains anything other than ANDs, ORs and
@@ -3907,11 +3903,10 @@ bool CombinerHelper::matchNotCmp(
   // the constant in the xor.
   int64_t Cst;
   if (Ty.isVector()) {
-    MachineInstr *CstDef = MRI.getVRegDef(CstReg);
-    auto MaybeCst = getIConstantSplatSExtVal(*CstDef, MRI);
-    if (!MaybeCst)
+    int64_t SplatCst;
+    if (!mi_match(CstReg, MRI, m_ICstOrSplat(SplatCst)))
       return false;
-    if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), *MaybeCst, true, IsFP))
+    if (!isConstValidTrue(TLI, Ty.getScalarSizeInBits(), SplatCst, true, IsFP))
       return false;
   } else {
     if (!mi_match(CstReg, MRI, m_ICst(Cst)))
@@ -4014,7 +4009,9 @@ bool CombinerHelper::matchPtrAddZero(MachineInstr &MI) const {
   }
 
   assert(Ty.isVector() && "Expecting a vector type");
-  const MachineInstr *VecMI = MRI.getVRegDef(PtrAdd.getBaseReg());
+  const MachineInstr *VecMI;
+  if (!mi_match(PtrAdd.getBaseReg(), MRI, m_MInstr(VecMI)))
+    return false;
   return isBuildVectorAllZeros(*VecMI, MRI);
 }
 
@@ -4045,22 +4042,25 @@ bool CombinerHelper::matchFoldBinOpIntoSelect(MachineInstr &MI,
 
   Register OtherOperandReg = RHS;
   SelectOpNo = 1;
-  MachineInstr *Select = MRI.getVRegDef(LHS);
+  Register SelectTrue, SelectFalse;
 
   // Don't do this unless the old select is going away. We want to eliminate the
   // binary operator, not replace a binop with a select.
-  if (Select->getOpcode() != TargetOpcode::G_SELECT ||
+  if (!mi_match(LHS, MRI,
+                m_GISelect(m_Reg(), m_Reg(SelectTrue), m_Reg(SelectFalse))) ||
       !MRI.hasOneNonDBGUse(LHS)) {
     OtherOperandReg = LHS;
     SelectOpNo = 2;
-    Select = MRI.getVRegDef(RHS);
-    if (Select->getOpcode() != TargetOpcode::G_SELECT ||
+    if (!mi_match(RHS, MRI,
+                  m_GISelect(m_Reg(), m_Reg(SelectTrue), m_Reg(SelectFalse))) ||
         !MRI.hasOneNonDBGUse(RHS))
       return false;
   }
 
-  MachineInstr *SelectLHS = MRI.getVRegDef(Select->getOperand(2).getReg());
-  MachineInstr *SelectRHS = MRI.getVRegDef(Select->getOperand(3).getReg());
+  MachineInstr *SelectLHS, *SelectRHS;
+  if (!mi_match(SelectTrue, MRI, m_MInstr(SelectLHS)) ||
+      !mi_match(SelectFalse, MRI, m_MInstr(SelectRHS)))
+    return false;
 
   if (!isConstantOrConstantVector(*SelectLHS, MRI,
                                   /*AllowFP*/ true,
@@ -4085,7 +4085,10 @@ bool CombinerHelper::matchFoldBinOpIntoSelect(MachineInstr &MI,
   if (CanFoldNonConst)
     return true;
 
-  return isConstantOrConstantVector(*MRI.getVRegDef(OtherOperandReg), MRI,
+  MachineInstr *OtherOperandDef;
+  if (!mi_match(OtherOperandReg, MRI, m_MInstr(OtherOperandDef)))
+    return false;
+  return isConstantOrConstantVector(*OtherOperandDef, MRI,
                                     /*AllowFP*/ true,
                                     /*AllowOpaqueConstants*/ false);
 }
@@ -4097,11 +4100,12 @@ void CombinerHelper::applyFoldBinOpIntoSelect(
   Register Dst = MI.getOperand(0).getReg();
   Register LHS = MI.getOperand(1).getReg();
   Register RHS = MI.getOperand(2).getReg();
-  MachineInstr *Select = MRI.getVRegDef(MI.getOperand(SelectOperand).getReg());
+  GSelect *Select =
+      cast<GSelect>(MRI.getVRegDef(MI.getOperand(SelectOperand).getReg()));
 
-  Register SelectCond = Select->getOperand(1).getReg();
-  Register SelectTrue = Select->getOperand(2).getReg();
-  Register SelectFalse = Select->getOperand(3).getReg();
+  Register SelectCond = Select->getCondReg();
+  Register SelectTrue = Select->getTrueReg();
+  Register SelectFalse = Select->getFalseReg();
 
   LLT Ty = MRI.getType(Dst);
   unsigned BinOpcode = MI.getOpcode();
@@ -4542,7 +4546,9 @@ void CombinerHelper::applyExtendThroughPhis(MachineInstr &MI,
   SmallDenseMap<MachineInstr *, MachineInstr *, 8> OldToNewSrcMap;
   for (unsigned I = 0; I < PHI.getNumIncomingValues(); ++I) {
     auto SrcReg = PHI.getIncomingValue(I);
-    auto *SrcMI = MRI.getVRegDef(SrcReg);
+    MachineInstr *SrcMI;
+    if (!mi_match(SrcReg, MRI, m_MInstr(SrcMI)))
+      continue;
     if (!SrcMIs.insert(SrcMI))
       continue;
 
@@ -4592,10 +4598,13 @@ bool CombinerHelper::matchExtractVecEltBuildVec(MachineInstr &MI,
 
   // Check if we have a build_vector or build_vector_trunc with an optional
   // trunc in front.
-  MachineInstr *SrcVecMI = MRI.getVRegDef(SrcVec);
-  if (SrcVecMI->getOpcode() == TargetOpcode::G_TRUNC) {
-    SrcVecMI = MRI.getVRegDef(SrcVecMI->getOperand(1).getReg());
-  }
+  MachineInstr *SrcVecMI;
+  Register TruncSrc;
+  if (mi_match(SrcVec, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
+    if (!mi_match(TruncSrc, MRI, m_MInstr(SrcVecMI)))
+      return false;
+  } else if (!mi_match(SrcVec, MRI, m_MInstr(SrcVecMI)))
+    return false;
 
   if (SrcVecMI->getOpcode() != TargetOpcode::G_BUILD_VECTOR &&
       SrcVecMI->getOpcode() != TargetOpcode::G_BUILD_VECTOR_TRUNC)
@@ -5322,8 +5331,10 @@ bool CombinerHelper::matchReassocPtrAdd(MachineInstr &MI,
   // 3) Move a constant from the LHS of an inner op to the RHS of the outer.
   // G_PTR_ADD (G_PTR_ADD X, C), Y) -> G_PTR_ADD (G_PTR_ADD(X, Y), C)
   // iif (G_PTR_ADD X, C) has one use.
-  MachineInstr *LHS = MRI.getVRegDef(PtrAdd.getBaseReg());
-  MachineInstr *RHS = MRI.getVRegDef(PtrAdd.getOffsetReg());
+  MachineInstr *LHS, *RHS;
+  if (!mi_match(PtrAdd.getBaseReg(), MRI, m_MInstr(LHS)) ||
+      !mi_match(PtrAdd.getOffsetReg(), MRI, m_MInstr(RHS)))
+    return false;
 
   // Try to match example 2.
   if (matchReassocFoldConstantsInSubTree(PtrAdd, LHS, RHS, MatchInfo))
@@ -5343,9 +5354,8 @@ bool CombinerHelper::tryReassocBinOp(unsigned Opc, Register DstReg,
                                      Register OpLHS, Register OpRHS,
                                      BuildFnTy &MatchInfo) const {
   LLT OpRHSTy = MRI.getType(OpRHS);
-  MachineInstr *OpLHSDef = MRI.getVRegDef(OpLHS);
-
-  if (OpLHSDef->getOpcode() != Opc)
+  MachineInstr *OpLHSDef;
+  if (!mi_match(OpLHS, MRI, m_MInstr(OpLHSDef)) || OpLHSDef->getOpcode() != Opc)
     return false;
 
   Register OpLHSLHS = OpLHSDef->getOperand(1).getReg();
@@ -5875,8 +5885,9 @@ bool CombinerHelper::matchUDivOrURemByConst(MachineInstr &MI) const {
         MRI, RHS, [](const Constant *C) { return C && !C->isNullValue(); });
   }
 
-  auto *RHSDef = MRI.getVRegDef(RHS);
-  if (!isConstantOrConstantVector(*RHSDef, MRI))
+  MachineInstr *RHSDef;
+  if (!mi_match(RHS, MRI, m_MInstr(RHSDef)) ||
+      !isConstantOrConstantVector(*RHSDef, MRI))
     return false;
 
   // Don't do this if the types are not going to be legal.
@@ -5933,8 +5944,9 @@ bool CombinerHelper::matchSDivOrSRemByConst(MachineInstr &MI) const {
         MRI, RHS, [](const Constant *C) { return C && !C->isNullValue(); });
   }
 
-  auto *RHSDef = MRI.getVRegDef(RHS);
-  if (!isConstantOrConstantVector(*RHSDef, MRI))
+  MachineInstr *RHSDef;
+  if (!mi_match(RHS, MRI, m_MInstr(RHSDef)) ||
+      !isConstantOrConstantVector(*RHSDef, MRI))
     return false;
 
   // Don't do this if the types are not going to be legal.
@@ -6494,8 +6506,12 @@ bool CombinerHelper::matchCombineFAddFMulToFMadOrFMA(
 
   Register Op1 = MI.getOperand(1).getReg();
   Register Op2 = MI.getOperand(2).getReg();
-  DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
-  DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+  MachineInstr *Op1Def, *Op2Def;
+  if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+      !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+    return false;
+  DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+  DefinitionAndSourceRegister RHS = {Op2Def, Op2};
   unsigned PreferredFusedOpcode =
       HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
 
@@ -6548,8 +6564,12 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMA(
   const auto &TLI = *MI.getMF()->getSubtarget().getTargetLowering();
   Register Op1 = MI.getOperand(1).getReg();
   Register Op2 = MI.getOperand(2).getReg();
-  DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
-  DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+  MachineInstr *Op1Def, *Op2Def;
+  if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+      !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+    return false;
+  DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+  DefinitionAndSourceRegister RHS = {Op2Def, Op2};
   LLT DstType = MRI.getType(MI.getOperand(0).getReg());
 
   unsigned PreferredFusedOpcode =
@@ -6609,8 +6629,12 @@ bool CombinerHelper::matchCombineFAddFMAFMulToFMadOrFMA(
 
   Register Op1 = MI.getOperand(1).getReg();
   Register Op2 = MI.getOperand(2).getReg();
-  DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
-  DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+  MachineInstr *Op1Def, *Op2Def;
+  if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+      !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+    return false;
+  DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+  DefinitionAndSourceRegister RHS = {Op2Def, Op2};
   LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
 
   unsigned PreferredFusedOpcode =
@@ -6646,7 +6670,9 @@ bool CombinerHelper::matchCombineFAddFMAFMulToFMadOrFMA(
   }
 
   if (FMA) {
-    MachineInstr *FMulMI = MRI.getVRegDef(FMA->getOperand(3).getReg());
+    MachineInstr *FMulMI;
+    if (!mi_match(FMA->getOperand(3).getReg(), MRI, m_MInstr(FMulMI)))
+      return false;
     Register X = FMA->getOperand(1).getReg();
     Register Y = FMA->getOperand(2).getReg();
     Register U = FMulMI->getOperand(1).getReg();
@@ -6682,8 +6708,12 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
   LLT DstType = MRI.getType(MI.getOperand(0).getReg());
   Register Op1 = MI.getOperand(1).getReg();
   Register Op2 = MI.getOperand(2).getReg();
-  DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
-  DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+  MachineInstr *Op1Def, *Op2Def;
+  if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+      !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+    return false;
+  DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+  DefinitionAndSourceRegister RHS = {Op2Def, Op2};
 
   unsigned PreferredFusedOpcode =
       HasFMAD ? TargetOpcode::G_FMAD : TargetOpcode::G_FMA;
@@ -6736,7 +6766,9 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
   // interesting for all targets, especially GPUs.
   if (mi_match(LHS.Reg, MRI, m_GFPExt(m_MInstr(FMAMI))) &&
       FMAMI->getOpcode() == PreferredFusedOpcode) {
-    MachineInstr *FMulMI = MRI.getVRegDef(FMAMI->getOperand(3).getReg());
+    MachineInstr *FMulMI;
+    if (!mi_match(FMAMI->getOperand(3).getReg(), MRI, m_MInstr(FMulMI)))
+      return false;
     if (isContractableFMul(*FMulMI, AllowFusionGlobally) &&
         TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
                             MRI.getType(FMAMI->getOperand(0).getReg()))) {
@@ -6782,7 +6814,9 @@ bool CombinerHelper::matchCombineFAddFpExtFMulToFMadOrFMAAggressive(
   // interesting for all targets, especially GPUs.
   if (mi_match(RHS.Reg, MRI, m_GFPExt(m_MInstr(FMAMI))) &&
       FMAMI->getOpcode() == PreferredFusedOpcode) {
-    MachineInstr *FMulMI = MRI.getVRegDef(FMAMI->getOperand(3).getReg());
+    MachineInstr *FMulMI;
+    if (!mi_match(FMAMI->getOperand(3).getReg(), MRI, m_MInstr(FMulMI)))
+      return false;
     if (isContractableFMul(*FMulMI, AllowFusionGlobally) &&
         TLI.isFPExtFoldable(MI, PreferredFusedOpcode, DstType,
                             MRI.getType(FMAMI->getOperand(0).getReg()))) {
@@ -6815,8 +6849,12 @@ bool CombinerHelper::matchCombineFSubFMulToFMadOrFMA(
 
   Register Op1 = MI.getOperand(1).getReg();
   Register Op2 = MI.getOperand(2).getReg();
-  DefinitionAndSourceRegister LHS = {MRI.getVRegDef(Op1), Op1};
-  DefinitionAndSourceRegister RHS = {MRI.getVRegDef(Op2), Op2};
+  MachineInstr *Op1Def, *Op2Def;
+  if (!mi_match(Op1, MRI, m_MInstr(Op1Def)) ||
+      !mi_match(Op2, MRI, m_MInstr(Op2Def)))
+    return false;
+  DefinitionAndSourceRegister LHS = {Op1Def, Op1};
+  DefinitionAndSourceRegister RHS = {Op2Def, Op2};
   LLT DstTy = MRI.getType(MI.getOperand(0).getReg());
 
   // If we have two choices trying to fold (fadd (fmul u, v), (fmul x, y)),
@@ -7450,17 +7488,20 @@ bool CombinerHelper::matchCommuteConstantToRHS(MachineInstr &MI) const {
   }
   Register LHS = MI.getOperand(LHSOpndIdx).getReg();
   Register RHS = MI.getOperand(RHSOpndIdx).getReg();
+  MachineInstr *LHSDef, *RHSDef;
+  if (!mi_match(LHS, MRI, m_MInstr(LHSDef)) ||
+      !mi_match(RHS, MRI, m_MInstr(RHSDef)))
+    return false;
+
   if (!getIConstantVRegVal(LHS, MRI)) {
     // Skip commuting if LHS is not a constant. But, LHS may be a
     // G_CONSTANT_FOLD_BARRIER. If so we commute as long as we don't already
     // have a constant on the RHS.
-    if (MRI.getVRegDef(LHS)->getOpcode() !=
-        TargetOpcode::G_CONSTANT_FOLD_BARRIER)
+    if (LHSDef->getOpcode() != TargetOpcode::G_CONSTANT_FOLD_BARRIER)
       return false;
   }
   // Commute as long as RHS is not a constant or G_CONSTANT_FOLD_BARRIER.
-  return MRI.getVRegDef(RHS)->getOpcode() !=
-             TargetOpcode::G_CONSTANT_FOLD_BARRIER &&
+  return RHSDef->getOpcode() != TargetOpcode::G_CONSTANT_FOLD_BARRIER &&
          !getIConstantVRegVal(RHS, MRI);
 }
 
@@ -7826,30 +7867,31 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
 
 bool CombinerHelper::matchSelectIMinMax(const MachineOperand &MO,
                                         BuildFnTy &MatchInfo) const {
-  GSelect *Select = cast<GSelect>(MRI.getVRegDef(MO.getReg()));
-  GICmp *Cmp = cast<GICmp>(MRI.getVRegDef(Select->getCondReg()));
+  Register DstReg = MO.getReg();
+  Register CondReg, True, False;
+  if (!mi_match(DstReg, MRI,
+                m_GISelect(m_Reg(CondReg), m_Reg(True), m_Reg(False))))
+    return false;
 
-  Register DstReg = Select->getReg(0);
-  Register True = Select->getTrueReg();
-  Register False = Select->getFalseReg();
-  LLT DstTy = MRI.getType(DstReg);
+  CmpInst::Predicate Pred;
+  Register CmpLHS, CmpRHS;
+  if (!mi_match(CondReg, MRI,
+                m_GICmp(m_Pred(Pred), m_Reg(CmpLHS), m_Reg(CmpRHS))))
+    return false;
 
+  LLT DstTy = MRI.getType(DstReg);
   if (DstTy.isPointerOrPointerVector())
     return false;
 
   // We want to fold the icmp and replace the select.
-  if (!MRI.hasOneNonDBGUse(Cmp->getReg(0)))
+  if (!MRI.hasOneNonDBGUse(CondReg))
     return false;
 
-  CmpInst::Predicate Pred = Cmp->getCond();
   // We need a larger or smaller predicate for
   // canonicalization.
   if (CmpInst::isEquality(Pred))
     return false;
 
-  Register CmpLHS = Cmp->getLHSReg();
-  Register CmpRHS = Cmp->getRHSReg();
-
   // We can swap CmpLHS and CmpRHS for higher hitrate.
   if (True == CmpRHS && False == CmpLHS) {
     std::swap(CmpLHS, CmpRHS);
@@ -7911,7 +7953,9 @@ bool CombinerHelper::matchSimplifyNegMinMax(MachineInstr &MI,
                                        m_GSMax(m_Reg(X), NegPattern),
                                        m_GUMin(m_Reg(X), NegPattern),
                                        m_GUMax(m_Reg(X), NegPattern)))))) {
-    MachineInstr *MinMaxMI = MRI.getVRegDef(MI.getOperand(2).getReg());
+    MachineInstr *MinMaxMI;
+    if (!mi_match(MI.getOperand(2).getReg(), MRI, m_MInstr(MinMaxMI)))
+      return false;
     unsigned NewOpc = getInverseGMinMaxOpcode(MinMaxMI->getOpcode());
     if (isLegal({NewOpc, {DestTy}})) {
       MatchInfo = [=](MachineIRBuilder &B) {
@@ -8427,20 +8471,22 @@ bool CombinerHelper::matchFoldAPlusC1MinusC2(const MachineInstr &MI,
                                              BuildFnTy &MatchInfo) const {
   // fold (A+C1)-C2 -> A+(C1-C2)
   const GSub *Sub = cast<GSub>(&MI);
-  GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getLHSReg()));
+  Register A, C1Reg;
+  if (!mi_match(Sub->getLHSReg(), MRI, m_GAdd(m_Reg(A), m_Reg(C1Reg))))
+    return false;
 
-  if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+  if (!MRI.hasOneNonDBGUse(Sub->getLHSReg()))
     return false;
 
   APInt C2 = getIConstantFromReg(Sub->getRHSReg(), MRI);
-  APInt C1 = getIConstantFromReg(Add->getRHSReg(), MRI);
+  APInt C1 = getIConstantFromReg(C1Reg, MRI);
 
   Register Dst = Sub->getReg(0);
   LLT DstTy = MRI.getType(Dst);
 
   MatchInfo = [=](MachineIRBuilder &B) {
     auto Const = B.buildConstant(DstTy, C1 - C2);
-    B.buildAdd(Dst, Add->getLHSReg(), Const);
+    B.buildAdd(Dst, A, Const);
   };
 
   return true;
@@ -8450,20 +8496,22 @@ bool CombinerHelper::matchFoldC2MinusAPlusC1(const MachineInstr &MI,
                                              BuildFnTy &MatchInfo) const {
   // fold C2-(A+C1) -> (C2-C1)-A
   const GSub *Sub = cast<GSub>(&MI);
-  GAdd *Add = cast<GAdd>(MRI.getVRegDef(Sub->getRHSReg()));
+  Register A, C1Reg;
+  if (!mi_match(Sub->getRHSReg(), MRI, m_GAdd(m_Reg(A), m_Reg(C1Reg))))
+    return false;
 
-  if (!MRI.hasOneNonDBGUse(Add->getReg(0)))
+  if (!MRI.hasOneNonDBGUse(Sub->getRHSReg()))
     return false;
 
   APInt C2 = getIConstantFromReg(Sub->getLHSReg(), MRI);
-  APInt C1 = getIConstantFromReg(Add->getRHSReg(), MRI);
+  APInt C1 = getIConstantFromReg(C1Reg, MRI);
 
   Register Dst = Sub->getReg(0);
   LLT DstTy = MRI.getType(Dst);
 
   MatchInfo = [=](MachineIRBuilder &B) {
     auto Const = B.buildConstant(DstTy, C2 - C1);
-    B.buildSub(Dst, Const, Add->getLHSReg());
+    B.buildSub(Dst, Const, A);
   };
 
   return true;
@@ -8473,20 +8521,22 @@ bool CombinerHelper::matchFoldAMinusC1MinusC2(const MachineInstr &MI,
                                               BuildFnTy &MatchInfo) const {
   // fold (A-C1)-C2 -> A-(C1+C2)
   const GSub *Sub1 = cast<GSub>(&MI);
-  GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+  Register A, C1Reg;
+  if (!mi_match(Sub1->getLHSReg(), MRI, m_GSub(m_Reg(A), m_Reg(C1Reg))))
+    return false;
 
-  if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+  if (!MRI.hasOneNonDBGUse(Sub1->getLHSReg()))
     return false;
 
   APInt C2 = getIConstantFromReg(Sub1->getRHSReg(), MRI);
-  APInt C1 = getIConstantFromReg(Sub2->getRHSReg(), MRI);
+  APInt C1 = getIConstantFromReg(C1Reg, MRI);
 
   Register Dst = Sub1->getReg(0);
   LLT DstTy = MRI.getType(Dst);
 
   MatchInfo = [=](MachineIRBuilder &B) {
     auto Const = B.buildConstant(DstTy, C1 + C2);
-    B.buildSub(Dst, Sub2->getLHSReg(), Const);
+    B.buildSub(Dst, A, Const);
   };
 
   return true;
@@ -8496,20 +8546,22 @@ bool CombinerHelper::matchFoldC1Minus2MinusC2(const MachineInstr &MI,
                                               BuildFnTy &MatchInfo) const {
   // fold (C1-A)-C2 -> (C1-C2)-A
   const GSub *Sub1 = cast<GSub>(&MI);
-  GSub *Sub2 = cast<GSub>(MRI.getVRegDef(Sub1->getLHSReg()));
+  Register C1Reg, A;
+  if (!mi_match(Sub1->getLHSReg(), MRI, m_GSub(m_Reg(C1Reg), m_Reg(A))))
+    return false;
 
-  if (!MRI.hasOneNonDBGUse(Sub2->getReg(0)))
+  if (!MRI.hasOneNonDBGUse(Sub1->getLHSReg()))
     return false;
 
   APInt C2 = getIConstantFromReg(Sub1->getRHSReg(), MRI);
-  APInt C1 = getIConstantFromReg(Sub2->getLHSReg(), MRI);
+  APInt C1 = getIConstantFromReg(C1Reg, MRI);
 
   Register Dst = Sub1->getReg(0);
   LLT DstTy = MRI.getType(Dst);
 
   MatchInfo = [=](MachineIRBuilder &B) {
     auto Const = B.buildConstant(DstTy, C1 - C2);
-    B.buildSub(Dst, Const, Sub2->getRHSReg());
+    B.buildSub(Dst, Const, A);
   };
 
   return true;
@@ -8519,20 +8571,22 @@ bool CombinerHelper::matchFoldAMinusC1PlusC2(const MachineInstr &MI,
                                              BuildFnTy &MatchInfo) const {
   // fold ((A-C1)+C2) -> (A+(C2-C1))
   const GAdd *Add = cast<GAdd>(&MI);
-  GSub *Sub = cast<GSub>(MRI.getVRegDef(Add->getLHSReg()));
+  Register A, C1Reg;
+  if (!mi_match(Add->getLHSReg(), MRI, m_GSub(m_Reg(A), m_Reg(C1Reg))))
+    return false;
 
-  if (!MRI.hasOneNonDBGUse(Sub->getReg(0)))
+  if (!MRI.hasOneNonDBGUse(Add->getLHSReg()))
     return false;
 
   APInt C2 = getIConstantFromReg(Add->getRHSReg(), MRI);
-  APInt C1 = getIConstantFromReg(Sub->getRHSReg(), MRI);
+  APInt C1 = getIConstantFromReg(C1Reg, MRI);
 
   Register Dst = Add->getReg(0);
   LLT DstTy = MRI.getType(Dst);
 
   MatchInfo = [=](MachineIRBuilder &B) {
     auto Const = B.buildConstant(DstTy, C2 - C1);
-    B.buildAdd(Dst, Sub->getLHSReg(), Const);
+    B.buildAdd(Dst, A, Const);
   };
 
   return true;
@@ -8545,8 +8599,6 @@ bool CombinerHelper::matchUnmergeValuesAnyExtBuildVector(
   if (!MRI.hasOneNonDBGUse(Unmerge->getSourceReg()))
     return false;
 
-  const MachineInstr *Source = MRI.getVRegDef(Unmerge->getSourceReg());
-
   LLT DstTy = MRI.getType(Unmerge->getReg(0));
 
   // $bv:_(<8 x s8>) = G_BUILD_VECTOR ....
@@ -8570,13 +8622,12 @@ bool CombinerHelper::matchUnmergeValuesAnyExtBuildVector(
   if (!DstTy.isFixedVector())
     return false;
 
-  const GAnyExt *Any = dyn_cast<GAnyExt>(Source);
-  if (!Any)
+  Register AnySrcReg;
+  if (!mi_match(Unmerge->getSourceReg(), MRI, m_GAnyExt(m_Reg(AnySrcReg))))
     return false;
 
-  const MachineInstr *NextSource = MRI.getVRegDef(Any->getSrcReg());
-
-  if (const GBuildVector *BV = dyn_cast<GBuildVector>(NextSource)) {
+  GBuildVector *BV;
+  if (mi_match(AnySrcReg, MRI, m_GBuildVector(BV))) {
     // G_UNMERGE_VALUES G_ANYEXT G_BUILD_VECTOR
 
     if (!MRI.hasOneNonDBGUse(BV->getReg(0)))
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
index 5e67029e68b56..a310cb8174f43 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperCasts.cpp
@@ -13,6 +13,7 @@
 #include "llvm/CodeGen/GlobalISel/CombinerHelper.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
+#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
 #include "llvm/CodeGen/GlobalISel/Utils.h"
 #include "llvm/CodeGen/LowLevelTypeUtils.h"
@@ -24,6 +25,7 @@
 #define DEBUG_TYPE "gi-combiner"
 
 using namespace llvm;
+using namespace MIPatternMatch;
 
 bool CombinerHelper::matchSextOfTrunc(const MachineOperand &MO,
                                       BuildFnTy &MatchInfo) const {
@@ -116,10 +118,10 @@ bool CombinerHelper::matchZextOfTrunc(const MachineOperand &MO,
 
 bool CombinerHelper::matchNonNegZext(const MachineOperand &MO,
                                      BuildFnTy &MatchInfo) const {
-  GZext *Zext = cast<GZext>(MRI.getVRegDef(MO.getReg()));
-
-  Register Dst = Zext->getReg(0);
-  Register Src = Zext->getSrcReg();
+  Register Dst = MO.getReg();
+  Register Src;
+  if (!mi_match(Dst, MRI, m_GZExt(m_Reg(Src))))
+    return false;
 
   LLT DstTy = MRI.getType(Dst);
   LLT SrcTy = MRI.getType(Src);
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
index 229076bbdeaa5..f657c6b49cbb4 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelperVectorOps.cpp
@@ -364,11 +364,10 @@ bool CombinerHelper::matchInsertVectorElementOOB(MachineInstr &MI,
 
 bool CombinerHelper::matchAddOfVScale(const MachineOperand &MO,
                                       BuildFnTy &MatchInfo) const {
-  GAdd *Add = cast<GAdd>(MRI.getVRegDef(MO.getReg()));
-  GVScale *LHSVScale = cast<GVScale>(MRI.getVRegDef(Add->getLHSReg()));
-  GVScale *RHSVScale = cast<GVScale>(MRI.getVRegDef(Add->getRHSReg()));
-
-  Register Dst = Add->getReg(0);
+  Register Dst = MO.getReg();
+  GVScale *LHSVScale, *RHSVScale;
+  if (!mi_match(Dst, MRI, m_GAdd(m_GVScale(LHSVScale), m_GVScale(RHSVScale))))
+    return false;
 
   if (!MRI.hasOneNonDBGUse(LHSVScale->getReg(0)) ||
       !MRI.hasOneNonDBGUse(RHSVScale->getReg(0)))
@@ -383,15 +382,16 @@ bool CombinerHelper::matchAddOfVScale(const MachineOperand &MO,
 
 bool CombinerHelper::matchMulOfVScale(const MachineOperand &MO,
                                       BuildFnTy &MatchInfo) const {
-  GMul *Mul = cast<GMul>(MRI.getVRegDef(MO.getReg()));
-  GVScale *LHSVScale = cast<GVScale>(MRI.getVRegDef(Mul->getLHSReg()));
+  Register Dst = MO.getReg();
+  GVScale *LHSVScale;
+  Register RHSReg;
+  if (!mi_match(Dst, MRI, m_GMul(m_GVScale(LHSVScale), m_Reg(RHSReg))))
+    return false;
 
-  std::optional<APInt> MaybeRHS = getIConstantVRegVal(Mul->getRHSReg(), MRI);
+  std::optional<APInt> MaybeRHS = getIConstantVRegVal(RHSReg, MRI);
   if (!MaybeRHS)
     return false;
 
-  Register Dst = MO.getReg();
-
   if (!MRI.hasOneNonDBGUse(LHSVScale->getReg(0)))
     return false;
 
@@ -404,10 +404,14 @@ bool CombinerHelper::matchMulOfVScale(const MachineOperand &MO,
 
 bool CombinerHelper::matchSubOfVScale(const MachineOperand &MO,
                                       BuildFnTy &MatchInfo) const {
-  GSub *Sub = cast<GSub>(MRI.getVRegDef(MO.getReg()));
-  GVScale *RHSVScale = cast<GVScale>(MRI.getVRegDef(Sub->getRHSReg()));
-
   Register Dst = MO.getReg();
+  Register SubLHS;
+  GVScale *RHSVScale;
+  uint32_t Flags;
+  if (!mi_match(Dst, MRI,
+                m_GSub(m_Reg(SubLHS), m_GVScale(RHSVScale), m_MIFlags(Flags))))
+    return false;
+
   LLT DstTy = MRI.getType(Dst);
 
   if (!MRI.hasOneNonDBGUse(RHSVScale->getReg(0)) ||
@@ -416,7 +420,7 @@ bool CombinerHelper::matchSubOfVScale(const MachineOperand &MO,
 
   MatchInfo = [=](MachineIRBuilder &B) {
     auto VScale = B.buildVScale(DstTy, -RHSVScale->getSrc());
-    B.buildAdd(Dst, Sub->getLHSReg(), VScale, Sub->getFlags());
+    B.buildAdd(Dst, SubLHS, VScale, Flags);
   };
 
   return true;
@@ -424,14 +428,16 @@ bool CombinerHelper::matchSubOfVScale(const MachineOperand &MO,
 
 bool CombinerHelper::matchShlOfVScale(const MachineOperand &MO,
                                       BuildFnTy &MatchInfo) const {
-  GShl *Shl = cast<GShl>(MRI.getVRegDef(MO.getReg()));
-  GVScale *LHSVScale = cast<GVScale>(MRI.getVRegDef(Shl->getSrcReg()));
+  Register Dst = MO.getReg();
+  GVScale *LHSVScale;
+  Register ShiftReg;
+  if (!mi_match(Dst, MRI, m_GShl(m_GVScale(LHSVScale), m_Reg(ShiftReg))))
+    return false;
 
-  std::optional<APInt> MaybeRHS = getIConstantVRegVal(Shl->getShiftReg(), MRI);
+  std::optional<APInt> MaybeRHS = getIConstantVRegVal(ShiftReg, MRI);
   if (!MaybeRHS)
     return false;
 
-  Register Dst = MO.getReg();
   LLT DstTy = MRI.getType(Dst);
 
   if (!MRI.hasOneNonDBGUse(LHSVScale->getReg(0)) ||



More information about the llvm-commits mailing list