[llvm] [CodeGen][MRI] Add allocation mask for register classes (PR #86007)

Christudasan Devadasan via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 20 14:14:12 PDT 2024


https://github.com/cdevadas created https://github.com/llvm/llvm-project/pull/86007

Some targets can have register classes with identical sets
of registers. However, their actual allocation order can vary.
The allocation mask computed based on target constraints
would help achieve this during register allocation.

>From a5bb710e7899ae06e195618ad0aa459b9d35bf57 Mon Sep 17 00:00:00 2001
From: Christudasan Devadasan <Christudasan.Devadasan at amd.com>
Date: Tue, 5 Sep 2023 17:42:30 +0530
Subject: [PATCH 1/2] [CodeGen][MRI] Introduce synthetic register classes

Currently register classes can only be defined statically.
There is no way targets can define classes during codegen
for a specific period of time.

This patch includes a new field named `Synthetic` in the
regclass definition with value false by default. This
field, when set to true, indicates that such regclasses are
disabled by default and won't take part in various regclass
queries like getAllocatableClass,  getMinimalPhysRegClass,
etc. and in fact, they won't be allocatable, but targets can
enable them dynamically so that they behave like other register
classes.

The static definition of such classes are done in *RegisterInfo.td
file like other classes for tablegen to include them in all the
tables it auto-generates. The Synthetic field would be set to true
for such classes.
---
 llvm/include/llvm/CodeGen/LiveStacks.h        |  1 +
 llvm/include/llvm/CodeGen/MachineInstr.h      |  8 +-
 .../llvm/CodeGen/MachineRegisterInfo.h        | 16 ++++
 llvm/include/llvm/CodeGen/RegisterBankInfo.h  |  3 +-
 llvm/include/llvm/CodeGen/TargetLowering.h    |  1 +
 .../include/llvm/CodeGen/TargetRegisterInfo.h | 31 ++++---
 llvm/include/llvm/MC/MCRegisterInfo.h         |  4 +
 llvm/include/llvm/Target/Target.td            |  6 ++
 llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp |  2 +-
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   | 14 ++-
 llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp    |  6 +-
 .../CodeGen/AsmPrinter/DwarfExpression.cpp    |  7 +-
 llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h |  4 +-
 llvm/lib/CodeGen/DetectDeadLanes.cpp          |  8 +-
 .../CodeGen/FixupStatepointCallerSaved.cpp    | 36 ++++---
 llvm/lib/CodeGen/GlobalISel/Utils.cpp         |  4 +-
 llvm/lib/CodeGen/LiveStacks.cpp               |  3 +-
 llvm/lib/CodeGen/MIRParser/MIRParser.cpp      |  2 +-
 llvm/lib/CodeGen/MachineCSE.cpp               |  2 +-
 llvm/lib/CodeGen/MachineCombiner.cpp          |  2 +-
 llvm/lib/CodeGen/MachineInstr.cpp             | 20 ++--
 llvm/lib/CodeGen/MachineRegisterInfo.cpp      | 35 ++++++-
 llvm/lib/CodeGen/MachineVerifier.cpp          |  6 +-
 llvm/lib/CodeGen/PeepholeOptimizer.cpp        |  2 +-
 llvm/lib/CodeGen/PrologEpilogInserter.cpp     |  9 +-
 llvm/lib/CodeGen/RegAllocGreedy.cpp           |  5 +-
 llvm/lib/CodeGen/RegisterBank.cpp             |  4 +-
 llvm/lib/CodeGen/RegisterBankInfo.cpp         | 10 +-
 llvm/lib/CodeGen/RegisterCoalescer.cpp        | 16 ++--
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  3 +-
 .../lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 22 +++--
 .../CodeGen/SelectionDAG/ScheduleDAGFast.cpp  |  2 +-
 .../SelectionDAG/ScheduleDAGRRList.cpp        |  3 +-
 .../SelectionDAG/ScheduleDAGSDNodes.cpp       |  8 +-
 .../SelectionDAG/SelectionDAGBuilder.cpp      |  8 +-
 llvm/lib/CodeGen/StackMaps.cpp                |  6 +-
 llvm/lib/CodeGen/TailDuplicator.cpp           |  2 +-
 llvm/lib/CodeGen/TargetLoweringBase.cpp       |  3 +-
 llvm/lib/CodeGen/TargetRegisterInfo.cpp       | 93 +++++++++++--------
 .../lib/CodeGen/TwoAddressInstructionPass.cpp |  7 +-
 .../Target/AArch64/AArch64FrameLowering.cpp   |  3 +-
 llvm/lib/Target/AArch64/AArch64InstrInfo.cpp  | 11 ++-
 .../AArch64/AArch64LoadStoreOptimizer.cpp     | 25 +++--
 .../AMDGPU/GCNRewritePartialRegUses.cpp       |  5 +-
 llvm/lib/Target/AMDGPU/SIISelLowering.cpp     |  7 +-
 llvm/lib/Target/AMDGPU/SIISelLowering.h       |  1 +
 llvm/lib/Target/AMDGPU/SIInstrInfo.cpp        |  6 +-
 llvm/lib/Target/AMDGPU/SIInstrInfo.h          |  2 +-
 llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp  |  7 +-
 llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp     | 20 ++--
 llvm/lib/Target/AMDGPU/SIRegisterInfo.h       |  7 +-
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp   | 12 +--
 llvm/lib/Target/ARM/ARMBaseRegisterInfo.h     |  3 +-
 llvm/lib/Target/AVR/AVRAsmPrinter.cpp         |  3 +-
 llvm/lib/Target/AVR/AVRFrameLowering.cpp      |  6 +-
 llvm/lib/Target/CSKY/CSKYFrameLowering.cpp    |  6 +-
 llvm/lib/Target/Hexagon/BitTracker.cpp        |  2 +-
 llvm/lib/Target/Hexagon/HexagonBitTracker.cpp |  3 +-
 .../Target/Hexagon/HexagonExpandCondsets.cpp  |  2 +-
 .../Target/Hexagon/HexagonFrameLowering.cpp   | 11 ++-
 llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp  |  4 +-
 .../Target/Hexagon/HexagonVLIWPacketizer.cpp  |  9 +-
 llvm/lib/Target/Hexagon/RDFCopy.cpp           |  8 +-
 .../LoongArch/LoongArchFrameLowering.cpp      |  3 +-
 llvm/lib/Target/Mips/MipsFrameLowering.cpp    |  3 +-
 llvm/lib/Target/Mips/MipsSEFrameLowering.cpp  |  6 +-
 llvm/lib/Target/PowerPC/PPCFrameLowering.cpp  |  5 +-
 llvm/lib/Target/PowerPC/PPCInstrInfo.cpp      |  8 +-
 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp   |  3 +-
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp  |  9 +-
 llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp   |  2 +-
 .../Target/SystemZ/SystemZFrameLowering.cpp   |  6 +-
 llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp  |  4 +-
 .../Target/SystemZ/SystemZRegisterInfo.cpp    |  9 +-
 .../WebAssembly/WebAssemblyInstrInfo.cpp      |  2 +-
 .../WebAssemblyReplacePhysRegs.cpp            |  2 +-
 llvm/lib/Target/X86/X86FrameLowering.cpp      |  9 +-
 llvm/lib/Target/X86/X86InstrInfo.cpp          |  4 +-
 llvm/lib/Target/X86/X86RegisterInfo.cpp       | 21 ++---
 llvm/lib/Target/X86/X86RegisterInfo.h         |  7 +-
 llvm/lib/Target/XCore/XCoreFrameLowering.cpp  |  6 +-
 llvm/unittests/CodeGen/MFCommon.inc           | 42 ++++++++-
 llvm/unittests/CodeGen/MachineInstrTest.cpp   | 13 ++-
 llvm/utils/TableGen/CodeGenRegisters.cpp      |  7 +-
 llvm/utils/TableGen/CodeGenRegisters.h        |  1 +
 llvm/utils/TableGen/RegisterInfoEmitter.cpp   |  3 +-
 86 files changed, 488 insertions(+), 274 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/LiveStacks.h b/llvm/include/llvm/CodeGen/LiveStacks.h
index 2edc2985f0ee66..b9e55987383901 100644
--- a/llvm/include/llvm/CodeGen/LiveStacks.h
+++ b/llvm/include/llvm/CodeGen/LiveStacks.h
@@ -34,6 +34,7 @@ class TargetRegisterInfo;
 
 class LiveStacks : public MachineFunctionPass {
   const TargetRegisterInfo *TRI = nullptr;
+  const MachineRegisterInfo *MRI = nullptr;
 
   /// Special pool allocator for VNInfo's (LiveInterval val#).
   ///
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index fcdd73d8b65fdd..c7067d90a3ce06 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -1586,7 +1586,7 @@ class MachineInstr
   const TargetRegisterClass *getRegClassConstraintEffectForVReg(
       Register Reg, const TargetRegisterClass *CurRC,
       const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
-      bool ExploreBundle = false) const;
+      const MachineRegisterInfo &MRI, bool ExploreBundle = false) const;
 
   /// Applies the constraints (def/use) implied by the \p OpIdx operand
   /// to the given \p CurRC.
@@ -1600,7 +1600,8 @@ class MachineInstr
   const TargetRegisterClass *
   getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
                               const TargetInstrInfo *TII,
-                              const TargetRegisterInfo *TRI) const;
+                              const TargetRegisterInfo *TRI,
+                              const MachineRegisterInfo &MRI) const;
 
   /// Add a tie between the register operands at DefIdx and UseIdx.
   /// The tie will cause the register allocator to ensure that the two
@@ -2005,7 +2006,8 @@ class MachineInstr
   /// If the related operand does not constrained Reg, this returns CurRC.
   const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
       unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
-      const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
+      const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+      const MachineRegisterInfo &MRI) const;
 
   /// Stores extra instruction information inline or allocates as ExtraInfo
   /// based on the number of pointers.
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 09d9a0b4ec402f..71a3baef70e8cd 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -94,6 +94,10 @@ class MachineRegisterInfo {
   /// all registers that were disabled are removed from the list.
   SmallVector<MCPhysReg, 16> UpdatedCSRs;
 
+  /// The Synthetic field of regclasses. Targets can alter this vector
+  /// to enable classes dynamically during codegen.
+  BitVector RegClassSyntheticInfo;
+
   /// RegAllocHints - This vector records register allocation hints for
   /// virtual registers. For each virtual register, it keeps a pair of hint
   /// type and hints vector making up the allocation hints. Only the first
@@ -257,6 +261,18 @@ class MachineRegisterInfo {
   /// Notice that it will override ant previously disabled/saved CSRs.
   void setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs);
 
+  /// Initialize the RegClassSyntheticInfo. It sets the bit position as
+  /// exactly as the tablegened Synthetic field. Targets can later flip this
+  /// field to enable/disable the regclass whenever required.
+  void initializeRegClassSyntheticInfo();
+
+  /// Change the synthetic info for the regclass \p RC from \p Value.
+  void changeSyntheticInfoForRC(const TargetRegisterClass *RC, bool Value);
+
+  /// This function checks if \p RC is enabled or not so that it can be included
+  /// in various regclass related queries.
+  bool isEnabled(const TargetRegisterClass *RC) const;
+
   // Strictly for use by MachineInstr.cpp.
   void addRegOperandToUseList(MachineOperand *MO);
 
diff --git a/llvm/include/llvm/CodeGen/RegisterBankInfo.h b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
index 62c4a57a605d68..117f381512a1c6 100644
--- a/llvm/include/llvm/CodeGen/RegisterBankInfo.h
+++ b/llvm/include/llvm/CodeGen/RegisterBankInfo.h
@@ -445,7 +445,8 @@ class RegisterBankInfo {
   /// Get the MinimalPhysRegClass for Reg.
   /// \pre Reg is a physical register.
   const TargetRegisterClass *
-  getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI) const;
+  getMinimalPhysRegClass(Register Reg, const TargetRegisterInfo &TRI,
+                         const MachineRegisterInfo &MRI) const;
 
   /// Try to get the mapping of \p MI.
   /// See getInstrMapping for more details on what a mapping represents.
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 59fad88f91b1d1..5ef963cae55286 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -4384,6 +4384,7 @@ class TargetLowering : public TargetLoweringBase {
   /// Returns 'true' is the edge is necessary, 'false' otherwise
   virtual bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
                                          const TargetRegisterInfo *TRI,
+                                         const MachineRegisterInfo &MRI,
                                          const TargetInstrInfo *TII,
                                          unsigned &PhysReg, int &Cost) const {
     return false;
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 117d3f71829747..a3d68d6743ede5 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -121,6 +121,9 @@ class TargetRegisterClass {
   /// Return true if this register class has a defined BaseClassOrder.
   bool isBaseClass() const { return MC->isBaseClass(); }
 
+  /// Return true if this register class is marked synthetic.
+  bool isSynthetic() const { return MC->isSynthetic(); }
+
   /// Return true if the specified TargetRegisterClass
   /// is a proper sub-class of this TargetRegisterClass.
   bool hasSubClass(const TargetRegisterClass *RC) const {
@@ -338,20 +341,23 @@ class TargetRegisterInfo : public MCRegisterInfo {
   /// Returns the Register Class of a physical register of the given type,
   /// picking the most sub register class of the right type that contains this
   /// physreg.
-  const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
-                                                    MVT VT = MVT::Other) const;
+  const TargetRegisterClass *
+  getMinimalPhysRegClass(MCRegister Reg, const MachineRegisterInfo &MRI,
+                         MVT VT = MVT::Other) const;
 
   /// Returns the Register Class of a physical register of the given type,
   /// picking the most sub register class of the right type that contains this
   /// physreg. If there is no register class compatible with the given type,
   /// returns nullptr.
-  const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
-                                                       LLT Ty = LLT()) const;
+  const TargetRegisterClass *
+  getMinimalPhysRegClassLLT(MCRegister Reg, const MachineRegisterInfo &MRI,
+                            LLT Ty = LLT()) const;
 
   /// Return the maximal subclass of the given register class that is
   /// allocatable or NULL.
   const TargetRegisterClass *
-    getAllocatableClass(const TargetRegisterClass *RC) const;
+  getAllocatableClass(const TargetRegisterClass *RC,
+                      const MachineRegisterInfo &MRI) const;
 
   /// Returns a bitset indexed by register number indicating if a register is
   /// allocatable or not. If a register class is specified, returns the subset
@@ -630,7 +636,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
   /// TableGen will synthesize missing A sub-classes.
   virtual const TargetRegisterClass *
   getMatchingSuperRegClass(const TargetRegisterClass *A,
-                           const TargetRegisterClass *B, unsigned Idx) const;
+                           const TargetRegisterClass *B, unsigned Idx,
+                           const MachineRegisterInfo &MRI) const;
 
   // For a copy-like instruction that defines a register of class DefRC with
   // subreg index DefSubReg, reading from another source with class SrcRC and
@@ -639,7 +646,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
   virtual bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
                                     unsigned DefSubReg,
                                     const TargetRegisterClass *SrcRC,
-                                    unsigned SrcSubReg) const;
+                                    unsigned SrcSubReg,
+                                    const MachineRegisterInfo &MRI) const;
 
   /// Returns the largest legal sub-class of RC that
   /// supports the sub-register index Idx.
@@ -769,10 +777,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
   /// corresponding argument register class.
   ///
   /// The function returns NULL if no register class can be found.
-  const TargetRegisterClass*
+  const TargetRegisterClass *
   getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
                          const TargetRegisterClass *RCB, unsigned SubB,
-                         unsigned &PreA, unsigned &PreB) const;
+                         unsigned &PreA, unsigned &PreB,
+                         const MachineRegisterInfo &MRI) const;
 
   //===--------------------------------------------------------------------===//
   // Register Class Information
@@ -809,8 +818,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
   /// Find the largest common subclass of A and B.
   /// Return NULL if there is no common subclass.
   const TargetRegisterClass *
-  getCommonSubClass(const TargetRegisterClass *A,
-                    const TargetRegisterClass *B) const;
+  getCommonSubClass(const TargetRegisterClass *A, const TargetRegisterClass *B,
+                    const MachineRegisterInfo &MRI) const;
 
   /// Returns a TargetRegisterClass used for pointer values.
   /// If a target supports multiple different pointer register classes,
diff --git a/llvm/include/llvm/MC/MCRegisterInfo.h b/llvm/include/llvm/MC/MCRegisterInfo.h
index fb4d11ec1d4d16..1a2ff58c31f5a6 100644
--- a/llvm/include/llvm/MC/MCRegisterInfo.h
+++ b/llvm/include/llvm/MC/MCRegisterInfo.h
@@ -47,6 +47,7 @@ class MCRegisterClass {
   const int8_t CopyCost;
   const bool Allocatable;
   const bool BaseClass;
+  const bool Synthetic;
 
   /// getID() - Return the register class ID number.
   ///
@@ -101,6 +102,9 @@ class MCRegisterClass {
 
   /// Return true if this register class has a defined BaseClassOrder.
   bool isBaseClass() const { return BaseClass; }
+  /// isSynthetic - Return true if this is a synthetic class. This field helps
+  /// targets to dynamically enable the regclass during codegen.
+  bool isSynthetic() const { return Synthetic; }
 };
 
 /// MCRegisterDesc - This record contains information about a particular
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index cb1c0ed2513d45..0cf9159030bc52 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -338,6 +338,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
   // Target-specific flags. This becomes the TSFlags field in TargetRegisterClass.
   bits<8> TSFlags = 0;
 
+  // If set to true, the register class won't take part in various regclass queries
+  // by default. This allows targets to dynamically enable classes for a period
+  // during codegen so that they can be turned allocatable, copyable, spillable,
+  // and/or make them available for various regclass queries.
+  bit Synthetic = false;
+
   // If set then consider this register class to be the base class for registers in
   // its MemberList.  The base class for registers present in multiple base register
   // classes will be resolved in the order defined by this value, with lower values
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index ed6ce6bc73d38c..93860aae8acfdf 100644
--- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -604,7 +604,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
   // check every use of the register and find the largest register class
   // that can be used in all of them.
   const TargetRegisterClass *SuperRC =
-    TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
+      TRI->getMinimalPhysRegClass(SuperReg, MRI, MVT::Other);
 
   ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
   if (Order.empty()) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 14f2a363f9be61..7b403fee7ed120 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -813,7 +813,7 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
   auto AddEntry = [&](const DbgValueLocEntry &Entry,
                       DIExpressionCursor &Cursor) {
     if (Entry.isLocation()) {
-      if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
+      if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
                                              Entry.getLoc().getReg()))
         return false;
     } else if (Entry.isInt()) {
@@ -910,7 +910,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(const Loc::MMI &MMI,
       addOpAddress(*Loc, FrameSymbol);
     else
       DwarfExpr.addMachineRegExpression(
-          *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, FrameReg);
+          *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+          Cursor, FrameReg);
     DwarfExpr.addExpression(std::move(Cursor));
   }
   if (Asm->TM.getTargetTriple().isNVPTX() && DD->tuneForGDB()) {
@@ -940,7 +941,8 @@ void DwarfCompileUnit::applyConcreteDbgVariableAttributes(
     DIExpressionCursor Cursor(Expr.getElements());
     DwarfExpr.beginEntryValueExpression(Cursor);
     DwarfExpr.addMachineRegExpression(
-        *Asm->MF->getSubtarget().getRegisterInfo(), Cursor, Register);
+        *Asm->MF->getSubtarget().getRegisterInfo(), Asm->MF->getRegInfo(),
+        Cursor, Register);
     DwarfExpr.addExpression(std::move(Cursor));
   }
   addBlock(VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
@@ -1557,7 +1559,8 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
 
   DIExpressionCursor Cursor({});
   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
-  if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+  if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+                                         Location.getReg()))
     return;
   DwarfExpr.addExpression(std::move(Cursor));
 
@@ -1587,7 +1590,8 @@ void DwarfCompileUnit::addComplexAddress(const DIExpression *DIExpr, DIE &Die,
     DwarfExpr.beginEntryValueExpression(Cursor);
 
   const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
-  if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+  if (!DwarfExpr.addMachineRegExpression(TRI, Asm->MF->getRegInfo(), Cursor,
+                                         Location.getReg()))
     return;
   DwarfExpr.addExpression(std::move(Cursor));
 
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6b5ad62e083e3b..0b372d7b0e1bf1 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2652,7 +2652,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
     DwarfExpr.beginEntryValueExpression(ExprCursor);
 
     const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
-    if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg()))
+    if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), ExprCursor,
+                                           Location.getReg()))
       return;
     return DwarfExpr.addExpression(std::move(ExprCursor));
   }
@@ -2673,7 +2674,8 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
         DwarfExpr.setMemoryLocationKind();
 
       const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
-      if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
+      if (!DwarfExpr.addMachineRegExpression(TRI, AP.MF->getRegInfo(), Cursor,
+                                             Location.getReg()))
         return false;
     } else if (Entry.isTargetIndexLocation()) {
       TargetIndexLocation Loc = Entry.getTargetIndexLocation();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index a74d43897d45b3..6d4794d27effbd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -97,6 +97,7 @@ void DwarfExpression::addAnd(unsigned Mask) {
 }
 
 bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
+                                    const MachineRegisterInfo &MRI,
                                     llvm::Register MachineReg,
                                     unsigned MaxSize) {
   if (!MachineReg.isPhysical()) {
@@ -134,7 +135,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
   // For example, Q0 on ARM is a composition of D0+D1.
   unsigned CurPos = 0;
   // The size of the register in bits.
-  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
+  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg, MRI);
   unsigned RegSize = TRI.getRegSizeInBits(*RC);
   // Keep track of the bits in the register we already emitted, so we
   // can avoid emitting redundant aliasing subregs. Because this is
@@ -248,11 +249,13 @@ void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
 }
 
 bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
+                                              const MachineRegisterInfo &MRI,
                                               DIExpressionCursor &ExprCursor,
                                               llvm::Register MachineReg,
                                               unsigned FragmentOffsetInBits) {
   auto Fragment = ExprCursor.getFragmentInfo();
-  if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
+  if (!addMachineReg(TRI, MRI, MachineReg,
+                     Fragment ? Fragment->SizeInBits : ~1U)) {
     LocationKind = Unknown;
     return false;
   }
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 667a9efc6f6c04..70ab73b5996b48 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -245,7 +245,8 @@ class DwarfExpression {
   /// multiple subregisters that alias the register.
   ///
   /// \return false if no DWARF register exists for MachineReg.
-  bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg,
+  bool addMachineReg(const TargetRegisterInfo &TRI,
+                     const MachineRegisterInfo &MRI, llvm::Register MachineReg,
                      unsigned MaxSize = ~1U);
 
   /// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
@@ -325,6 +326,7 @@ class DwarfExpression {
   /// \return                         false if no DWARF register exists
   ///                                 for MachineReg.
   bool addMachineRegExpression(const TargetRegisterInfo &TRI,
+                               const MachineRegisterInfo &MRI,
                                DIExpressionCursor &Expr,
                                llvm::Register MachineReg,
                                unsigned FragmentOffsetInBits = 0);
diff --git a/llvm/lib/CodeGen/DetectDeadLanes.cpp b/llvm/lib/CodeGen/DetectDeadLanes.cpp
index 86e9f3abe010d7..57c5466129162e 100644
--- a/llvm/lib/CodeGen/DetectDeadLanes.cpp
+++ b/llvm/lib/CodeGen/DetectDeadLanes.cpp
@@ -97,12 +97,12 @@ static bool isCrossCopy(const MachineRegisterInfo &MRI,
   unsigned PreA, PreB; // Unused.
   if (SrcSubIdx && DstSubIdx)
     return !TRI.getCommonSuperRegClass(SrcRC, SrcSubIdx, DstRC, DstSubIdx, PreA,
-                                       PreB);
+                                       PreB, MRI);
   if (SrcSubIdx)
-    return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx);
+    return !TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSubIdx, MRI);
   if (DstSubIdx)
-    return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx);
-  return !TRI.getCommonSubClass(SrcRC, DstRC);
+    return !TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSubIdx, MRI);
+  return !TRI.getCommonSubClass(SrcRC, DstRC, MRI);
 }
 
 void DeadLaneDetector::addUsedLanesOnOperand(const MachineOperand &MO,
diff --git a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
index 4d668c53f7156b..6732a814f54401 100644
--- a/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
+++ b/llvm/lib/CodeGen/FixupStatepointCallerSaved.cpp
@@ -89,8 +89,9 @@ INITIALIZE_PASS_END(FixupStatepointCallerSaved, DEBUG_TYPE,
                     "Fixup Statepoint Caller Saved", false, false)
 
 // Utility function to get size of the register.
-static unsigned getRegisterSize(const TargetRegisterInfo &TRI, Register Reg) {
-  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+static unsigned getRegisterSize(const TargetRegisterInfo &TRI, Register Reg,
+                                const MachineRegisterInfo &MRI) {
+  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg, MRI);
   return TRI.getSpillSize(*RC);
 }
 
@@ -124,6 +125,7 @@ static Register performCopyPropagation(Register Reg,
   MachineBasicBlock *MBB = RI->getParent();
   MachineBasicBlock::reverse_iterator E = MBB->rend();
   MachineInstr *Def = nullptr, *Use = nullptr;
+  const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
   for (auto It = ++(RI.getReverse()); It != E; ++It) {
     if (It->readsRegister(Reg, &TRI) && !Use)
       Use = &*It;
@@ -142,7 +144,7 @@ static Register performCopyPropagation(Register Reg,
 
   Register SrcReg = DestSrc->Source->getReg();
 
-  if (getRegisterSize(TRI, Reg) != getRegisterSize(TRI, SrcReg))
+  if (getRegisterSize(TRI, Reg, MRI) != getRegisterSize(TRI, SrcReg, MRI))
     return Reg;
 
   LLVM_DEBUG(dbgs() << "spillRegisters: perform copy propagation "
@@ -209,6 +211,7 @@ class FrameIndexesCache {
   };
   MachineFrameInfo &MFI;
   const TargetRegisterInfo &TRI;
+  const MachineRegisterInfo &MRI;
   // Map size to list of frame indexes of this size. If the mode is
   // FixupSCSExtendSlotSize then the key 0 is used to keep all frame indexes.
   // If the size of required spill slot is greater than in a cache then the
@@ -232,8 +235,9 @@ class FrameIndexesCache {
   }
 
 public:
-  FrameIndexesCache(MachineFrameInfo &MFI, const TargetRegisterInfo &TRI)
-      : MFI(MFI), TRI(TRI) {}
+  FrameIndexesCache(MachineFrameInfo &MFI, const TargetRegisterInfo &TRI,
+                    const MachineRegisterInfo &MRI)
+      : MFI(MFI), TRI(TRI), MRI(MRI) {}
   // Reset the current state of used frame indexes. After invocation of
   // this function all frame indexes are available for allocation with
   // the exception of slots reserved for landing pad processing (if any).
@@ -265,7 +269,7 @@ class FrameIndexesCache {
       }
     }
 
-    unsigned Size = getRegisterSize(TRI, Reg);
+    unsigned Size = getRegisterSize(TRI, Reg, MRI);
     FrameIndexesPerSize &Line = getCacheBucket(Size);
     while (Line.Index < Line.Slots.size()) {
       int FI = Line.Slots[Line.Index++];
@@ -299,11 +303,12 @@ class FrameIndexesCache {
   // Sort all registers to spill in descendent order. In the
   // FixupSCSExtendSlotSize mode it will minimize the total frame size.
   // In non FixupSCSExtendSlotSize mode we can skip this step.
-  void sortRegisters(SmallVectorImpl<Register> &Regs) {
+  void sortRegisters(SmallVectorImpl<Register> &Regs,
+                     const MachineRegisterInfo &MRI) {
     if (!FixupSCSExtendSlotSize)
       return;
     llvm::sort(Regs, [&](Register &A, Register &B) {
-      return getRegisterSize(TRI, A) > getRegisterSize(TRI, B);
+      return getRegisterSize(TRI, A, MRI) > getRegisterSize(TRI, B, MRI);
     });
   }
 };
@@ -398,7 +403,7 @@ class StatepointState {
         RegsToSpill.push_back(Reg);
       OpsToSpill.push_back(Idx);
     }
-    CacheFI.sortRegisters(RegsToSpill);
+    CacheFI.sortRegisters(RegsToSpill, MF.getRegInfo());
     return !RegsToSpill.empty();
   }
 
@@ -418,7 +423,8 @@ class StatepointState {
       bool IsKill = true;
       MachineBasicBlock::iterator InsertBefore(MI);
       Reg = performCopyPropagation(Reg, InsertBefore, IsKill, TII, TRI);
-      const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+      const TargetRegisterClass *RC =
+          TRI.getMinimalPhysRegClass(Reg, MF.getRegInfo());
 
       LLVM_DEBUG(dbgs() << "Insert spill before " << *InsertBefore);
       TII.storeRegToStackSlot(*MI.getParent(), InsertBefore, Reg, IsKill, FI,
@@ -428,7 +434,8 @@ class StatepointState {
 
   void insertReloadBefore(unsigned Reg, MachineBasicBlock::iterator It,
                           MachineBasicBlock *MBB) {
-    const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC =
+        TRI.getMinimalPhysRegClass(Reg, MF.getRegInfo());
     int FI = RegToSlotIdx[Reg];
     if (It != MBB->end()) {
       TII.loadRegFromStackSlot(*MBB, It, Reg, FI, RC, &TRI, Register());
@@ -519,7 +526,7 @@ class StatepointState {
       if (I == OpsToSpill[CurOpIdx]) {
         int FI = RegToSlotIdx[MO.getReg()];
         MIB.addImm(StackMaps::IndirectMemRefOp);
-        MIB.addImm(getRegisterSize(TRI, MO.getReg()));
+        MIB.addImm(getRegisterSize(TRI, MO.getReg(), MF.getRegInfo()));
         assert(MO.isReg() && "Should be register");
         assert(MO.getReg().isPhysical() && "Should be physical register");
         MIB.addFrameIndex(FI);
@@ -538,6 +545,7 @@ class StatepointState {
     assert(CurOpIdx == (OpsToSpill.size() - 1) && "Not all operands processed");
     // Add mem operands.
     NewMI->setMemRefs(MF, MI.memoperands());
+    const MachineRegisterInfo &MRI = MF.getRegInfo();
     for (auto It : RegToSlotIdx) {
       Register R = It.first;
       int FrameIndex = It.second;
@@ -546,7 +554,7 @@ class StatepointState {
       if (is_contained(RegsToReload, R))
         Flags |= MachineMemOperand::MOStore;
       auto *MMO =
-          MF.getMachineMemOperand(PtrInfo, Flags, getRegisterSize(TRI, R),
+          MF.getMachineMemOperand(PtrInfo, Flags, getRegisterSize(TRI, R, MRI),
                                   MFI.getObjectAlign(FrameIndex));
       NewMI->addMemOperand(MF, MMO);
     }
@@ -570,7 +578,7 @@ class StatepointProcessor {
 public:
   StatepointProcessor(MachineFunction &MF)
       : MF(MF), TRI(*MF.getSubtarget().getRegisterInfo()),
-        CacheFI(MF.getFrameInfo(), TRI) {}
+        CacheFI(MF.getFrameInfo(), TRI, MF.getRegInfo()) {}
 
   bool process(MachineInstr &MI, bool AllowGCPtrInCSR) {
     StatepointOpers SO(&MI);
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index a9fa73b60a097f..8d597ceb0a043e 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -124,10 +124,10 @@ Register llvm::constrainOperandRegClass(
     // register types (E.g., AMDGPU's VGPR and AGPR). The regbank ambiguity
     // resolved by targets during regbankselect should not be overridden.
     if (const auto *SubRC = TRI.getCommonSubClass(
-            OpRC, TRI.getConstrainedRegClassForOperand(RegMO, MRI)))
+            OpRC, TRI.getConstrainedRegClassForOperand(RegMO, MRI), MRI))
       OpRC = SubRC;
 
-    OpRC = TRI.getAllocatableClass(OpRC);
+    OpRC = TRI.getAllocatableClass(OpRC, MRI);
   }
 
   if (!OpRC) {
diff --git a/llvm/lib/CodeGen/LiveStacks.cpp b/llvm/lib/CodeGen/LiveStacks.cpp
index 8fc5a929d77b21..4290d511dd1c21 100644
--- a/llvm/lib/CodeGen/LiveStacks.cpp
+++ b/llvm/lib/CodeGen/LiveStacks.cpp
@@ -45,6 +45,7 @@ void LiveStacks::releaseMemory() {
 
 bool LiveStacks::runOnMachineFunction(MachineFunction &MF) {
   TRI = MF.getSubtarget().getRegisterInfo();
+  MRI = &MF.getRegInfo();
   // FIXME: No analysis is being done right now. We are relying on the
   // register allocators to provide the information.
   return false;
@@ -64,7 +65,7 @@ LiveStacks::getOrCreateInterval(int Slot, const TargetRegisterClass *RC) {
   } else {
     // Use the largest common subclass register class.
     const TargetRegisterClass *OldRC = S2RCMap[Slot];
-    S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC);
+    S2RCMap[Slot] = TRI->getCommonSubClass(OldRC, RC, *MRI);
   }
   return I->second;
 }
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index e09318a486955b..27e72ccc74052f 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -687,7 +687,7 @@ bool MIRParserImpl::setupRegisterInfo(const PerFunctionMIParsingState &PFS,
       Error = true;
       break;
     case VRegInfo::NORMAL:
-      if (!Info.D.RC->isAllocatable()) {
+      if (!Info.D.RC->isAllocatable() || Info.D.RC->isSynthetic()) {
         error(Twine("Cannot use non-allocatable class '") +
               TRI->getRegClassName(Info.D.RC) + "' for virtual register " +
               Name + " in function '" + MF.getName() + "'");
diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp
index 26a8d00e662651..44ade0d87159a0 100644
--- a/llvm/lib/CodeGen/MachineCSE.cpp
+++ b/llvm/lib/CodeGen/MachineCSE.cpp
@@ -196,7 +196,7 @@ bool MachineCSE::PerformTrivialCopyPropagation(MachineInstr *MI,
     // cse-add-with-overflow.ll). This can be done here as follows:
     // if (SrcSubReg)
     //  RC = TRI->getMatchingSuperRegClass(MRI->getRegClass(SrcReg), RC,
-    //                                     SrcSubReg);
+    //                                     SrcSubReg, MRI);
     // MO.substVirtReg(SrcReg, SrcSubReg, *TRI);
     //
     // The 2-addr pass has been updated to handle coalesced subregs. However,
diff --git a/llvm/lib/CodeGen/MachineCombiner.cpp b/llvm/lib/CodeGen/MachineCombiner.cpp
index a4c87a7678bd8d..703af75ac5c18e 100644
--- a/llvm/lib/CodeGen/MachineCombiner.cpp
+++ b/llvm/lib/CodeGen/MachineCombiner.cpp
@@ -175,7 +175,7 @@ bool MachineCombiner::isTransientMI(const MachineInstr *MI) {
     auto SrcSub = MI->getOperand(1).getSubReg();
     auto SrcRC = MRI->getRegClass(Src);
     auto DstRC = MRI->getRegClass(Dst);
-    return TRI->getMatchingSuperRegClass(SrcRC, DstRC, SrcSub) != nullptr;
+    return TRI->getMatchingSuperRegClass(SrcRC, DstRC, SrcSub, *MRI) != nullptr;
   }
 
   if (Src.isPhysical() && Dst.isPhysical())
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index fe2f9ccd33a330..79f3873c858521 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -940,36 +940,40 @@ MachineInstr::getRegClassConstraint(unsigned OpIdx,
 
 const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
     Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
-    const TargetRegisterInfo *TRI, bool ExploreBundle) const {
+    const TargetRegisterInfo *TRI, const MachineRegisterInfo &MRI,
+    bool ExploreBundle) const {
   // Check every operands inside the bundle if we have
   // been asked to.
   if (ExploreBundle)
     for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC;
          ++OpndIt)
       CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl(
-          OpndIt.getOperandNo(), Reg, CurRC, TII, TRI);
+          OpndIt.getOperandNo(), Reg, CurRC, TII, TRI, MRI);
   else
     // Otherwise, just check the current operands.
     for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i)
-      CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI);
+      CurRC =
+          getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI, MRI);
   return CurRC;
 }
 
 const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
     unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
-    const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
+    const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+    const MachineRegisterInfo &MRI) const {
   assert(CurRC && "Invalid initial register class");
   // Check if Reg is constrained by some of its use/def from MI.
   const MachineOperand &MO = getOperand(OpIdx);
   if (!MO.isReg() || MO.getReg() != Reg)
     return CurRC;
   // If yes, accumulate the constraints through the operand.
-  return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI);
+  return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI, MRI);
 }
 
 const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
     unsigned OpIdx, const TargetRegisterClass *CurRC,
-    const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
+    const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
+    const MachineRegisterInfo &MRI) const {
   const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI);
   const MachineOperand &MO = getOperand(OpIdx);
   assert(MO.isReg() &&
@@ -977,11 +981,11 @@ const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
   assert(CurRC && "Invalid initial register class");
   if (unsigned SubIdx = MO.getSubReg()) {
     if (OpRC)
-      CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
+      CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx, MRI);
     else
       CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
   } else if (OpRC)
-    CurRC = TRI->getCommonSubClass(CurRC, OpRC);
+    CurRC = TRI->getCommonSubClass(CurRC, OpRC, MRI);
   return CurRC;
 }
 
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index b0c1838b3ff0ec..c979e3d5e9cf41 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -48,6 +48,7 @@ MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
   RegAllocHints.reserve(256);
   UsedPhysRegMask.resize(NumRegs);
   PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]());
+  initializeRegClassSyntheticInfo();
   TheDelegates.clear();
 }
 
@@ -55,7 +56,8 @@ MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
 ///
 void
 MachineRegisterInfo::setRegClass(Register Reg, const TargetRegisterClass *RC) {
-  assert(RC && RC->isAllocatable() && "Invalid RC for virtual register");
+  assert(RC && isEnabled(RC) && RC->isAllocatable() &&
+         "Invalid RC for virtual register");
   VRegInfo[Reg].first = RC;
 }
 
@@ -71,7 +73,7 @@ constrainRegClass(MachineRegisterInfo &MRI, Register Reg,
   if (OldRC == RC)
     return RC;
   const TargetRegisterClass *NewRC =
-      MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC);
+      MRI.getTargetRegisterInfo()->getCommonSubClass(OldRC, RC, MRI);
   if (!NewRC || NewRC == OldRC)
     return NewRC;
   if (NewRC->getNumRegs() < MinNumRegs)
@@ -134,7 +136,7 @@ MachineRegisterInfo::recomputeRegClass(Register Reg) {
     MachineInstr *MI = MO.getParent();
     unsigned OpNo = &MO - &MI->getOperand(0);
     NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, TII,
-                                            getTargetRegisterInfo());
+                                            getTargetRegisterInfo(), *this);
     if (!NewRC || NewRC == OldRC)
       return false;
   }
@@ -159,6 +161,8 @@ MachineRegisterInfo::createVirtualRegister(const TargetRegisterClass *RegClass,
   assert(RegClass && "Cannot create register without RegClass!");
   assert(RegClass->isAllocatable() &&
          "Virtual register RegClass must be allocatable.");
+  assert(isEnabled(RegClass) &&
+         "RegClass must be enabled first to create its virtual registers.");
 
   // New virtual register number.
   Register Reg = createIncompleteVirtualRegister(Name);
@@ -650,6 +654,31 @@ void MachineRegisterInfo::setCalleeSavedRegs(ArrayRef<MCPhysReg> CSRs) {
   IsUpdatedCSRsInitialized = true;
 }
 
+void MachineRegisterInfo::initializeRegClassSyntheticInfo() {
+  const TargetRegisterInfo *TRI = getTargetRegisterInfo();
+
+  RegClassSyntheticInfo.resize(TRI->getNumRegClasses());
+  for (const TargetRegisterClass *RC : TRI->regclasses()) {
+    if (RC->isSynthetic())
+      RegClassSyntheticInfo.set(RC->getID());
+  }
+}
+
+void MachineRegisterInfo::changeSyntheticInfoForRC(
+    const TargetRegisterClass *RC, bool Value) {
+  assert(RC->isSynthetic() && "Regclasses can be enabled/disabled dynamically "
+                              "only if marked synthetic.");
+
+  if (Value)
+    RegClassSyntheticInfo.set(RC->getID());
+  else
+    RegClassSyntheticInfo.reset(RC->getID());
+}
+
+bool MachineRegisterInfo::isEnabled(const TargetRegisterClass *RC) const {
+  return !RegClassSyntheticInfo.test(RC->getID());
+}
+
 bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
   for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index c69d36fc7fdd60..a33653160cb69d 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2109,14 +2109,14 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
     TypeSize DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
     if (SrcReg.isPhysical() && DstTy.isValid()) {
       const TargetRegisterClass *SrcRC =
-          TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy);
+          TRI->getMinimalPhysRegClassLLT(SrcReg, *MRI, DstTy);
       if (SrcRC)
         SrcSize = TRI->getRegSizeInBits(*SrcRC);
     }
 
     if (DstReg.isPhysical() && SrcTy.isValid()) {
       const TargetRegisterClass *DstRC =
-          TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy);
+          TRI->getMinimalPhysRegClassLLT(DstReg, *MRI, SrcTy);
       if (DstRC)
         DstSize = TRI->getRegSizeInBits(*DstRC);
     }
@@ -2490,7 +2490,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
               report("No largest legal super class exists.", MO, MONum);
               return;
             }
-            DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx);
+            DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx, *MRI);
             if (!DRC) {
               report("No matching super-reg register class.", MO, MONum);
               return;
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index 1b1f22e827cb1e..d5809fa46939b4 100644
--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -793,7 +793,7 @@ bool PeepholeOptimizer::findNextSource(RegSubRegPair RegSubReg,
       // Keep following the chain if the value isn't any better yet.
       const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg);
       if (!TRI->shouldRewriteCopySrc(DefRC, RegSubReg.SubReg, SrcRC,
-                                     CurSrcPair.SubReg))
+                                     CurSrcPair.SubReg, *MRI))
         continue;
 
       // We currently cannot deal with subreg operands on PHI instructions
diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
index eaf96ec5cbde8c..77271140cb7fa3 100644
--- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -477,7 +477,8 @@ static void assignCalleeSavedSpillSlots(MachineFunction &F,
         continue;
 
       unsigned Reg = CS.getReg();
-      const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
+      const TargetRegisterClass *RC =
+          RegInfo->getMinimalPhysRegClass(Reg, F.getRegInfo());
 
       int FrameIdx;
       if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) {
@@ -607,7 +608,8 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock,
                 TII.get(TargetOpcode::COPY), CS.getDstReg())
           .addReg(Reg, getKillRegState(true));
       } else {
-        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+        const TargetRegisterClass *RC =
+            TRI->getMinimalPhysRegClass(Reg, MF.getRegInfo());
         TII.storeRegToStackSlot(SaveBlock, I, Reg, true, CS.getFrameIdx(), RC,
                                 TRI, Register());
       }
@@ -634,7 +636,8 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
         BuildMI(RestoreBlock, I, DebugLoc(), TII.get(TargetOpcode::COPY), Reg)
           .addReg(CI.getDstReg(), getKillRegState(true));
       } else {
-        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+        const TargetRegisterClass *RC =
+            TRI->getMinimalPhysRegClass(Reg, MF.getRegInfo());
         TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC,
                                  TRI, Register());
         assert(I != RestoreBlock.begin() &&
diff --git a/llvm/lib/CodeGen/RegAllocGreedy.cpp b/llvm/lib/CodeGen/RegAllocGreedy.cpp
index a208bf89fadf29..decf7b6cda14a2 100644
--- a/llvm/lib/CodeGen/RegAllocGreedy.cpp
+++ b/llvm/lib/CodeGen/RegAllocGreedy.cpp
@@ -1342,8 +1342,9 @@ static unsigned getNumAllocatableRegsForConstraints(
   assert(SuperRC && "Invalid register class");
 
   const TargetRegisterClass *ConstrainedRC =
-      MI->getRegClassConstraintEffectForVReg(Reg, SuperRC, TII, TRI,
-                                             /* ExploreBundle */ true);
+      MI->getRegClassConstraintEffectForVReg(
+          Reg, SuperRC, TII, TRI, MI->getParent()->getParent()->getRegInfo(),
+          /* ExploreBundle */ true);
   if (!ConstrainedRC)
     return 0;
   return RCI.getNumAllocatableRegs(ConstrainedRC);
diff --git a/llvm/lib/CodeGen/RegisterBank.cpp b/llvm/lib/CodeGen/RegisterBank.cpp
index bdc6df78fd3d98..ac4ef3344e7ebd 100644
--- a/llvm/lib/CodeGen/RegisterBank.cpp
+++ b/llvm/lib/CodeGen/RegisterBank.cpp
@@ -36,7 +36,7 @@ bool RegisterBank::verify(const RegisterBankInfo &RBI,
     for (unsigned SubRCId = 0; SubRCId != End; ++SubRCId) {
       const TargetRegisterClass &SubRC = *TRI.getRegClass(RCId);
 
-      if (!RC.hasSubClassEq(&SubRC))
+      if (SubRC.isSynthetic() || !RC.hasSubClassEq(&SubRC))
         continue;
 
       // Verify that the Size of the register bank is big enough to cover
@@ -91,7 +91,7 @@ void RegisterBank::print(raw_ostream &OS, bool IsForDebug,
   for (unsigned RCId = 0, End = TRI->getNumRegClasses(); RCId != End; ++RCId) {
     const TargetRegisterClass &RC = *TRI->getRegClass(RCId);
 
-    if (covers(RC))
+    if (covers(RC) && !RC.isSynthetic())
       OS << LS << TRI->getRegClassName(&RC);
   }
 }
diff --git a/llvm/lib/CodeGen/RegisterBankInfo.cpp b/llvm/lib/CodeGen/RegisterBankInfo.cpp
index 5548430d1b0ae8..b57a19dd4ad854 100644
--- a/llvm/lib/CodeGen/RegisterBankInfo.cpp
+++ b/llvm/lib/CodeGen/RegisterBankInfo.cpp
@@ -86,7 +86,7 @@ RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI,
   if (!Reg.isVirtual()) {
     // FIXME: This was probably a copy to a virtual register that does have a
     // type we could use.
-    const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, TRI);
+    const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, TRI, MRI);
     return RC ? &getRegBankFromRegClass(*RC, LLT()) : nullptr;
   }
 
@@ -101,12 +101,14 @@ RegisterBankInfo::getRegBank(Register Reg, const MachineRegisterInfo &MRI,
 
 const TargetRegisterClass *
 RegisterBankInfo::getMinimalPhysRegClass(Register Reg,
-                                         const TargetRegisterInfo &TRI) const {
+                                         const TargetRegisterInfo &TRI,
+                                         const MachineRegisterInfo &MRI) const {
   assert(Reg.isPhysical() && "Reg must be a physreg");
   const auto &RegRCIt = PhysRegMinimalRCs.find(Reg);
   if (RegRCIt != PhysRegMinimalRCs.end())
     return RegRCIt->second;
-  const TargetRegisterClass *PhysRC = TRI.getMinimalPhysRegClassLLT(Reg, LLT());
+  const TargetRegisterClass *PhysRC =
+      TRI.getMinimalPhysRegClassLLT(Reg, MRI, LLT());
   PhysRegMinimalRCs[Reg] = PhysRC;
   return PhysRC;
 }
@@ -503,7 +505,7 @@ TypeSize RegisterBankInfo::getSizeInBits(Register Reg,
     // Instead, we need to access a register class that contains Reg and
     // get the size of that register class.
     // Because this is expensive, we'll cache the register class by calling
-    auto *RC = getMinimalPhysRegClass(Reg, TRI);
+    auto *RC = getMinimalPhysRegClass(Reg, TRI, MRI);
     assert(RC && "Expecting Register class");
     return TRI.getRegSizeInBits(*RC);
   }
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 7e9c992031f8d3..ff300430d38d01 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -498,21 +498,21 @@ bool CoalescerPair::setRegisters(const MachineInstr *MI) {
       if (Src == Dst && SrcSub != DstSub)
         return false;
 
-      NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub,
-                                         SrcIdx, DstIdx);
+      NewRC = TRI.getCommonSuperRegClass(SrcRC, SrcSub, DstRC, DstSub, SrcIdx,
+                                         DstIdx, MRI);
       if (!NewRC)
         return false;
     } else if (DstSub) {
       // SrcReg will be merged with a sub-register of DstReg.
       SrcIdx = DstSub;
-      NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub);
+      NewRC = TRI.getMatchingSuperRegClass(DstRC, SrcRC, DstSub, MRI);
     } else if (SrcSub) {
       // DstReg will be merged with a sub-register of SrcReg.
       DstIdx = SrcSub;
-      NewRC = TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSub);
+      NewRC = TRI.getMatchingSuperRegClass(SrcRC, DstRC, SrcSub, MRI);
     } else {
       // This is a straight copy without sub-registers.
-      NewRC = TRI.getCommonSubClass(DstRC, SrcRC);
+      NewRC = TRI.getCommonSubClass(DstRC, SrcRC, MRI);
     }
 
     // The combined constraint may be impossible to satisfy.
@@ -1387,7 +1387,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
              && "Shouldn't have SrcIdx+DstIdx at this point");
       const TargetRegisterClass *DstRC = MRI->getRegClass(DstReg);
       const TargetRegisterClass *CommonRC =
-        TRI->getCommonSubClass(DefRC, DstRC);
+          TRI->getCommonSubClass(DefRC, DstRC, *MRI);
       if (CommonRC != nullptr) {
         NewRC = CommonRC;
 
@@ -1481,9 +1481,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
 
     if (DefRC != nullptr) {
       if (NewIdx)
-        NewRC = TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx);
+        NewRC = TRI->getMatchingSuperRegClass(NewRC, DefRC, NewIdx, *MRI);
       else
-        NewRC = TRI->getCommonSubClass(NewRC, DefRC);
+        NewRC = TRI->getCommonSubClass(NewRC, DefRC, *MRI);
       assert(NewRC && "subreg chosen for remat incompatible with instruction");
     }
     // Remap subranges to new lanemask and change register class.
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index f199625bf67ad3..a8a4286c26230d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19094,7 +19094,8 @@ struct LoadedSlice {
     const TargetRegisterInfo *TRI = DAG->getSubtarget().getRegisterInfo();
     // Assume bitcasts are cheap, unless both register classes do not
     // explicitly share a common sub class.
-    if (!TRI || TRI->getCommonSubClass(ArgRC, ResRC))
+    if (!TRI || TRI->getCommonSubClass(ArgRC, ResRC,
+                                       DAG->getMachineFunction().getRegInfo()))
       return false;
 
     // Check if it will be merged with the load.
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index 54409cbf91f1f7..a557406b236fba 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -131,13 +131,13 @@ void InstrEmitter::EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
           const TargetRegisterClass *RC = nullptr;
           if (i + II.getNumDefs() < II.getNumOperands()) {
             RC = TRI->getAllocatableClass(
-                TII->getRegClass(II, i + II.getNumDefs(), TRI, *MF));
+                TII->getRegClass(II, i + II.getNumDefs(), TRI, *MF), *MRI);
           }
           if (!UseRC)
             UseRC = RC;
           else if (RC) {
             const TargetRegisterClass *ComRC =
-                TRI->getCommonSubClass(UseRC, RC);
+                TRI->getCommonSubClass(UseRC, RC, *MRI);
             // If multiple uses expect disjoint register classes, we emit
             // copies in AddRegisterOperand.
             if (ComRC)
@@ -152,7 +152,7 @@ void InstrEmitter::EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone,
   }
 
   const TargetRegisterClass *SrcRC = nullptr, *DstRC = nullptr;
-  SrcRC = TRI->getMinimalPhysRegClass(SrcReg, VT);
+  SrcRC = TRI->getMinimalPhysRegClass(SrcReg, *MRI, VT);
 
   // Figure out the register class to create for the destreg.
   if (VRBase) {
@@ -203,7 +203,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node,
     // register instead of creating a new vreg.
     Register VRBase;
     const TargetRegisterClass *RC =
-      TRI->getAllocatableClass(TII->getRegClass(II, i, TRI, *MF));
+        TRI->getAllocatableClass(TII->getRegClass(II, i, TRI, *MF), *MRI);
     // Always let the value type influence the used register class. The
     // constraints on the instruction may be too lax to represent the value
     // type correctly. For example, a 64-bit float (X86::FR64) can't live in
@@ -213,7 +213,7 @@ void InstrEmitter::CreateVirtualRegisters(SDNode *Node,
           Node->getSimpleValueType(i),
           (Node->isDivergent() || (RC && TRI->isDivergentRegClass(RC))));
       if (RC)
-        VTRC = TRI->getCommonSubClass(RC, VTRC);
+        VTRC = TRI->getCommonSubClass(RC, VTRC, *MRI);
       if (VTRC)
         RC = VTRC;
     }
@@ -350,7 +350,7 @@ InstrEmitter::AddRegisterOperand(MachineInstrBuilder &MIB,
       const TargetRegisterClass *ConstrainedRC
         = MRI->constrainRegClass(VReg, OpRC, MinNumRegs);
       if (!ConstrainedRC) {
-        OpRC = TRI->getAllocatableClass(OpRC);
+        OpRC = TRI->getAllocatableClass(OpRC, *MRI);
         assert(OpRC && "Constraints cannot be fulfilled for allocation");
         Register NewVReg = MRI->createVirtualRegister(OpRC);
         BuildMI(*MBB, InsertPos, Op.getNode()->getDebugLoc(),
@@ -412,7 +412,8 @@ void InstrEmitter::AddOperand(MachineInstrBuilder &MIB,
     Register VReg = R->getReg();
     MVT OpVT = Op.getSimpleValueType();
     const TargetRegisterClass *IIRC =
-        II ? TRI->getAllocatableClass(TII->getRegClass(*II, IIOpNum, TRI, *MF))
+        II ? TRI->getAllocatableClass(TII->getRegClass(*II, IIOpNum, TRI, *MF),
+                                      *MRI)
            : nullptr;
     const TargetRegisterClass *OpRC =
         TLI->isTypeLegal(OpVT)
@@ -640,7 +641,7 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node,
   // Create the new VReg in the destination class and emit a copy.
   unsigned DstRCIdx = Node->getConstantOperandVal(1);
   const TargetRegisterClass *DstRC =
-    TRI->getAllocatableClass(TRI->getRegClass(DstRCIdx));
+      TRI->getAllocatableClass(TRI->getRegClass(DstRCIdx), *MRI);
   Register NewVReg = MRI->createVirtualRegister(DstRC);
   BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TargetOpcode::COPY),
     NewVReg).addReg(VReg);
@@ -658,7 +659,8 @@ void InstrEmitter::EmitRegSequence(SDNode *Node,
                                   bool IsClone, bool IsCloned) {
   unsigned DstRCIdx = Node->getConstantOperandVal(0);
   const TargetRegisterClass *RC = TRI->getRegClass(DstRCIdx);
-  Register NewVReg = MRI->createVirtualRegister(TRI->getAllocatableClass(RC));
+  Register NewVReg =
+      MRI->createVirtualRegister(TRI->getAllocatableClass(RC, *MRI));
   const MCInstrDesc &II = TII->get(TargetOpcode::REG_SEQUENCE);
   MachineInstrBuilder MIB = BuildMI(*MF, Node->getDebugLoc(), II, NewVReg);
   unsigned NumOps = Node->getNumOperands();
@@ -681,7 +683,7 @@ void InstrEmitter::EmitRegSequence(SDNode *Node,
         unsigned SubReg = getVR(Node->getOperand(i-1), VRBaseMap);
         const TargetRegisterClass *TRC = MRI->getRegClass(SubReg);
         const TargetRegisterClass *SRC =
-        TRI->getMatchingSuperRegClass(RC, TRC, SubIdx);
+            TRI->getMatchingSuperRegClass(RC, TRC, SubIdx, *MRI);
         if (SRC && SRC != RC) {
           MRI->setRegClass(NewVReg, SRC);
           RC = SRC;
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index e3acb58327a8c1..f6124201775d91 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -581,7 +581,7 @@ void ScheduleDAGFast::ListScheduleBottomUp() {
         SUnit *LRDef = LiveRegDefs[Reg];
         MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
         const TargetRegisterClass *RC =
-          TRI->getMinimalPhysRegClass(Reg, VT);
+            TRI->getMinimalPhysRegClass(Reg, MRI, VT);
         const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
 
         // If cross copy register class is the same as RC, then it must be
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index e4ee3fd99f16e3..699fab5333e5c1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1561,8 +1561,7 @@ SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() {
     unsigned Reg = LRegs[0];
     SUnit *LRDef = LiveRegDefs[Reg];
     MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
-    const TargetRegisterClass *RC =
-      TRI->getMinimalPhysRegClass(Reg, VT);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT);
     const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
 
     // If cross copy register class is the same as RC, then it must be possible
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index c9e2745f00c958..07728bd3b43548 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -111,12 +111,14 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
                                       const TargetRegisterInfo *TRI,
                                       const TargetInstrInfo *TII,
                                       const TargetLowering &TLI,
+                                      const MachineRegisterInfo &MRI,
                                       unsigned &PhysReg, int &Cost) {
   if (Op != 2 || User->getOpcode() != ISD::CopyToReg)
     return;
 
   unsigned Reg = cast<RegisterSDNode>(User->getOperand(1))->getReg();
-  if (TLI.checkForPhysRegDependency(Def, User, Op, TRI, TII, PhysReg, Cost))
+  if (TLI.checkForPhysRegDependency(Def, User, Op, TRI, MRI, TII, PhysReg,
+                                    Cost))
     return;
 
   if (Register::isVirtualRegister(Reg))
@@ -134,7 +136,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
 
   if (PhysReg != 0) {
     const TargetRegisterClass *RC =
-        TRI->getMinimalPhysRegClass(Reg, Def->getSimpleValueType(ResNo));
+        TRI->getMinimalPhysRegClass(Reg, MRI, Def->getSimpleValueType(ResNo));
     Cost = RC->getCopyCost();
   }
 }
@@ -490,7 +492,7 @@ void ScheduleDAGSDNodes::AddSchedEdges() {
         int Cost = 1;
         // Determine if this is a physical register dependency.
         const TargetLowering &TLI = DAG->getTargetLoweringInfo();
-        CheckForPhysRegDependency(OpN, N, i, TRI, TII, TLI, PhysReg, Cost);
+        CheckForPhysRegDependency(OpN, N, i, TRI, TII, TLI, MRI, PhysReg, Cost);
         assert((PhysReg == 0 || !isChain) &&
                "Chain dependence via physreg data?");
         // FIXME: See ScheduleDAGSDNodes::EmitCopyFromReg. For now, scheduler
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 2d63774c75e372..982d1a0c44f77c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -9738,9 +9738,11 @@ void SelectionDAGBuilder::visitInlineAsm(const CallBase &Call,
           Register TiedReg = R->getReg();
           MVT RegVT = R->getSimpleValueType(0);
           const TargetRegisterClass *RC =
-              TiedReg.isVirtual()     ? MRI.getRegClass(TiedReg)
-              : RegVT != MVT::Untyped ? TLI.getRegClassFor(RegVT)
-                                      : TRI.getMinimalPhysRegClass(TiedReg);
+              TiedReg.isVirtual()
+                  ? MRI.getRegClass(TiedReg)
+                  : RegVT != MVT::Untyped
+                        ? TLI.getRegClassFor(RegVT)
+                        : TRI.getMinimalPhysRegClass(TiedReg, MRI);
           for (unsigned i = 0, e = Flag.getNumOperandRegisters(); i != e; ++i)
             Regs.push_back(MRI.createVirtualRegister(RC));
 
diff --git a/llvm/lib/CodeGen/StackMaps.cpp b/llvm/lib/CodeGen/StackMaps.cpp
index 90aa93e442cf36..eca640ef9ad646 100644
--- a/llvm/lib/CodeGen/StackMaps.cpp
+++ b/llvm/lib/CodeGen/StackMaps.cpp
@@ -277,7 +277,8 @@ StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
 
     assert(MOI->getReg().isPhysical() &&
            "Virtreg operands should have been rewritten before now.");
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(MOI->getReg());
+    const TargetRegisterClass *RC =
+        TRI->getMinimalPhysRegClass(MOI->getReg(), AP.MF->getRegInfo());
     assert(!MOI->getSubReg() && "Physical subreg still around.");
 
     unsigned Offset = 0;
@@ -373,7 +374,8 @@ void StackMaps::print(raw_ostream &OS) {
 StackMaps::LiveOutReg
 StackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const {
   unsigned DwarfRegNum = getDwarfRegNum(Reg, TRI);
-  unsigned Size = TRI->getSpillSize(*TRI->getMinimalPhysRegClass(Reg));
+  unsigned Size =
+      TRI->getSpillSize(*TRI->getMinimalPhysRegClass(Reg, AP.MF->getRegInfo()));
   return LiveOutReg(Reg, DwarfRegNum, Size);
 }
 
diff --git a/llvm/lib/CodeGen/TailDuplicator.cpp b/llvm/lib/CodeGen/TailDuplicator.cpp
index 5ed67bd0a121ed..e42c4f1348ab77 100644
--- a/llvm/lib/CodeGen/TailDuplicator.cpp
+++ b/llvm/lib/CodeGen/TailDuplicator.cpp
@@ -417,7 +417,7 @@ void TailDuplicator::duplicateInstruction(
           const TargetRegisterClass *ConstrRC;
           if (VI->second.SubReg != 0) {
             ConstrRC = TRI->getMatchingSuperRegClass(MappedRC, OrigRC,
-                                                     VI->second.SubReg);
+                                                     VI->second.SubReg, *MRI);
             if (ConstrRC) {
               // The actual constraining (as in "find appropriate new class")
               // is done by getMatchingSuperRegClass, so now we only need to
diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 9990556f89ed8b..9adfa8f839104e 100644
--- a/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -1365,7 +1365,8 @@ TargetLoweringBase::findRepresentativeClass(const TargetRegisterInfo *TRI,
   for (unsigned i : SuperRegRC.set_bits()) {
     const TargetRegisterClass *SuperRC = TRI->getRegClass(i);
     // We want the largest possible spill size.
-    if (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC))
+    if (SuperRC->isSynthetic() ||
+        (TRI->getSpillSize(*SuperRC) <= TRI->getSpillSize(*BestRC)))
       continue;
     if (!isLegalRC(*TRI, *SuperRC))
       continue;
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index c9503fcb77bb21..7c24748acdd93c 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -193,14 +193,15 @@ Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo,
 /// getAllocatableClass - Return the maximal subclass of the given register
 /// class that is alloctable, or NULL.
 const TargetRegisterClass *
-TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const {
+TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC,
+                                        const MachineRegisterInfo &MRI) const {
   if (!RC || RC->isAllocatable())
     return RC;
 
   for (BitMaskClassIterator It(RC->getSubClassMask(), *this); It.isValid();
        ++It) {
     const TargetRegisterClass *SubRC = getRegClass(It.getID());
-    if (SubRC->isAllocatable())
+    if (SubRC->isAllocatable() && MRI.isEnabled(SubRC))
       return SubRC;
   }
   return nullptr;
@@ -209,8 +210,8 @@ TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const {
 /// getMinimalPhysRegClass - Returns the Register Class of a physical
 /// register of the given type, picking the most sub register class of
 /// the right type that contains this physreg.
-const TargetRegisterClass *
-TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const {
+const TargetRegisterClass *TargetRegisterInfo::getMinimalPhysRegClass(
+    MCRegister reg, const MachineRegisterInfo &MRI, MVT VT) const {
   assert(Register::isPhysicalRegister(reg) &&
          "reg must be a physical register");
 
@@ -219,7 +220,8 @@ TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const {
   const TargetRegisterClass* BestRC = nullptr;
   for (const TargetRegisterClass* RC : regclasses()) {
     if ((VT == MVT::Other || isTypeLegalForClass(*RC, VT)) &&
-        RC->contains(reg) && (!BestRC || BestRC->hasSubClass(RC)))
+        RC->contains(reg) && MRI.isEnabled(RC) &&
+        (!BestRC || BestRC->hasSubClass(RC)))
       BestRC = RC;
   }
 
@@ -227,8 +229,8 @@ TargetRegisterInfo::getMinimalPhysRegClass(MCRegister reg, MVT VT) const {
   return BestRC;
 }
 
-const TargetRegisterClass *
-TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const {
+const TargetRegisterClass *TargetRegisterInfo::getMinimalPhysRegClassLLT(
+    MCRegister reg, const MachineRegisterInfo &MRI, LLT Ty) const {
   assert(Register::isPhysicalRegister(reg) &&
          "reg must be a physical register");
 
@@ -237,7 +239,7 @@ TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const {
   const TargetRegisterClass *BestRC = nullptr;
   for (const TargetRegisterClass *RC : regclasses()) {
     if ((!Ty.isValid() || isTypeLegalForClass(*RC, Ty)) && RC->contains(reg) &&
-        (!BestRC || BestRC->hasSubClass(RC)))
+        MRI.isEnabled(RC) && (!BestRC || BestRC->hasSubClass(RC)))
       BestRC = RC;
   }
 
@@ -248,7 +250,8 @@ TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister reg, LLT Ty) const {
 /// registers for the specific register class.
 static void getAllocatableSetForRC(const MachineFunction &MF,
                                    const TargetRegisterClass *RC, BitVector &R){
-  assert(RC->isAllocatable() && "invalid for nonallocatable sets");
+  assert(RC->isAllocatable() && MF.getRegInfo().isEnabled(RC) &&
+         "invalid for nonallocatable sets");
   ArrayRef<MCPhysReg> Order = RC->getRawAllocationOrder(MF);
   for (MCPhysReg PR : Order)
     R.set(PR);
@@ -257,38 +260,44 @@ static void getAllocatableSetForRC(const MachineFunction &MF,
 BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF,
                                           const TargetRegisterClass *RC) const {
   BitVector Allocatable(getNumRegs());
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   if (RC) {
     // A register class with no allocatable subclass returns an empty set.
-    const TargetRegisterClass *SubClass = getAllocatableClass(RC);
+    const TargetRegisterClass *SubClass = getAllocatableClass(RC, MRI);
     if (SubClass)
       getAllocatableSetForRC(MF, SubClass, Allocatable);
   } else {
     for (const TargetRegisterClass *C : regclasses())
-      if (C->isAllocatable())
+      if (C->isAllocatable() && MRI.isEnabled(C))
         getAllocatableSetForRC(MF, C, Allocatable);
   }
 
   // Mask out the reserved registers
-  const MachineRegisterInfo &MRI = MF.getRegInfo();
   const BitVector &Reserved = MRI.getReservedRegs();
   Allocatable.reset(Reserved);
 
   return Allocatable;
 }
 
-static inline
-const TargetRegisterClass *firstCommonClass(const uint32_t *A,
-                                            const uint32_t *B,
-                                            const TargetRegisterInfo *TRI) {
-  for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32)
-    if (unsigned Common = *A++ & *B++)
-      return TRI->getRegClass(I + llvm::countr_zero(Common));
+static inline const TargetRegisterClass *
+firstCommonClass(const uint32_t *A, const uint32_t *B,
+                 const TargetRegisterInfo *TRI,
+                 const MachineRegisterInfo &MRI) {
+  for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; I += 32) {
+    if (unsigned Common = *A++ & *B++) {
+      const TargetRegisterClass *RC =
+          TRI->getRegClass(I + llvm::countr_zero(Common));
+      if (MRI.isEnabled(RC))
+        return RC;
+    }
+  }
   return nullptr;
 }
 
 const TargetRegisterClass *
 TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A,
-                                      const TargetRegisterClass *B) const {
+                                      const TargetRegisterClass *B,
+                                      const MachineRegisterInfo &MRI) const {
   // First take care of the trivial cases.
   if (A == B)
     return A;
@@ -297,13 +306,13 @@ TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A,
 
   // Register classes are ordered topologically, so the largest common
   // sub-class it the common sub-class with the smallest ID.
-  return firstCommonClass(A->getSubClassMask(), B->getSubClassMask(), this);
+  return firstCommonClass(A->getSubClassMask(), B->getSubClassMask(), this,
+                          MRI);
 }
 
-const TargetRegisterClass *
-TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
-                                             const TargetRegisterClass *B,
-                                             unsigned Idx) const {
+const TargetRegisterClass *TargetRegisterInfo::getMatchingSuperRegClass(
+    const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned Idx,
+    const MachineRegisterInfo &MRI) const {
   assert(A && B && "Missing register class");
   assert(Idx && "Bad sub-register index");
 
@@ -312,14 +321,14 @@ TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
     if (RCI.getSubReg() == Idx)
       // The bit mask contains all register classes that are projected into B
       // by Idx. Find a class that is also a sub-class of A.
-      return firstCommonClass(RCI.getMask(), A->getSubClassMask(), this);
+      return firstCommonClass(RCI.getMask(), A->getSubClassMask(), this, MRI);
   return nullptr;
 }
 
-const TargetRegisterClass *TargetRegisterInfo::
-getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
-                       const TargetRegisterClass *RCB, unsigned SubB,
-                       unsigned &PreA, unsigned &PreB) const {
+const TargetRegisterClass *TargetRegisterInfo::getCommonSuperRegClass(
+    const TargetRegisterClass *RCA, unsigned SubA,
+    const TargetRegisterClass *RCB, unsigned SubB, unsigned &PreA,
+    unsigned &PreB, const MachineRegisterInfo &MRI) const {
   assert(RCA && SubA && RCB && SubB && "Invalid arguments");
 
   // Search all pairs of sub-register indices that project into RCA and RCB
@@ -352,7 +361,7 @@ getCommonSuperRegClass(const TargetRegisterClass *RCA, unsigned SubA,
     for (SuperRegClassIterator IB(RCB, this, true); IB.isValid(); ++IB) {
       // Check if a common super-register class exists for this index pair.
       const TargetRegisterClass *RC =
-        firstCommonClass(IA.getMask(), IB.getMask(), this);
+          firstCommonClass(IA.getMask(), IB.getMask(), this, MRI);
       if (!RC || getRegSizeInBits(*RC) < MinSize)
         continue;
 
@@ -384,7 +393,8 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI,
                                   const TargetRegisterClass *DefRC,
                                   unsigned DefSubReg,
                                   const TargetRegisterClass *SrcRC,
-                                  unsigned SrcSubReg) {
+                                  unsigned SrcSubReg,
+                                  const MachineRegisterInfo &MRI) {
   // Same register class.
   if (DefRC == SrcRC)
     return true;
@@ -393,7 +403,7 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI,
   unsigned SrcIdx, DefIdx;
   if (SrcSubReg && DefSubReg) {
     return TRI.getCommonSuperRegClass(SrcRC, SrcSubReg, DefRC, DefSubReg,
-                                      SrcIdx, DefIdx) != nullptr;
+                                      SrcIdx, DefIdx, MRI) != nullptr;
   }
 
   // At most one of the register is a sub register, make it Src to avoid
@@ -405,18 +415,19 @@ static bool shareSameRegisterFile(const TargetRegisterInfo &TRI,
 
   // One of the register is a sub register, check if we can get a superclass.
   if (SrcSubReg)
-    return TRI.getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg) != nullptr;
+    return TRI.getMatchingSuperRegClass(SrcRC, DefRC, SrcSubReg, MRI) !=
+           nullptr;
 
   // Plain copy.
-  return TRI.getCommonSubClass(DefRC, SrcRC) != nullptr;
+  return TRI.getCommonSubClass(DefRC, SrcRC, MRI) != nullptr;
 }
 
-bool TargetRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
-                                              unsigned DefSubReg,
-                                              const TargetRegisterClass *SrcRC,
-                                              unsigned SrcSubReg) const {
+bool TargetRegisterInfo::shouldRewriteCopySrc(
+    const TargetRegisterClass *DefRC, unsigned DefSubReg,
+    const TargetRegisterClass *SrcRC, unsigned SrcSubReg,
+    const MachineRegisterInfo &MRI) const {
   // If this source does not incur a cross register bank copy, use it.
-  return shareSameRegisterFile(*this, DefRC, DefSubReg, SrcRC, SrcSubReg);
+  return shareSameRegisterFile(*this, DefRC, DefSubReg, SrcRC, SrcSubReg, MRI);
 }
 
 // Compute target-independent register allocator hints to help eliminate copies.
@@ -507,7 +518,7 @@ TargetRegisterInfo::getRegSizeInBits(Register Reg,
     // The size is not directly available for physical registers.
     // Instead, we need to access a register class that contains Reg and
     // get the size of that register class.
-    RC = getMinimalPhysRegClass(Reg);
+    RC = getMinimalPhysRegClass(Reg, MRI);
     assert(RC && "Unable to deduce the register class");
     return getRegSizeInBits(*RC);
   }
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
index ebacbc420f8580..f38186a892f0e1 100644
--- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -1328,9 +1328,8 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi,
       if (UnfoldMCID.getNumDefs() == 1) {
         // Unfold the load.
         LLVM_DEBUG(dbgs() << "2addr:   UNFOLDING: " << MI);
-        const TargetRegisterClass *RC =
-          TRI->getAllocatableClass(
-            TII->getRegClass(UnfoldMCID, LoadRegIndex, TRI, *MF));
+        const TargetRegisterClass *RC = TRI->getAllocatableClass(
+            TII->getRegClass(UnfoldMCID, LoadRegIndex, TRI, *MF), *MRI);
         Register Reg = MRI->createVirtualRegister(RC);
         SmallVector<MachineInstr *, 2> NewMIs;
         if (!TII->unfoldMemoryOperand(*MF, MI, Reg,
@@ -1531,7 +1530,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
     if (SubRegB) {
       if (RegA.isVirtual()) {
         assert(TRI->getMatchingSuperRegClass(RC, MRI->getRegClass(RegA),
-                                             SubRegB) &&
+                                             SubRegB, *MRI) &&
                "tied subregister must be a truncation");
         // The superreg class will not be used to constrain the subreg class.
         RC = nullptr;
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 5cc612e89162af..f2090ffb04d842 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -3451,7 +3451,8 @@ bool AArch64FrameLowering::assignCalleeSavedSpillSlots(
 
   for (auto &CS : CSI) {
     Register Reg = CS.getReg();
-    const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC =
+        RegInfo->getMinimalPhysRegClass(Reg, MF.getRegInfo());
 
     unsigned Size = RegInfo->getSpillSize(*RC);
     Align Alignment(RegInfo->getSpillAlign(*RC));
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 02943b8a4ab158..c8cd27d2473744 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -703,15 +703,15 @@ bool AArch64InstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
                                        int &FalseCycles) const {
   // Check register classes.
   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
-  const TargetRegisterClass *RC =
-      RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
+  const TargetRegisterClass *RC = RI.getCommonSubClass(
+      MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI);
   if (!RC)
     return false;
 
   // Also need to check the dest regclass, in case we're trying to optimize
   // something like:
   // %1(gpr) = PHI %2(fpr), bb1, %(fpr), bb2
-  if (!RI.getCommonSubClass(RC, MRI.getRegClass(DstReg)))
+  if (!RI.getCommonSubClass(RC, MRI.getRegClass(DstReg), MRI))
     return false;
 
   // Expanding cbz/tbz requires an extra cycle of latency on the condition.
@@ -5557,8 +5557,9 @@ MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl(
     // This is slightly expensive to compute for physical regs since
     // getMinimalPhysRegClass is slow.
     auto getRegClass = [&](unsigned Reg) {
-      return Register::isVirtualRegister(Reg) ? MRI.getRegClass(Reg)
-                                              : TRI.getMinimalPhysRegClass(Reg);
+      return Register::isVirtualRegister(Reg)
+                 ? MRI.getRegClass(Reg)
+                 : TRI.getMinimalPhysRegClass(Reg, MRI);
     };
 
     if (DstMO.getSubReg() == 0 && SrcMO.getSubReg() == 0) {
diff --git a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
index d0adb78b231a76..2583acd67ee1a4 100644
--- a/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
@@ -879,7 +879,6 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
   if (RenameReg) {
     MCRegister RegToRename = getLdStRegOp(*I).getReg();
     DefinedInBB.addReg(*RenameReg);
-
     // Return the sub/super register for RenameReg, matching the size of
     // OriginalReg.
     auto GetMatchingSubReg =
@@ -895,6 +894,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
     std::function<bool(MachineInstr &, bool)> UpdateMIs =
         [this, RegToRename, GetMatchingSubReg, MergeForward](MachineInstr &MI,
                                                              bool IsDef) {
+          const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
           if (IsDef) {
             bool SeenDef = false;
             for (unsigned OpIdx = 0; OpIdx < MI.getNumOperands(); ++OpIdx) {
@@ -916,7 +916,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
                   if (!isRewritableImplicitDef(MI.getOpcode()))
                     continue;
                   MatchingReg = GetMatchingSubReg(
-                      TRI->getMinimalPhysRegClass(MOP.getReg()));
+                      TRI->getMinimalPhysRegClass(MOP.getReg(), MRI));
                 }
                 MOP.setReg(MatchingReg);
                 SeenDef = true;
@@ -936,7 +936,7 @@ AArch64LoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
                   MatchingReg = GetMatchingSubReg(RC);
                 else
                   MatchingReg = GetMatchingSubReg(
-                      TRI->getMinimalPhysRegClass(MOP.getReg()));
+                      TRI->getMinimalPhysRegClass(MOP.getReg(), MRI));
                 assert(MatchingReg != AArch64::NoRegister &&
                        "Cannot find matching regs for renaming");
                 MOP.setReg(MatchingReg);
@@ -1422,7 +1422,8 @@ static bool areCandidatesToMergeOrPair(MachineInstr &FirstMI, MachineInstr &MI,
 static bool canRenameMOP(const MachineOperand &MOP,
                          const TargetRegisterInfo *TRI) {
   if (MOP.isReg()) {
-    auto *RegClass = TRI->getMinimalPhysRegClass(MOP.getReg());
+    const MachineRegisterInfo &MRI = MOP.getParent()->getMF()->getRegInfo();
+    auto *RegClass = TRI->getMinimalPhysRegClass(MOP.getReg(), MRI);
     // Renaming registers with multiple disjunct sub-registers (e.g. the
     // result of a LD3) means that all sub-registers are renamed, potentially
     // impacting other instructions we did not check. Bail out.
@@ -1496,6 +1497,7 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween,
     // loop.
     FoundDef = IsDef;
 
+    const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
     // For defs, check if we can rename the first def of RegToRename.
     if (FoundDef) {
       // For some pseudo instructions, we might not generate code in the end
@@ -1518,7 +1520,7 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween,
           LLVM_DEBUG(dbgs() << "  Cannot rename " << MOP << " in " << MI);
           return false;
         }
-        RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg()));
+        RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg(), MRI));
       }
       return true;
     } else {
@@ -1531,7 +1533,7 @@ canRenameUpToDef(MachineInstr &FirstMI, LiveRegUnits &UsedInBetween,
           LLVM_DEBUG(dbgs() << "  Cannot rename " << MOP << " in " << MI);
           return false;
         }
-        RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg()));
+        RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg(), MRI));
       }
     }
     return true;
@@ -1577,6 +1579,8 @@ static bool canRenameUntilSecondLoad(
           return false;
         }
 
+        const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
+
         for (auto &MOP : MI.operands()) {
           if (!MOP.isReg() || MOP.isDebug() || !MOP.getReg() ||
               !TRI->regsOverlap(MOP.getReg(), RegToRename))
@@ -1585,7 +1589,8 @@ static bool canRenameUntilSecondLoad(
             LLVM_DEBUG(dbgs() << "  Cannot rename " << MOP << " in " << MI);
             return false;
           }
-          RequiredClasses.insert(TRI->getMinimalPhysRegClass(MOP.getReg()));
+          RequiredClasses.insert(
+              TRI->getMinimalPhysRegClass(MOP.getReg(), MRI));
         }
 
         return true;
@@ -1625,7 +1630,7 @@ static std::optional<MCPhysReg> tryToFindRegisterToRename(
     });
   };
 
-  auto *RegClass = TRI->getMinimalPhysRegClass(Reg);
+  auto *RegClass = TRI->getMinimalPhysRegClass(Reg, RegInfo);
   for (const MCPhysReg &PR : *RegClass) {
     if (DefinedInBB.available(PR) && UsedInBetween.available(PR) &&
         !RegInfo.isReserved(PR) && !AnySubOrSuperRegCalleePreserved(PR) &&
@@ -1653,7 +1658,9 @@ static std::optional<MCPhysReg> findRenameRegForSameLdStRegPair(
   if (!DebugCounter::shouldExecute(RegRenamingCounter))
     return RenameReg;
 
-  auto *RegClass = TRI->getMinimalPhysRegClass(getLdStRegOp(FirstMI).getReg());
+  const MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
+  auto *RegClass =
+      TRI->getMinimalPhysRegClass(getLdStRegOp(FirstMI).getReg(), MRI);
   MachineFunction &MF = *FirstMI.getParent()->getParent();
   if (!RegClass || !MF.getRegInfo().tracksLiveness())
     return RenameReg;
diff --git a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
index 019b64dd871e2a..53159742d14ad5 100644
--- a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
@@ -208,7 +208,8 @@ const BitVector &GCNRewritePartialRegUses::getAllocatableAndAlignedRegClassMask(
     BV.resize(TRI->getNumRegClasses());
     for (unsigned ClassID = 0; ClassID < TRI->getNumRegClasses(); ++ClassID) {
       auto *RC = TRI->getRegClass(ClassID);
-      if (RC->isAllocatable() && TRI->isRegClassAligned(RC, AlignNumBits))
+      if (RC->isAllocatable() && MRI->isEnabled(RC) &&
+          TRI->isRegClassAligned(RC, AlignNumBits))
         BV.set(ClassID);
     }
   }
@@ -437,7 +438,7 @@ bool GCNRewritePartialRegUses::rewriteReg(Register Reg) const {
       if (const TargetRegisterClass *OpDescRC = getOperandRegClass(MO)) {
         LLVM_DEBUG(dbgs() << TRI->getRegClassName(SubRegRC) << " & "
                           << TRI->getRegClassName(OpDescRC) << " = ");
-        SubRegRC = TRI->getCommonSubClass(SubRegRC, OpDescRC);
+        SubRegRC = TRI->getCommonSubClass(SubRegRC, OpDescRC, *MRI);
       }
     }
 
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
index 5ccf21f76015de..782d29e288e1fd 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp
@@ -16285,7 +16285,8 @@ SITargetLowering::getTargetMMOFlags(const Instruction &I) const {
 
 bool SITargetLowering::checkForPhysRegDependency(
     SDNode *Def, SDNode *User, unsigned Op, const TargetRegisterInfo *TRI,
-    const TargetInstrInfo *TII, unsigned &PhysReg, int &Cost) const {
+    const MachineRegisterInfo &MRI, const TargetInstrInfo *TII,
+    unsigned &PhysReg, int &Cost) const {
   if (User->getOpcode() != ISD::CopyToReg)
     return false;
   if (!Def->isMachineOpcode())
@@ -16300,8 +16301,8 @@ bool SITargetLowering::checkForPhysRegDependency(
   const MCInstrDesc &II = TII->get(MDef->getMachineOpcode());
   if (II.isCompare() && II.hasImplicitDefOfPhysReg(AMDGPU::SCC)) {
     PhysReg = AMDGPU::SCC;
-    const TargetRegisterClass *RC =
-        TRI->getMinimalPhysRegClass(PhysReg, Def->getSimpleValueType(ResNo));
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(
+        PhysReg, MRI, Def->getSimpleValueType(ResNo));
     Cost = RC->getCopyCost();
     return true;
   }
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.h b/llvm/lib/Target/AMDGPU/SIISelLowering.h
index 89da4428e3ab0a..33ea15834fba26 100644
--- a/llvm/lib/Target/AMDGPU/SIISelLowering.h
+++ b/llvm/lib/Target/AMDGPU/SIISelLowering.h
@@ -530,6 +530,7 @@ class SITargetLowering final : public AMDGPUTargetLowering {
 
   bool checkForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
                                  const TargetRegisterInfo *TRI,
+                                 const MachineRegisterInfo &MRI,
                                  const TargetInstrInfo *TII, unsigned &PhysReg,
                                  int &Cost) const override;
 
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index f4b21b7dfac391..c8083ddf9f9515 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -2559,7 +2559,7 @@ void SIInstrInfo::reMaterialize(MachineBasicBlock &MBB,
 
     const MCInstrDesc &TID = get(NewOpcode);
     const TargetRegisterClass *NewRC =
-        RI.getAllocatableClass(getRegClass(TID, 0, &RI, *MF));
+        RI.getAllocatableClass(getRegClass(TID, 0, &RI, *MF), MRI);
     MRI.setRegClass(DestReg, NewRC);
 
     UseMO->setReg(DestReg);
@@ -4683,7 +4683,7 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr &MI,
       if (RI.hasVectorRegisters(RC) && MO.getSubReg()) {
         const TargetRegisterClass *SubRC =
             RI.getSubRegisterClass(RC, MO.getSubReg());
-        RC = RI.getCompatibleSubRegClass(RC, SubRC, MO.getSubReg());
+        RC = RI.getCompatibleSubRegClass(RC, SubRC, MO.getSubReg(), MRI);
         if (RC)
           RC = SubRC;
       }
@@ -5665,7 +5665,7 @@ bool SIInstrInfo::isLegalRegOperand(const MachineRegisterInfo &MRI,
     if (!SuperRC)
       return false;
 
-    DRC = RI.getMatchingSuperRegClass(SuperRC, DRC, MO.getSubReg());
+    DRC = RI.getMatchingSuperRegClass(SuperRC, DRC, MO.getSubReg(), MRI);
     if (!DRC)
       return false;
   }
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index 4c5978cdc6665c..63ebc543d0b279 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -1387,7 +1387,7 @@ inline bool isOfRegClass(const TargetInstrInfo::RegSubRegPair &P,
   if (!P.SubReg)
     return RC == &TRC;
   auto *TRI = MRI.getTargetRegisterInfo();
-  return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg);
+  return RC == TRI->getMatchingSuperRegClass(RC, &TRC, P.SubReg, MRI);
 }
 
 /// \brief Create RegSubRegPair from a register MachineOperand
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index 4b13825040ebe6..128c17e2a0a0ae 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -103,7 +103,7 @@ static void insertCSRSaves(MachineBasicBlock &SaveBlock,
 
       MachineInstrSpan MIS(I, &SaveBlock);
       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(
-          Reg, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32);
+          Reg, MRI, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32);
 
       // If this value was already livein, we probably have a direct use of the
       // incoming register value, so don't kill at the spill point. This happens
@@ -135,6 +135,7 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
   const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
   const SIRegisterInfo *RI = ST.getRegisterInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   // Restore all registers immediately before the return and any
   // terminators that precede it.
   MachineBasicBlock::iterator I = RestoreBlock.getFirstTerminator();
@@ -144,7 +145,7 @@ static void insertCSRRestores(MachineBasicBlock &RestoreBlock,
     for (const CalleeSavedInfo &CI : reverse(CSI)) {
       Register Reg = CI.getReg();
       const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(
-          Reg, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32);
+          Reg, MRI, Reg == RI->getReturnAddressReg(MF) ? MVT::i64 : MVT::i32);
 
       TII.loadRegFromStackSlot(RestoreBlock, I, Reg, CI.getFrameIdx(), RC, TRI,
                                Register());
@@ -233,7 +234,7 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs(
 
       if (SavedRegs.test(Reg)) {
         const TargetRegisterClass *RC =
-          TRI->getMinimalPhysRegClass(Reg, MVT::i32);
+            TRI->getMinimalPhysRegClass(Reg, MRI, MVT::i32);
         int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
                                            TRI->getSpillAlign(*RC), true);
 
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index 79a7d1cf66c4d3..8454636ad0a436 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -2906,13 +2906,12 @@ SIRegisterInfo::getEquivalentSGPRClass(const TargetRegisterClass *VRC) const {
   return SRC;
 }
 
-const TargetRegisterClass *
-SIRegisterInfo::getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
-                                         const TargetRegisterClass *SubRC,
-                                         unsigned SubIdx) const {
+const TargetRegisterClass *SIRegisterInfo::getCompatibleSubRegClass(
+    const TargetRegisterClass *SuperRC, const TargetRegisterClass *SubRC,
+    unsigned SubIdx, const MachineRegisterInfo &MRI) const {
   // Ensure this subregister index is aligned in the super register.
   const TargetRegisterClass *MatchRC =
-      getMatchingSuperRegClass(SuperRC, SubRC, SubIdx);
+      getMatchingSuperRegClass(SuperRC, SubRC, SubIdx, MRI);
   return MatchRC && MatchRC->hasSubClassEq(SuperRC) ? MatchRC : nullptr;
 }
 
@@ -2926,10 +2925,9 @@ bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const {
 }
 
 bool SIRegisterInfo::shouldRewriteCopySrc(
-  const TargetRegisterClass *DefRC,
-  unsigned DefSubReg,
-  const TargetRegisterClass *SrcRC,
-  unsigned SrcSubReg) const {
+    const TargetRegisterClass *DefRC, unsigned DefSubReg,
+    const TargetRegisterClass *SrcRC, unsigned SrcSubReg,
+    const MachineRegisterInfo &MRI) const {
   // We want to prefer the smallest register class possible, so we don't want to
   // stop and rewrite on anything that looks like a subregister
   // extract. Operations mostly don't care about the super register class, so we
@@ -2946,7 +2944,7 @@ bool SIRegisterInfo::shouldRewriteCopySrc(
   //  => %3 = COPY %0
 
   // Plain copy.
-  return getCommonSubClass(DefRC, SrcRC) != nullptr;
+  return getCommonSubClass(DefRC, SrcRC, MRI) != nullptr;
 }
 
 bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const {
@@ -3121,7 +3119,7 @@ SIRegisterInfo::getConstrainedRegClassForOperand(const MachineOperand &MO,
     return getRegClassForTypeOnBank(MRI.getType(MO.getReg()), *RB);
 
   if (const auto *RC = RCOrRB.dyn_cast<const TargetRegisterClass *>())
-    return getAllocatableClass(RC);
+    return getAllocatableClass(RC, MRI);
 
   return nullptr;
 }
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
index 88d5686720985e..f732682f42e7bc 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
@@ -264,13 +264,14 @@ class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
   /// a register tuple), return null.
   const TargetRegisterClass *
   getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
-                           const TargetRegisterClass *SubRC,
-                           unsigned SubIdx) const;
+                           const TargetRegisterClass *SubRC, unsigned SubIdx,
+                           const MachineRegisterInfo &MRI) const;
 
   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
                             unsigned DefSubReg,
                             const TargetRegisterClass *SrcRC,
-                            unsigned SrcSubReg) const override;
+                            unsigned SrcSubReg,
+                            const MachineRegisterInfo &MRI) const override;
 
   /// \returns True if operands defined with this operand type can accept
   /// a literal constant (i.e. any 32-bit immediate).
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 9adf758b46c481..a85f4099e81f6d 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -933,16 +933,16 @@ bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI,
   return false;
 }
 
-bool ARMBaseRegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
-                                               unsigned DefSubReg,
-                                               const TargetRegisterClass *SrcRC,
-                                               unsigned SrcSubReg) const {
+bool ARMBaseRegisterInfo::shouldRewriteCopySrc(
+    const TargetRegisterClass *DefRC, unsigned DefSubReg,
+    const TargetRegisterClass *SrcRC, unsigned SrcSubReg,
+    const MachineRegisterInfo &MRI) const {
   // We can't extract an SPR from an arbitary DPR (as opposed to a DPR_VFP2).
   if (DefRC == &ARM::SPRRegClass && DefSubReg == 0 &&
       SrcRC == &ARM::DPRRegClass &&
       (SrcSubReg == ARM::ssub_0 || SrcSubReg == ARM::ssub_1))
     return false;
 
-  return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg,
-                                                  SrcRC, SrcSubReg);
+  return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC,
+                                                  SrcSubReg, MRI);
 }
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
index 53803cff8b90ac..cdc362d7a91f42 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
@@ -237,7 +237,8 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
                             unsigned DefSubReg,
                             const TargetRegisterClass *SrcRC,
-                            unsigned SrcSubReg) const override;
+                            unsigned SrcSubReg,
+                            const MachineRegisterInfo &MRI) const override;
 
   int getSEHRegNum(unsigned i) const { return getEncodingValue(i); }
 
diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
index 1c8213b668f71a..ace52074880266 100644
--- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
+++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
@@ -124,7 +124,8 @@ bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
     const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
     const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
 
-    const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC =
+        TRI.getMinimalPhysRegClass(Reg, MF->getRegInfo());
     unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8;
     assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported.");
 
diff --git a/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/llvm/lib/Target/AVR/AVRFrameLowering.cpp
index 64dd0338bf60ed..1b79758a01fc35 100644
--- a/llvm/lib/Target/AVR/AVRFrameLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRFrameLowering.cpp
@@ -253,6 +253,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters(
   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
   const TargetInstrInfo &TII = *STI.getInstrInfo();
   AVRMachineFunctionInfo *AVRFI = MF.getInfo<AVRMachineFunctionInfo>();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
   for (const CalleeSavedInfo &I : llvm::reverse(CSI)) {
     Register Reg = I.getReg();
@@ -268,7 +269,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters(
           break;
         }
 
-    assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
+    assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg, MRI)) == 8 &&
            "Invalid register size");
 
     // Add the callee-saved register as live-in only if it is not already a
@@ -301,11 +302,12 @@ bool AVRFrameLowering::restoreCalleeSavedRegisters(
   const MachineFunction &MF = *MBB.getParent();
   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
   const TargetInstrInfo &TII = *STI.getInstrInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
   for (const CalleeSavedInfo &CCSI : CSI) {
     Register Reg = CCSI.getReg();
 
-    assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
+    assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg, MRI)) == 8 &&
            "Invalid register size");
 
     BuildMI(MBB, MI, DL, TII.get(AVR::POPRd), Reg);
diff --git a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
index cedcbff1db24fc..fc8e090328d822 100644
--- a/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
+++ b/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
@@ -468,6 +468,7 @@ bool CSKYFrameLowering::spillCalleeSavedRegisters(
 
   MachineFunction *MF = MBB.getParent();
   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   DebugLoc DL;
   if (MI != MBB.end() && !MI->isDebugInstr())
     DL = MI->getDebugLoc();
@@ -475,7 +476,7 @@ bool CSKYFrameLowering::spillCalleeSavedRegisters(
   for (auto &CS : CSI) {
     // Insert the spill to the stack frame.
     Register Reg = CS.getReg();
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.storeRegToStackSlot(MBB, MI, Reg, true, CS.getFrameIdx(), RC, TRI,
                             Register());
   }
@@ -491,13 +492,14 @@ bool CSKYFrameLowering::restoreCalleeSavedRegisters(
 
   MachineFunction *MF = MBB.getParent();
   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   DebugLoc DL;
   if (MI != MBB.end() && !MI->isDebugInstr())
     DL = MI->getDebugLoc();
 
   for (auto &CS : reverse(CSI)) {
     Register Reg = CS.getReg();
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI,
                              Register());
     assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!");
diff --git a/llvm/lib/Target/Hexagon/BitTracker.cpp b/llvm/lib/Target/Hexagon/BitTracker.cpp
index 4d5789a3c5fe19..855e64b4b81c2d 100644
--- a/llvm/lib/Target/Hexagon/BitTracker.cpp
+++ b/llvm/lib/Target/Hexagon/BitTracker.cpp
@@ -712,7 +712,7 @@ BT::BitMask BT::MachineEvaluator::mask(Register Reg, unsigned Sub) const {
 }
 
 uint16_t BT::MachineEvaluator::getPhysRegBitWidth(MCRegister Reg) const {
-  const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg);
+  const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg, MRI);
   return TRI.getRegSizeInBits(PC);
 }
 
diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
index a027f2cedca0a0..d44ea12d154b91 100644
--- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
@@ -120,7 +120,8 @@ uint16_t HexagonEvaluator::getPhysRegBitWidth(MCRegister Reg) const {
         return TRI.getRegSizeInBits(RC);
   }
   // Default treatment for other physical registers.
-  if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg))
+  if (const TargetRegisterClass *RC =
+          TRI.getMinimalPhysRegClass(Reg, MF.getRegInfo()))
     return TRI.getRegSizeInBits(*RC);
 
   llvm_unreachable(
diff --git a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp
index e1005296d63752..e71cc55766a5f8 100644
--- a/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonExpandCondsets.cpp
@@ -612,7 +612,7 @@ unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO,
       PhysR = RS.Reg;
     }
     MCRegister PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub);
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS, *MRI);
     switch (TRI->getRegSizeInBits(*RC)) {
       case 32:
         return IfTrue ? Hexagon::A2_tfrt : Hexagon::A2_tfrf;
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 232651132d6e4f..b1ac44a06418c5 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -1411,6 +1411,7 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
     return true;
   }
 
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   for (const CalleeSavedInfo &I : CSI) {
     Register Reg = I.getReg();
     // Add live in registers. We treat eh_return callee saved register r0 - r3
@@ -1418,7 +1419,7 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
     // supposed to be killed.
     bool IsKill = !HRI.isEHReturnCalleeSaveReg(Reg);
     int FI = I.getFrameIdx();
-    const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg, MRI);
     HII.storeRegToStackSlot(MBB, MI, Reg, IsKill, FI, RC, &HRI, Register());
     if (IsKill)
       MBB.addLiveIn(Reg);
@@ -1480,9 +1481,10 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
     return true;
   }
 
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   for (const CalleeSavedInfo &I : CSI) {
     Register Reg = I.getReg();
-    const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = HRI.getMinimalPhysRegClass(Reg, MRI);
     int FI = I.getFrameIdx();
     HII.loadRegFromStackSlot(MBB, MI, Reg, FI, RC, &HRI, Register());
   }
@@ -1560,6 +1562,7 @@ bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF,
       const TargetRegisterInfo *TRI, std::vector<CalleeSavedInfo> &CSI) const {
   LLVM_DEBUG(dbgs() << __func__ << " on " << MF.getName() << '\n');
   MachineFrameInfo &MFI = MF.getFrameInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   BitVector SRegs(Hexagon::NUM_TARGET_REGS);
 
   // Generate a set of unique, callee-saved registers (SRegs), where each
@@ -1665,7 +1668,7 @@ bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF,
   for (const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
     if (!SRegs[S->Reg])
       continue;
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(S->Reg, MRI);
     int FI = MFI.CreateFixedSpillStackObject(TRI->getSpillSize(*RC), S->Offset);
     MinOffset = std::min(MinOffset, S->Offset);
     CSI.push_back(CalleeSavedInfo(S->Reg, FI));
@@ -1677,7 +1680,7 @@ bool HexagonFrameLowering::assignCalleeSavedSpillSlots(MachineFunction &MF,
   // such register, create a non-fixed stack object.
   for (int x = SRegs.find_first(); x >= 0; x = SRegs.find_next(x)) {
     Register R = x;
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(R, MRI);
     unsigned Size = TRI->getSpillSize(*RC);
     int Off = MinOffset - Size;
     Align Alignment = std::min(TRI->getSpillAlign(*RC), getStackAlign());
diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
index b9bf26ba7cca1e..20bd79352bae1c 100644
--- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -1730,12 +1730,14 @@ bool HexagonInstrInfo::ClobbersPredicate(MachineInstr &MI,
                                          std::vector<MachineOperand> &Pred,
                                          bool SkipDead) const {
   const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
+  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
 
   for (const MachineOperand &MO : MI.operands()) {
     if (MO.isReg()) {
       if (!MO.isDef())
         continue;
-      const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
+      const TargetRegisterClass *RC =
+          HRI.getMinimalPhysRegClass(MO.getReg(), MRI);
       if (RC == &Hexagon::PredRegsRegClass) {
         Pred.push_back(MO);
         return true;
diff --git a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index 56472d633694ae..7c21a12f00db56 100644
--- a/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -705,13 +705,14 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI,
     unsigned predRegNumSrc = 0;
     unsigned predRegNumDst = 0;
     const TargetRegisterClass* predRegClass = nullptr;
+    const MachineRegisterInfo &MRI = PacketMI.getMF()->getRegInfo();
 
     // Get predicate register used in the source instruction.
     for (auto &MO : PacketMI.operands()) {
       if (!MO.isReg())
         continue;
       predRegNumSrc = MO.getReg();
-      predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
+      predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc, MRI);
       if (predRegClass == &Hexagon::PredRegsRegClass)
         break;
     }
@@ -723,7 +724,7 @@ bool HexagonPacketizerList::canPromoteToNewValueStore(const MachineInstr &MI,
       if (!MO.isReg())
         continue;
       predRegNumDst = MO.getReg();
-      predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
+      predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst, MRI);
       if (predRegClass == &Hexagon::PredRegsRegClass)
         break;
     }
@@ -1406,6 +1407,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
   if (!SUJ->isSucc(SUI))
     return true;
 
+  const MachineRegisterInfo &MRI = I.getMF()->getRegInfo();
+
   for (unsigned i = 0; i < SUJ->Succs.size(); ++i) {
     if (FoundSequentialDependence)
       break;
@@ -1433,7 +1436,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
     const TargetRegisterClass *RC = nullptr;
     if (DepType == SDep::Data) {
       DepReg = SUJ->Succs[i].getReg();
-      RC = HRI->getMinimalPhysRegClass(DepReg);
+      RC = HRI->getMinimalPhysRegClass(DepReg, MRI);
     }
 
     if (I.isCall() || HII->isJumpR(I) || I.isReturn() || HII->isTailCall(I)) {
diff --git a/llvm/lib/Target/Hexagon/RDFCopy.cpp b/llvm/lib/Target/Hexagon/RDFCopy.cpp
index b26821cd01718d..1f2d2ca88472f0 100644
--- a/llvm/lib/Target/Hexagon/RDFCopy.cpp
+++ b/llvm/lib/Target/Hexagon/RDFCopy.cpp
@@ -48,8 +48,9 @@ bool CopyPropagation::interpretAsCopy(const MachineInstr *MI, EqualityMap &EM) {
       assert(Register::isPhysicalRegister(DstR.Reg));
       assert(Register::isPhysicalRegister(SrcR.Reg));
       const TargetRegisterInfo &TRI = DFG.getTRI();
-      if (TRI.getMinimalPhysRegClass(DstR.Reg) !=
-          TRI.getMinimalPhysRegClass(SrcR.Reg))
+      const MachineRegisterInfo &MRI = DFG.getMF().getRegInfo();
+      if (TRI.getMinimalPhysRegClass(DstR.Reg, MRI) !=
+          TRI.getMinimalPhysRegClass(SrcR.Reg, MRI))
         return false;
       if (!DFG.isTracked(SrcR) || !DFG.isTracked(DstR))
         return false;
@@ -158,7 +159,8 @@ bool CopyPropagation::run() {
 
   auto MinPhysReg = [this] (RegisterRef RR) -> unsigned {
     const TargetRegisterInfo &TRI = DFG.getTRI();
-    const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg);
+    const TargetRegisterClass &RC =
+        *TRI.getMinimalPhysRegClass(RR.Reg, DFG.getMF().getRegInfo());
     if ((RC.LaneMask & RR.Mask) == RC.LaneMask)
       return RR.Reg;
     for (MCSubRegIndexIterator S(RR.Reg, &TRI); S.isValid(); ++S)
diff --git a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
index dc2d61a6e4740e..063ae2490417e2 100644
--- a/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchFrameLowering.cpp
@@ -463,7 +463,8 @@ bool LoongArchFrameLowering::spillCalleeSavedRegisters(
     // LoongArchTargetLowering::lowerRETURNADDR, don't set kill flag.
     bool IsKill =
         !(Reg == LoongArch::R1 && MF->getFrameInfo().isReturnAddressTaken());
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC =
+        TRI->getMinimalPhysRegClass(Reg, MF->getRegInfo());
     TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, CS.getFrameIdx(), RC, TRI,
                             Register());
   }
diff --git a/llvm/lib/Target/Mips/MipsFrameLowering.cpp b/llvm/lib/Target/Mips/MipsFrameLowering.cpp
index 99d225f9abfe89..b152d70f7970b4 100644
--- a/llvm/lib/Target/Mips/MipsFrameLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsFrameLowering.cpp
@@ -114,6 +114,7 @@ bool MipsFrameLowering::hasBP(const MachineFunction &MF) const {
 uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const {
   const MachineFrameInfo &MFI = MF.getFrameInfo();
   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
   int64_t Size = 0;
 
@@ -124,7 +125,7 @@ uint64_t MipsFrameLowering::estimateStackSize(const MachineFunction &MF) const {
 
   // Conservatively assume all callee-saved registers will be saved.
   for (const MCPhysReg *R = TRI.getCalleeSavedRegs(&MF); *R; ++R) {
-    unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R));
+    unsigned RegSize = TRI.getSpillSize(*TRI.getMinimalPhysRegClass(*R, MRI));
     Size = alignTo(Size + RegSize, RegSize);
   }
 
diff --git a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
index 38f6889a523583..a923d21de8fcf5 100644
--- a/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsSEFrameLowering.cpp
@@ -259,7 +259,8 @@ bool ExpandPseudo::expandCopyACC(MachineBasicBlock &MBB, Iter I,
   //  copy dst_hi, $vr1
 
   unsigned Dst = I->getOperand(0).getReg(), Src = I->getOperand(1).getReg();
-  const TargetRegisterClass *DstRC = RegInfo.getMinimalPhysRegClass(Dst);
+  const TargetRegisterClass *DstRC =
+      RegInfo.getMinimalPhysRegClass(Dst, MBB.getParent()->getRegInfo());
   unsigned VRegSize = RegInfo.getRegSizeInBits(*DstRC) / 16;
   const TargetRegisterClass *RC = RegInfo.intRegClass(VRegSize);
   Register VR0 = MRI.createVirtualRegister(RC);
@@ -796,6 +797,7 @@ bool MipsSEFrameLowering::spillCalleeSavedRegisters(
     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
   MachineFunction *MF = MBB.getParent();
   const TargetInstrInfo &TII = *STI.getInstrInfo();
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
 
   for (const CalleeSavedInfo &I : CSI) {
     // Add the callee-saved register as live-in. Do not add if the register is
@@ -831,7 +833,7 @@ bool MipsSEFrameLowering::spillCalleeSavedRegisters(
 
     // Insert the spill to the stack frame.
     bool IsKill = !IsRAAndRetAddrIsTaken;
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, I.getFrameIdx(), RC, TRI,
                             Register());
   }
diff --git a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
index 6dcb59a3a57f85..e697920f948542 100644
--- a/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
@@ -2502,7 +2502,7 @@ bool PPCFrameLowering::spillCalleeSavedRegisters(
         }
         Spilled.set(Dst);
       } else {
-        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
         // Use !IsLiveIn for the kill flag.
         // We do not want to kill registers that are live in this function
         // before their use because they will become undefined registers.
@@ -2605,6 +2605,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
   bool CR4Spilled = false;
   unsigned CSIIndex = 0;
   BitVector Restored(TRI->getNumRegs());
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
 
   // Initialize insertion-point logic; we will be restoring in reverse
   // order of spill.
@@ -2677,7 +2678,7 @@ bool PPCFrameLowering::restoreCalleeSavedRegisters(
 
       } else {
         // Default behavior for non-CR saves.
-        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
 
         // Functions without NoUnwind need to preserve the order of elements in
         // saved vector registers.
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 5f5eb31a5a85fa..fe8df2a6012336 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -1526,8 +1526,8 @@ bool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
 
   // Check register classes.
   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
-  const TargetRegisterClass *RC =
-    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
+  const TargetRegisterClass *RC = RI.getCommonSubClass(
+      MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI);
   if (!RC)
     return false;
 
@@ -1559,8 +1559,8 @@ void PPCInstrInfo::insertSelect(MachineBasicBlock &MBB,
 
   // Get the register classes.
   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
-  const TargetRegisterClass *RC =
-    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
+  const TargetRegisterClass *RC = RI.getCommonSubClass(
+      MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI);
   assert(RC && "TrueReg and FalseReg must have overlapping register classes");
 
   bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 0f450a4bf9692b..74073f2f07f48c 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -456,6 +456,7 @@ bool PPCRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) co
   const PPCInstrInfo *InstrInfo =  Subtarget.getInstrInfo();
   const MachineFrameInfo &MFI = MF.getFrameInfo();
   const std::vector<CalleeSavedInfo> &Info = MFI.getCalleeSavedInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
   LLVM_DEBUG(dbgs() << "requiresFrameIndexScavenging for " << MF.getName()
                     << ".\n");
@@ -486,7 +487,7 @@ bool PPCRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) co
     int FrIdx = CSI.getFrameIdx();
     Register Reg = CSI.getReg();
 
-    const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = getMinimalPhysRegClass(Reg, MRI);
     unsigned Opcode = InstrInfo->getStoreOpcodeForSpill(RC);
     if (!MFI.isFixedObjectIndex(FrIdx)) {
       // This is not a fixed object. If it requires alignment then we may still
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 8bac41372b5a83..8010da5dc5634e 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1391,10 +1391,11 @@ bool RISCVFrameLowering::assignCalleeSavedSpillSlots(
 
   MachineFrameInfo &MFI = MF.getFrameInfo();
   const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
   for (auto &CS : CSI) {
     unsigned Reg = CS.getReg();
-    const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg, MRI);
     unsigned Size = RegInfo->getSpillSize(*RC);
 
     // This might need a fixed stack slot.
@@ -1483,10 +1484,11 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
 
   // Manually spill values not spilled by libcall & Push/Pop.
   const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
   for (auto &CS : UnmanagedCSI) {
     // Insert the spill to the stack frame.
     Register Reg = CS.getReg();
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.storeRegToStackSlot(MBB, MI, Reg, !MBB.isLiveIn(Reg), CS.getFrameIdx(),
                             RC, TRI, Register());
   }
@@ -1513,9 +1515,10 @@ bool RISCVFrameLowering::restoreCalleeSavedRegisters(
   // load-to-use data hazard between loading RA and return by RA.
   // loadRegFromStackSlot can insert multiple instructions.
   const auto &UnmanagedCSI = getUnmanagedCSI(*MF, CSI);
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
   for (auto &CS : UnmanagedCSI) {
     Register Reg = CS.getReg();
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI,
                              Register());
     assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!");
diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
index 10bf1e88d74146..f6bf254cd81c5d 100644
--- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp
@@ -555,7 +555,7 @@ bool RISCVRegisterInfo::needsFrameBaseReg(MachineInstr *MI,
   BitVector ReservedRegs = getReservedRegs(MF);
   for (const MCPhysReg *R = MRI.getCalleeSavedRegs(); MCPhysReg Reg = *R; ++R) {
     if (!ReservedRegs.test(Reg))
-      CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg));
+      CalleeSavedSize += getSpillSize(*getMinimalPhysRegClass(Reg, MRI));
   }
 
   int64_t MaxFPOffset = Offset - CalleeSavedSize;
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index 80c994a32ea96a..a1b023618aa369 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -185,6 +185,7 @@ bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots(
   unsigned LowGPR = 0;
   unsigned HighGPR = SystemZ::R15D;
   int StartSPOffset = SystemZMC::ELFCallFrameSize;
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   for (auto &CS : CSI) {
     Register Reg = CS.getReg();
     int Offset = getRegSpillOffset(MF, Reg);
@@ -227,7 +228,7 @@ bool SystemZELFFrameLowering::assignCalleeSavedSpillSlots(
     if (CS.getFrameIdx() != INT32_MAX)
       continue;
     Register Reg = CS.getReg();
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     unsigned Size = TRI->getSpillSize(*RC);
     CurrOffset -= Size;
     assert(CurrOffset % 8 == 0 &&
@@ -1009,6 +1010,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
   int LowSpillOffset = INT32_MAX;
   Register HighGPR = 0;
   int HighOffset = -1;
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
   for (auto &CS : CSI) {
     Register Reg = CS.getReg();
@@ -1038,7 +1040,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
       }
     } else {
       Register Reg = CS.getReg();
-      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
       Align Alignment = TRI->getSpillAlign(*RC);
       unsigned Size = TRI->getSpillSize(*RC);
       Alignment = std::min(Alignment, getStackAlign());
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 2a6dce863c28f1..d4dae31f888bec 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -548,8 +548,8 @@ bool SystemZInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
 
   // Check register classes.
   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
-  const TargetRegisterClass *RC =
-    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
+  const TargetRegisterClass *RC = RI.getCommonSubClass(
+      MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI);
   if (!RC)
     return false;
 
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index d246d3f3c5bd11..2e6bc82d4849ef 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -146,12 +146,11 @@ bool SystemZRegisterInfo::getRegAllocationHints(
             Use.getOpcode() == SystemZ::SELRMux) {
           MachineOperand &TrueMO = Use.getOperand(1);
           MachineOperand &FalseMO = Use.getOperand(2);
-          const TargetRegisterClass *RC =
-            TRI->getCommonSubClass(getRC32(FalseMO, VRM, MRI),
-                                   getRC32(TrueMO, VRM, MRI));
+          const TargetRegisterClass *RC = TRI->getCommonSubClass(
+              getRC32(FalseMO, VRM, MRI), getRC32(TrueMO, VRM, MRI), *MRI);
           if (Use.getOpcode() == SystemZ::SELRMux)
-            RC = TRI->getCommonSubClass(RC,
-                                        getRC32(Use.getOperand(0), VRM, MRI));
+            RC = TRI->getCommonSubClass(
+                RC, getRC32(Use.getOperand(0), VRM, MRI), *MRI);
           if (RC && RC != &SystemZ::GRX32BitRegClass) {
             addHints(Order, Hints, RC, MRI);
             // Return true to make these hints the only regs available to
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
index 32a4accd040ebe..614ecca8908276 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
@@ -64,7 +64,7 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   const TargetRegisterClass *RC =
       Register::isVirtualRegister(DestReg)
           ? MRI.getRegClass(DestReg)
-          : MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(DestReg);
+          : MRI.getTargetRegisterInfo()->getMinimalPhysRegClass(DestReg, MRI);
 
   unsigned CopyOpcode = WebAssembly::getCopyOpcodeForRegClass(RC);
 
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp
index 1e2bee7a5c73b4..51a1997a52d36e 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyReplacePhysRegs.cpp
@@ -80,7 +80,7 @@ bool WebAssemblyReplacePhysRegs::runOnMachineFunction(MachineFunction &MF) {
       continue;
 
     // Replace explicit uses of the physical register with a virtual register.
-    const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg);
+    const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PReg, MRI);
     unsigned VReg = WebAssembly::NoRegister;
     for (MachineOperand &MO :
          llvm::make_early_inc_range(MRI.reg_operands(PReg))) {
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index d914e1b61ab075..0e0e30877fe1df 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -2882,6 +2882,7 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
     }
   }
 
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   // Assign slots for GPRs. It increases frame size.
   for (CalleeSavedInfo &I : llvm::reverse(CSI)) {
     Register Reg = I.getReg();
@@ -2931,7 +2932,7 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
     if (X86::VK16RegClass.contains(Reg))
       VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
 
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT);
     unsigned Size = TRI->getSpillSize(*RC);
     Align Alignment = TRI->getSpillAlign(*RC);
     // ensure alignment
@@ -3018,6 +3019,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters(
         .setMIFlag(MachineInstr::FrameSetup);
   }
 
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
   // Make XMM regs spilled. X86 does not have ability of push/pop XMM.
   // It can be done by spilling XMMs to stack frame.
   for (const CalleeSavedInfo &I : llvm::reverse(CSI)) {
@@ -3032,7 +3034,7 @@ bool X86FrameLowering::spillCalleeSavedRegisters(
 
     // Add the callee-saved register as live-in. It's killed at the spill.
     MBB.addLiveIn(Reg);
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT);
 
     TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC, TRI,
                             Register());
@@ -3097,6 +3099,7 @@ bool X86FrameLowering::restoreCalleeSavedRegisters(
   }
 
   DebugLoc DL = MBB.findDebugLoc(MI);
+  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
 
   // Reload XMMs from stack frame.
   for (const CalleeSavedInfo &I : CSI) {
@@ -3109,7 +3112,7 @@ bool X86FrameLowering::restoreCalleeSavedRegisters(
     if (X86::VK16RegClass.contains(Reg))
       VT = STI.hasBWI() ? MVT::v64i1 : MVT::v16i1;
 
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, VT);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI, VT);
     TII.loadRegFromStackSlot(MBB, MI, Reg, I.getFrameIdx(), RC, TRI,
                              Register());
   }
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index eb42a4b2119d5e..dc2b6514dcfcd8 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -4028,8 +4028,8 @@ bool X86InstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
 
   // Check register classes.
   const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
-  const TargetRegisterClass *RC =
-      RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
+  const TargetRegisterClass *RC = RI.getCommonSubClass(
+      MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg), MRI);
   if (!RC)
     return false;
 
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index be0cf1596d0d90..32c4ee88459d9a 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -93,17 +93,16 @@ X86RegisterInfo::getSubClassWithSubReg(const TargetRegisterClass *RC,
   return X86GenRegisterInfo::getSubClassWithSubReg(RC, Idx);
 }
 
-const TargetRegisterClass *
-X86RegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
-                                          const TargetRegisterClass *B,
-                                          unsigned SubIdx) const {
+const TargetRegisterClass *X86RegisterInfo::getMatchingSuperRegClass(
+    const TargetRegisterClass *A, const TargetRegisterClass *B, unsigned SubIdx,
+    const MachineRegisterInfo &MRI) const {
   // The sub_8bit sub-register index is more constrained in 32-bit mode.
   if (!Is64Bit && SubIdx == X86::sub_8bit) {
     A = X86GenRegisterInfo::getSubClassWithSubReg(A, X86::sub_8bit_hi);
     if (!A)
       return nullptr;
   }
-  return X86GenRegisterInfo::getMatchingSuperRegClass(A, B, SubIdx);
+  return X86GenRegisterInfo::getMatchingSuperRegClass(A, B, SubIdx, MRI);
 }
 
 const TargetRegisterClass *
@@ -218,10 +217,10 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF,
   }
 }
 
-bool X86RegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
-                                           unsigned DefSubReg,
-                                           const TargetRegisterClass *SrcRC,
-                                           unsigned SrcSubReg) const {
+bool X86RegisterInfo::shouldRewriteCopySrc(
+    const TargetRegisterClass *DefRC, unsigned DefSubReg,
+    const TargetRegisterClass *SrcRC, unsigned SrcSubReg,
+    const MachineRegisterInfo &MRI) const {
   // Prevent rewriting a copy where the destination size is larger than the
   // input size. See PR41619.
   // FIXME: Should this be factored into the base implementation somehow.
@@ -229,8 +228,8 @@ bool X86RegisterInfo::shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
       SrcRC->hasSuperClassEq(&X86::GR64RegClass) && SrcSubReg == X86::sub_32bit)
     return false;
 
-  return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg,
-                                                  SrcRC, SrcSubReg);
+  return TargetRegisterInfo::shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC,
+                                                  SrcSubReg, MRI);
 }
 
 const TargetRegisterClass *
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h
index 7296a5f021e4ad..e61defefbdf3fa 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.h
+++ b/llvm/lib/Target/X86/X86RegisterInfo.h
@@ -62,8 +62,8 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
   /// specified sub-register index which is in the specified register class B.
   const TargetRegisterClass *
   getMatchingSuperRegClass(const TargetRegisterClass *A,
-                           const TargetRegisterClass *B,
-                           unsigned Idx) const override;
+                           const TargetRegisterClass *B, unsigned Idx,
+                           const MachineRegisterInfo &MRI) const override;
 
   const TargetRegisterClass *
   getSubClassWithSubReg(const TargetRegisterClass *RC,
@@ -76,7 +76,8 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
                             unsigned DefSubReg,
                             const TargetRegisterClass *SrcRC,
-                            unsigned SrcSubReg) const override;
+                            unsigned SrcSubReg,
+                            const MachineRegisterInfo &MRI) const override;
 
   /// getPointerRegClass - Returns a TargetRegisterClass used for pointer
   /// values.
diff --git a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
index 8cb9413f965268..ea05ea2078c7bd 100644
--- a/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
+++ b/llvm/lib/Target/XCore/XCoreFrameLowering.cpp
@@ -422,6 +422,7 @@ bool XCoreFrameLowering::spillCalleeSavedRegisters(
   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
   XCoreFunctionInfo *XFI = MF->getInfo<XCoreFunctionInfo>();
   bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF);
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
 
   DebugLoc DL;
   if (MI != MBB.end() && !MI->isDebugInstr())
@@ -434,7 +435,7 @@ bool XCoreFrameLowering::spillCalleeSavedRegisters(
 
     // Add the callee-saved register as live-in. It's killed at the spill.
     MBB.addLiveIn(Reg);
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.storeRegToStackSlot(MBB, MI, Reg, true, I.getFrameIdx(), RC, TRI,
                             Register());
     if (emitFrameMoves) {
@@ -453,6 +454,7 @@ bool XCoreFrameLowering::restoreCalleeSavedRegisters(
   const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
   bool AtStart = MI == MBB.begin();
   MachineBasicBlock::iterator BeforeI = MI;
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
   if (!AtStart)
     --BeforeI;
   for (const CalleeSavedInfo &CSR : CSI) {
@@ -460,7 +462,7 @@ bool XCoreFrameLowering::restoreCalleeSavedRegisters(
     assert(Reg != XCore::LR && !(Reg == XCore::R10 && hasFP(*MF)) &&
            "LR & FP are always handled in emitEpilogue");
 
-    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
+    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg, MRI);
     TII.loadRegFromStackSlot(MBB, MI, Reg, CSR.getFrameIdx(), RC, TRI,
                              Register());
     assert(MI != MBB.begin() &&
diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc
index 7de7eabdd1f604..8db39e384dea1e 100644
--- a/llvm/unittests/CodeGen/MFCommon.inc
+++ b/llvm/unittests/CodeGen/MFCommon.inc
@@ -17,12 +17,50 @@ public:
   bool hasFP(const MachineFunction &MF) const override { return false; }
 };
 
-static TargetRegisterClass *const BogusRegisterClasses[] = {nullptr};
+// Dummy regclass fields ...
+namespace {
+enum {
+  NoRegister,
+  GPR0 = 1,
+  NUM_TARGET_REGS
+};
+
+enum {
+  GPRsRegClassID = 0,
+};
+
+const MCPhysReg GPRs[] = {GPR0};
+
+const uint8_t GPRsBits[] = { 0x00 };
+
+static const uint32_t GPRsSubClassMask[] = {
+  0x00000001,
+};
+} // namespace
+
+static const TargetRegisterClass *const NullRegClasses[] = { nullptr };
+static const MCRegisterClass BogusMCRegisterClasses[] = {{ GPRs, GPRsBits, 0, 1,
+    sizeof(GPRsBits), GPRsRegClassID, 1, -1, false, true ,false }};
+static const TargetRegisterClass GPRsRegClass = {
+    &BogusMCRegisterClasses[GPRsRegClassID],
+    GPRsSubClassMask,
+    0,
+    LaneBitmask(0x0000000000000001),
+    0,
+    false,
+    0x0,
+    false,
+    false,
+    NullRegClasses,
+    nullptr
+};
+
+ static const TargetRegisterClass *const BogusRegisterClasses[] = {&GPRsRegClass};
 
 class BogusRegisterInfo : public TargetRegisterInfo {
 public:
   BogusRegisterInfo()
-      : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses,
+      : TargetRegisterInfo(nullptr, BogusRegisterClasses, BogusRegisterClasses+1,
                            nullptr, nullptr, LaneBitmask(~0u), nullptr, nullptr) {
     InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
                        nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr);
diff --git a/llvm/unittests/CodeGen/MachineInstrTest.cpp b/llvm/unittests/CodeGen/MachineInstrTest.cpp
index 49da0c38eefdca..3bac28324db131 100644
--- a/llvm/unittests/CodeGen/MachineInstrTest.cpp
+++ b/llvm/unittests/CodeGen/MachineInstrTest.cpp
@@ -530,8 +530,17 @@ TEST(MachineInstrTest, SpliceOperands) {
   EXPECT_EQ(MI->getOperand(8).getImm(), MachineOperand::CreateImm(4).getImm());
 
   // test tied operands
-  MCRegisterClass MRC{
-      0, 0, 0, 0, 0, 0, 0, 0, /*Allocatable=*/true, /*BaseClass=*/true};
+  MCRegisterClass MRC{0,
+                      0,
+                      0,
+                      0,
+                      0,
+                      0,
+                      0,
+                      0,
+                      /*Allocatable=*/true,
+                      /*BaseClass=*/true,
+                      /*Synthetic=*/false};
   TargetRegisterClass RC{&MRC, 0, 0, {}, 0, 0, 0, 0, 0, 0, 0};
   // MachineRegisterInfo will be very upset if these registers aren't
   // allocatable.
diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp
index 40af0d3077b2de..e72ada51d2bc03 100644
--- a/llvm/utils/TableGen/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/CodeGenRegisters.cpp
@@ -818,6 +818,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
     BitInit *Bit = cast<BitInit>(TSF->getBit(I));
     TSFlags |= uint8_t(Bit->getValue()) << I;
   }
+
+  Synthetic = R->getValueAsBit("Synthetic");
 }
 
 // Create an inferred register class that was missing from the .td files.
@@ -828,7 +830,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
     : Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)),
       TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI),
       CopyCost(0), Allocatable(true), AllocationPriority(0),
-      GlobalPriority(false), TSFlags(0) {
+      GlobalPriority(false), TSFlags(0), Synthetic(false) {
   Artificial = true;
   GeneratePressureSet = false;
   for (const auto R : Members) {
@@ -1096,7 +1098,8 @@ CodeGenRegisterClass::getMatchingSubClassWithSubRegs(
   for (auto *SuperRegRC : SuperRegRCs) {
     for (const auto &SuperRegClassPair : SuperRegClasses) {
       const BitVector &SuperRegClassBV = SuperRegClassPair.second;
-      if (SuperRegClassBV[SuperRegRC->EnumValue]) {
+      if (SuperRegClassBV[SuperRegRC->EnumValue] &&
+          !SuperRegClassPair.first->Synthetic) {
         SubRegRC = SuperRegClassPair.first;
         ChosenSuperRegClass = SuperRegRC;
 
diff --git a/llvm/utils/TableGen/CodeGenRegisters.h b/llvm/utils/TableGen/CodeGenRegisters.h
index c34f376ea99db3..d53682417fc54f 100644
--- a/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/CodeGenRegisters.h
@@ -333,6 +333,7 @@ class CodeGenRegisterClass {
   uint8_t AllocationPriority;
   bool GlobalPriority;
   uint8_t TSFlags;
+  bool Synthetic;
   /// Contains the combination of the lane masks of all subregisters.
   LaneBitmask LaneMask;
   /// True if there are at least 2 subregisters which do not interfere.
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index d074e31c624588..041983de18248f 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1065,7 +1065,8 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
        << ", " << RCBitsSize << ", " << RC.getQualifiedIdName() << ", "
        << RegSize << ", " << RC.CopyCost << ", "
        << (RC.Allocatable ? "true" : "false") << ", "
-       << (RC.getBaseClassOrder() ? "true" : "false") << " },\n";
+       << (RC.getBaseClassOrder() ? "true" : "false") << " ,"
+       << (RC.Synthetic ? "true" : "false") << " },\n";
   }
 
   OS << "};\n\n";

>From 908917b954f28313142e6fc9e69cfc3f26b18e89 Mon Sep 17 00:00:00 2001
From: Christudasan Devadasan <Christudasan.Devadasan at amd.com>
Date: Wed, 20 Mar 2024 23:34:07 +0530
Subject: [PATCH 2/2] [CodeGen][MRI] Add allocation mask for register classes

Some targets can have register classes with identical set
of registers. But their actual allocation order can vary.
The allocation mask computed based on target constraints
would help achieve this during register allocation.
---
 .../include/llvm/CodeGen/MachineRegisterInfo.h | 18 ++++++++++++++++++
 llvm/lib/CodeGen/MachineRegisterInfo.cpp       | 13 +++++++++++++
 llvm/lib/CodeGen/RegisterClassInfo.cpp         | 11 ++++++++++-
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 71a3baef70e8cd..78414f31d1bf82 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -98,6 +98,12 @@ class MachineRegisterInfo {
   /// to enable classes dynamically during codegen.
   BitVector RegClassSyntheticInfo;
 
+  /// To have more restrictions on the allocation order for each register class.
+  /// For some targets, two distinct register classes can have the same set of
+  /// registers, but their allocatable set can vary. This vector helps targets
+  /// to dynamically determine the actual allocatable set for RCs.
+  std::vector<BitVector> RegClassAllocationMasks;
+
   /// RegAllocHints - This vector records register allocation hints for
   /// virtual registers. For each virtual register, it keeps a pair of hint
   /// type and hints vector making up the allocation hints. Only the first
@@ -273,6 +279,18 @@ class MachineRegisterInfo {
   /// in various regclass related queries.
   bool isEnabled(const TargetRegisterClass *RC) const;
 
+  /// Update dynamically determined allocation mask for register classes.
+  void updateAllocationMaskForRCs(std::vector<BitVector> &&Mask);
+
+  // Return the allocation mask for regclass \p RC.
+  const BitVector &getAllocationMaskForRC(const TargetRegisterClass &RC) const;
+
+  /// True when the target has dynamically determined allocation mask for its
+  /// register classes.
+  bool hasAllocationMaskForRCs() const {
+    return RegClassAllocationMasks.size();
+  }
+
   // Strictly for use by MachineInstr.cpp.
   void addRegOperandToUseList(MachineOperand *MO);
 
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index c979e3d5e9cf41..2be50214e3ad8b 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -49,6 +49,7 @@ MachineRegisterInfo::MachineRegisterInfo(MachineFunction *MF)
   UsedPhysRegMask.resize(NumRegs);
   PhysRegUseDefLists.reset(new MachineOperand*[NumRegs]());
   initializeRegClassSyntheticInfo();
+  RegClassAllocationMasks.clear();
   TheDelegates.clear();
 }
 
@@ -679,6 +680,18 @@ bool MachineRegisterInfo::isEnabled(const TargetRegisterClass *RC) const {
   return !RegClassSyntheticInfo.test(RC->getID());
 }
 
+void MachineRegisterInfo::updateAllocationMaskForRCs(
+    std::vector<BitVector> &&Mask) {
+  unsigned Size = Mask.size();
+  for (unsigned I = 0; I < Size; ++I)
+    RegClassAllocationMasks.push_back(std::move(Mask[I]));
+}
+
+const BitVector &MachineRegisterInfo::getAllocationMaskForRC(
+    const TargetRegisterClass &RC) const {
+  return RegClassAllocationMasks[RC.getID()];
+}
+
 bool MachineRegisterInfo::isReservedRegUnit(unsigned Unit) const {
   const TargetRegisterInfo *TRI = getTargetRegisterInfo();
   for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
diff --git a/llvm/lib/CodeGen/RegisterClassInfo.cpp b/llvm/lib/CodeGen/RegisterClassInfo.cpp
index 9312bc03bc522a..a373aed30b8750 100644
--- a/llvm/lib/CodeGen/RegisterClassInfo.cpp
+++ b/llvm/lib/CodeGen/RegisterClassInfo.cpp
@@ -142,9 +142,18 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
   // FIXME: Once targets reserve registers instead of removing them from the
   // allocation order, we can simply use begin/end here.
   ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF);
+  const MachineRegisterInfo &MRI = MF->getRegInfo();
+  // Apply the allocation mask for the regclass if found one. Another level of
+  // restriction based on target constraints before getting the actual
+  // allocation order.
+  BitVector ReservedForRC(TRI->getNumRegs(), false);
+  ReservedForRC |= Reserved;
+  if (MRI.hasAllocationMaskForRCs())
+    ReservedForRC |= MRI.getAllocationMaskForRC(*RC);
+
   for (unsigned PhysReg : RawOrder) {
     // Remove reserved registers from the allocation order.
-    if (Reserved.test(PhysReg))
+    if (ReservedForRC.test(PhysReg))
       continue;
     uint8_t Cost = RegCosts[PhysReg];
     MinCost = std::min(MinCost, Cost);



More information about the llvm-commits mailing list