[llvm-branch-commits] [llvm] AMDGPU: Validate VOPD/VOPD3 physical source registers against operand RC (PR #196515)

Mirko BrkuĊĦanin via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jul 20 07:16:09 PDT 2026


================
@@ -34,6 +34,28 @@ using namespace llvm;
 
 #define DEBUG_TYPE "gcn-vopd-utils"
 
+// Check if physical register from src<SrcIdx> operand of MI<CompIdx> matches
+// register class constraints in corresponding VOPDOpc operand with name
+// src/vsrc<SrcIdx><CompIdx>.
+bool isValidVOPDSrc(const SIInstrInfo &TII, int VOPDOpc, unsigned CompIdx,
+                    unsigned SrcIdx, Register PhysSrcReg) {
+  using namespace AMDGPU;
+  static constexpr OpName OpNames[] = {
+      OpName::src0X, OpName::vsrc1X, OpName::vsrc2X, OpName::src2X,
+      OpName::src0Y, OpName::vsrc1Y, OpName::vsrc2Y, OpName::src2Y};
+  unsigned OpNamesIdx = CompIdx * 4 + SrcIdx; // 4 possible OpNames per CompIdx
+  unsigned OpNamesCnt = SrcIdx == 2 ? 2 : 1;  // src2 has 2 possible OpNames
+
+  int OpIdx = -1;
+  for (unsigned I = OpNamesIdx; I != OpNamesIdx + OpNamesCnt; ++I) {
+    OpIdx = getNamedOperandIdx(VOPDOpc, OpNames[I]);
+    if (OpIdx > 0)
+      break;
+  }
----------------
mbrkusanin wrote:

```suggestion
  int OpIdx = -1;
  const bool IsX = CompIdx == VOPD::X;
  switch (SrcIdx) {
  case 0:
    OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::src0X : OpName::src0Y);
    break;
  case 1:
    OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::vsrc1X : OpName::vsrc1Y);
    break;
  case 2:
    OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::vsrc2X : OpName::vsrc2Y);
    if (OpIdx == -1)
      OpIdx = getNamedOperandIdx(VOPDOpc, IsX ? OpName::src2X : OpName::src2Y);
    break;
  default:
    llvm_unreachable("unexpected VOPD source index");
  }
```
Calculating a range of indices we want to check with for loop is confusing. Would this be more readable?

https://github.com/llvm/llvm-project/pull/196515


More information about the llvm-branch-commits mailing list