[llvm] [NFC][CodeGen] Add helper function to check SubReg validity (PR #181489)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 14 08:59:42 PST 2026


https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/181489

None

>From 4951019f7313601daf4fcd50d81f66d6e10d7e9b Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Sat, 14 Feb 2026 08:58:27 -0800
Subject: [PATCH] [NFC][CodeGen] Add helper function to check SubReg validity

---
 .../include/llvm/CodeGen/TargetRegisterInfo.h | 14 +++++++++++
 llvm/lib/CodeGen/MachineInstr.cpp             |  3 ++-
 llvm/lib/CodeGen/MachineVerifier.cpp          | 24 ++++++-------------
 llvm/lib/CodeGen/PeepholeOptimizer.cpp        |  8 ++-----
 llvm/lib/CodeGen/TargetRegisterInfo.cpp       |  2 +-
 .../AMDGPU/GCNRewritePartialRegUses.cpp       |  2 +-
 6 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index b69a91651e300..09428c78292ba 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -735,6 +735,20 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
     return nullptr;
   }
 
+  /// Returns true if sub-register \p Idx can be used with register class
+  /// \p RC.
+  bool isSubRegValidForRegClass(const TargetRegisterClass *RC,
+                                unsigned Idx) const {
+    // NoSubRegister is always valid.
+    if (!Idx)
+      return true;
+
+    // `Idx` is valid if the largest subclass of `RC` that supports
+    // sub-register index `Idx` is same as `RC`. That is, every physical
+    // register in `RC` support sub-register index `Idx`.
+    return getSubClassWithSubReg(RC, Idx) == RC;
+  }
+
   /// Return the subregister index you get from composing
   /// two subregister indices.
   ///
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 20e448f1d1954..926c00336efbc 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -1078,8 +1078,9 @@ const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
       CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
     else
       CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
-  } else if (OpRC)
+  } else if (OpRC) {
     CurRC = TRI->getCommonSubClass(CurRC, OpRC);
+  }
   return CurRC;
 }
 
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 919d451e25e54..7f016267f9906 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2800,23 +2800,13 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
 
         break;
       }
-      if (SubIdx) {
-        const TargetRegisterClass *SRC =
-          TRI->getSubClassWithSubReg(RC, SubIdx);
-        if (!SRC) {
-          report("Invalid subregister index for virtual register", MO, MONum);
-          OS << "Register class " << TRI->getRegClassName(RC)
-             << " does not support subreg index "
-             << TRI->getSubRegIndexName(SubIdx) << '\n';
-          return;
-        }
-        if (RC != SRC) {
-          report("Invalid register class for subregister index", MO, MONum);
-          OS << "Register class " << TRI->getRegClassName(RC)
-             << " does not fully support subreg index "
-             << TRI->getSubRegIndexName(SubIdx) << '\n';
-          return;
-        }
+      // Validate that SubIdx can be applied to the virtual register.
+      if (!TRI->isSubRegValidForRegClass(RC, SubIdx)) {
+        report("Invalid subregister index for virtual register", MO, MONum);
+        OS << "Register class " << TRI->getRegClassName(RC)
+           << " does not support subreg index "
+           << TRI->getSubRegIndexName(SubIdx) << '\n';
+        return;
       }
       if (MONum < MCID.getNumOperands()) {
         if (const TargetRegisterClass *DRC = TII->getRegClass(MCID, MONum)) {
diff --git a/llvm/lib/CodeGen/PeepholeOptimizer.cpp b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
index 6cb59717c4997..73aecda4e522c 100644
--- a/llvm/lib/CodeGen/PeepholeOptimizer.cpp
+++ b/llvm/lib/CodeGen/PeepholeOptimizer.cpp
@@ -1930,9 +1930,7 @@ ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
     if (SrcReg.isVirtual()) {
       // TODO: Try constraining on rewrite if we can
       const TargetRegisterClass *RegRC = MRI.getRegClass(SrcReg);
-      const TargetRegisterClass *SrcWithSubRC =
-          TRI->getSubClassWithSubReg(RegRC, SubReg);
-      if (RegRC != SrcWithSubRC)
+      if (!TRI->isSubRegValidForRegClass(RegRC, SubReg))
         return ValueTrackerResult();
     } else {
       if (!TRI->getSubReg(SrcReg, SubReg))
@@ -2040,9 +2038,7 @@ ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
     //
     // TODO: Should we modify the register class to support the index?
     const TargetRegisterClass *SrcRC = MRI.getRegClass(RegSeqInput.Reg);
-    const TargetRegisterClass *SrcWithSubRC =
-        TRI->getSubClassWithSubReg(SrcRC, ComposedDefInSrcReg1);
-    if (SrcRC != SrcWithSubRC)
+    if (!TRI->isSubRegValidForRegClass(SrcRC, ComposedDefInSrcReg1))
       return ValueTrackerResult();
 
     return ValueTrackerResult(RegSeqInput.Reg, ComposedDefInSrcReg1);
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index a56285679929e..7edc94dedb658 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -555,7 +555,7 @@ bool TargetRegisterInfo::getCoveringSubRegIndexes(
 
   for (unsigned Idx = 1, E = getNumSubRegIndices(); Idx < E; ++Idx) {
     // Is this index even compatible with the given class?
-    if (getSubClassWithSubReg(RC, Idx) != RC)
+    if (!isSubRegValidForRegClass(RC, Idx))
       continue;
     LaneBitmask SubRegMask = getSubRegIndexLaneMask(Idx);
     // Early exit if we found a perfect match.
diff --git a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
index 237da2d64d4ee..94f82f2915cef 100644
--- a/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
+++ b/llvm/lib/Target/AMDGPU/GCNRewritePartialRegUses.cpp
@@ -268,7 +268,7 @@ GCNRewritePartialRegUsesImpl::getRegClassWithShiftedSubregs(
     assert(MinRC->isAllocatable() && TRI->isRegClassAligned(MinRC, RCAlign));
     for (auto [OldSubReg, NewSubReg] : SubRegs)
       // Check that all registers in MinRC support NewSubReg subregister.
-      assert(MinRC == TRI->getSubClassWithSubReg(MinRC, NewSubReg));
+      assert(TRI->isSubRegValidForRegClass(MinRC, NewSubReg));
   }
 #endif
   // There might be zero RShift - in this case we just trying to find smaller



More information about the llvm-commits mailing list