Skip to content

Conversation

ro-i
Copy link
Contributor

@ro-i ro-i commented Aug 22, 2025

This is meant as the inverse of getNamedOperandIdx and returns the OpName for a given operand index for a given opcode.

@llvmbot
Copy link
Member

llvmbot commented Aug 22, 2025

@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-tablegen

Author: Robert Imschweiler (ro-i)

Changes

This is meant as the inverse of getNamedOperandIdx and returns the OpName for a given operand index for a given opcode.


Full diff: https://github.com/llvm/llvm-project/pull/154944.diff

2 Files Affected:

  • (modified) llvm/test/TableGen/get-named-operand-idx.td (+71-30)
  • (modified) llvm/utils/TableGen/InstrInfoEmitter.cpp (+100-38)
diff --git a/llvm/test/TableGen/get-named-operand-idx.td b/llvm/test/TableGen/get-named-operand-idx.td
index ab23edd54c723..3d07ba1278a53 100644
--- a/llvm/test/TableGen/get-named-operand-idx.td
+++ b/llvm/test/TableGen/get-named-operand-idx.td
@@ -48,34 +48,75 @@ def InstD : InstBase {
   let UseNamedOperandTable = 0;
 }
 
-// CHECK: #ifdef GET_INSTRINFO_OPERAND_ENUM
-// CHECK: #undef GET_INSTRINFO_OPERAND_ENUM
-// CHECK: namespace llvm::MyNamespace {
-// CHECK: enum class OpName {
-// CHECK:   a = 0,
-// CHECK:   b = 1,
-// CHECK:   c = 2,
-// CHECK:   d = 3,
-// CHECK:   x = 4,
-// CHECK:   NUM_OPERAND_NAMES = 5,
-// CHECK: }; // enum class OpName
-// CHECK: } // end namespace llvm::MyNamespace
-// CHECK: #endif //GET_INSTRINFO_OPERAND_ENUM
+// CHECK-LABEL: #ifdef GET_INSTRINFO_OPERAND_ENUM
+// CHECK-NEXT:  #undef GET_INSTRINFO_OPERAND_ENUM
+// CHECK-NEXT:  namespace llvm::MyNamespace {
+// CHECK-NEXT:  enum class OpName {
+// CHECK-NEXT:    a = 0,
+// CHECK-NEXT:    b = 1,
+// CHECK-NEXT:    c = 2,
+// CHECK-NEXT:    d = 3,
+// CHECK-NEXT:    x = 4,
+// CHECK-NEXT:    NUM_OPERAND_NAMES = 5,
+// CHECK-NEXT:  }; // enum class OpName
+// CHECK-EMPTY:
+// CHECK-NEXT:  LLVM_READONLY
+// CHECK-NEXT:  int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name);
+// CHECK-NEXT:  LLVM_READONLY
+// CHECK-NEXT:  OpName getOperandIdxName(uint16_t Opcode, int16_t Idx);
+// CHECK-NEXT:  } // end namespace llvm::MyNamespace
+// CHECK-NEXT:  #endif //GET_INSTRINFO_OPERAND_ENUM
 
-// CHECK: #ifdef GET_INSTRINFO_NAMED_OPS
-// CHECK: #undef GET_INSTRINFO_NAMED_OPS
-// CHECK: namespace llvm::MyNamespace {
-// CHECK: LLVM_READONLY
-// CHECK: int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name) {
-// CHECK:  assert(Name != OpName::NUM_OPERAND_NAMES);
-// CHECK:  static constexpr int8_t OperandMap[][5] = {
-// CHECK:      {0, 1, 2, -1, -1, },
-// CHECK:      {-1, -1, -1, 0, 1, },
-// CHECK:    };
-// CHECK:    static constexpr uint8_t InstructionIndex[] = {
-// CHECK:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-// CHECK:    };
-// CHECK:    return OperandMap[InstructionIndex[Opcode]][(unsigned)Name];
-// CHECK:  }
-// CHECK:  } // end namespace llvm::MyNamespace
-// CHECK:  #endif //GET_INSTRINFO_NAMED_OPS
+// CHECK-LABEL: #ifdef GET_INSTRINFO_NAMED_OPS
+// CHECK-NEXT:  #undef GET_INSTRINFO_NAMED_OPS
+// CHECK-NEXT:  namespace llvm::MyNamespace {
+// CHECK-NEXT:  LLVM_READONLY
+// CHECK-NEXT:  static uint8_t getInstructionIndexForOpLookup(uint16_t Opcode) {
+// CHECK-NEXT:    static constexpr uint8_t InstructionIndex[] = {
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// CHECK-NEXT:      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0,
+// CHECK-NEXT:    };
+// CHECK-NEXT:    return InstructionIndex[Opcode];
+// CHECK-NEXT:  }
+// CHECK-NEXT:  LLVM_READONLY
+// CHECK-NEXT:  int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name) {
+// CHECK-NEXT:    assert(Name != OpName::NUM_OPERAND_NAMES);
+// CHECK-NEXT:    static constexpr int8_t OperandMap[][5] = {
+// CHECK-NEXT:      {-1, -1, -1, -1, -1, },
+// CHECK-NEXT:      {0, 1, 2, -1, -1, },
+// CHECK-NEXT:      {-1, -1, -1, 0, 1, },
+// CHECK-NEXT:    };
+// CHECK-NEXT:    unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);
+// CHECK-NEXT:    return OperandMap[InstrIdx][(unsigned)Name];
+// CHECK-NEXT:  }
+// CHECK-NEXT:  LLVM_READONLY
+// CHECK-NEXT:  OpName getOperandIdxName(uint16_t Opcode, int16_t Idx) {
+// CHECK-NEXT:    assert(Idx >= 0 && Idx < 3);
+// CHECK-NEXT:    static constexpr uint8_t OperandMap[][3] = {
+// CHECK-NEXT:      {5, 5, 5, },
+// CHECK-NEXT:      {0, 1, 2, },
+// CHECK-NEXT:      {3, 4, 5, },
+// CHECK-NEXT:    };
+// CHECK-NEXT:    unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);
+// CHECK-NEXT:    return (OpName) OperandMap[InstrIdx][(unsigned)Idx];
+// CHECK-NEXT:  }
+// CHECK-NEXT:  } // end namespace llvm::MyNamespace
+// CHECK-NEXT:  #endif //GET_INSTRINFO_NAMED_OPS
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 6f72b51963f87..eedceb19e5783 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -223,17 +223,104 @@ void InstrInfoEmitter::EmitOperandInfo(raw_ostream &OS,
   }
 }
 
+static void emitGetInstructionIndexForOpLookup(
+    raw_ostream &OS, const MapVector<SmallVector<int>, unsigned> &OperandMap,
+    ArrayRef<unsigned> InstructionIndex) {
+  StringRef Type = OperandMap.size() <= UINT8_MAX + 1 ? "uint8_t" : "uint16_t";
+  OS << "LLVM_READONLY\n";
+  OS << "static " << Type
+     << " getInstructionIndexForOpLookup(uint16_t Opcode) {\n";
+  OS << "  static constexpr " << Type << " InstructionIndex[] = {";
+  for (auto [TableIndex, Entry] : enumerate(InstructionIndex))
+    OS << (TableIndex % 16 == 0 ? "\n    " : " ") << Entry << ',';
+  OS << "\n  };\n";
+  OS << "  return InstructionIndex[Opcode];\n";
+  OS << "}\n";
+}
+
+static void
+emitGetNamedOperandIdx(raw_ostream &OS, StringRef Namespace,
+                       const MapVector<StringRef, unsigned> &OperandNameToID,
+                       const MapVector<SmallVector<int>, unsigned> &OperandMap,
+                       unsigned MaxOperandNo, unsigned NumOperandNames) {
+  OS << "LLVM_READONLY\n";
+  OS << "int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name) {\n";
+  OS << "  assert(Name != OpName::NUM_OPERAND_NAMES);\n";
+  if (!NumOperandNames) {
+    // There are no operands, so no need to emit anything
+    OS << "  return -1;\n}\n";
+    return;
+  }
+  assert(MaxOperandNo <= INT16_MAX &&
+         "Too many operands for the operand name -> index table");
+  StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
+  OS << "  static constexpr " << Type << " OperandMap[][" << NumOperandNames
+     << "] = {\n";
+  for (const auto &[OpList, _] : OperandMap) {
+    // Emit a row of the OperandMap table.
+    OS << "    {";
+    for (unsigned ID = 0; ID < NumOperandNames; ++ID)
+      OS << (ID < OpList.size() ? OpList[ID] : -1) << ", ";
+    OS << "},\n";
+  }
+  OS << "  };\n";
+
+  OS << "  unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);\n";
+  OS << "  return OperandMap[InstrIdx][(unsigned)Name];\n";
+  OS << "}\n";
+}
+
+static void
+emitGetOperandIdxName(raw_ostream &OS, StringRef Namespace,
+                      const MapVector<StringRef, unsigned> &OperandNameToID,
+                      const MapVector<SmallVector<int>, unsigned> &OperandMap,
+                      unsigned MaxOperandNo, unsigned NumOperandNames) {
+  OS << "LLVM_READONLY\n";
+  OS << "OpName getOperandIdxName(uint16_t Opcode, int16_t Idx) {\n";
+  OS << "  assert(Idx >= 0 && Idx < " << MaxOperandNo << ");\n";
+  if (!MaxOperandNo) {
+    // There are no operands, so no need to emit anything
+    OS << "  return -1;\n}\n";
+    return;
+  }
+  assert(NumOperandNames <= UINT16_MAX &&
+         "Too many operands for the operand index -> name table");
+  StringRef Type = NumOperandNames <= UINT8_MAX ? "uint8_t" : "uint16_t";
+  OS << "  static constexpr " << Type << " OperandMap[][" << MaxOperandNo
+     << "] = {\n";
+  for (const auto &[OpList, _] : OperandMap) {
+    SmallVector<unsigned> IDs(MaxOperandNo, NumOperandNames);
+    for (const auto &[ID, Idx] : enumerate(OpList)) {
+      if (Idx >= 0)
+        IDs[Idx] = ID;
+    }
+    // Emit a row of the OperandMap table. Map operand indices to enum values.
+    OS << "    {";
+    for (unsigned ID : IDs)
+      OS << ID << ", ";
+    OS << "},\n";
+  }
+  OS << "  };\n";
+
+  OS << "  unsigned InstrIdx = getInstructionIndexForOpLookup(Opcode);\n";
+  OS << "  return (OpName) OperandMap[InstrIdx][(unsigned)Idx];\n";
+  OS << "}\n";
+}
+
 /// Generate a table and function for looking up the indices of operands by
 /// name.
 ///
 /// This code generates:
 /// - An enum in the llvm::TargetNamespace::OpName namespace, with one entry
 ///   for each operand name.
-/// - A 2-dimensional table called OperandMap for mapping OpName enum values to
-///   operand indices.
-/// - A function called getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
+/// - A 2-dimensional table for mapping OpName enum values to operand indices.
+/// - A function called getNamedOperandIdx(uint16_t Opcode, OpName Name)
 ///   for looking up the operand index for an instruction, given a value from
 ///   OpName enum
+/// - A 2-dimensional table for mapping operand indices to OpName enum values.
+/// - A function called getOperandIdxName(uint16_t Opcode, int16_t Idx)
+///   for looking up the OpName enum for an instruction, given the operand
+///   index. This is the inverse of getNamedOperandIdx().
 ///
 /// Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
 /// we can just skip them. Hence accept just the TargetInstructions.
@@ -242,11 +329,6 @@ void InstrInfoEmitter::emitOperandNameMappings(
     ArrayRef<const CodeGenInstruction *> TargetInstructions) {
   StringRef Namespace = Target.getInstNamespace();
 
-  /// To facilitate assigning OpName enum values in the sorted alphabetical
-  /// order, we go through an indirection from OpName -> ID, and Enum -> ID.
-  /// This allows us to build the OpList and assign IDs to OpNames in a single
-  /// scan of the instructions below.
-
   // Map of operand names to their ID.
   MapVector<StringRef, unsigned> OperandNameToID;
 
@@ -257,7 +339,7 @@ void InstrInfoEmitter::emitOperandNameMappings(
   /// instructions that have identical OpName -> Operand index mapping.
   MapVector<SmallVector<int>, unsigned> OperandMap;
 
-  // Max operand index seen.
+  // Max operand index seen + 1.
   unsigned MaxOperandNo = 0;
 
   // Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so
@@ -277,7 +359,7 @@ void InstrInfoEmitter::emitOperandNameMappings(
               .first->second;
       OpList.resize(std::max((unsigned)OpList.size(), ID + 1), -1);
       OpList[ID] = Info.MIOperandNo;
-      MaxOperandNo = std::max(MaxOperandNo, Info.MIOperandNo);
+      MaxOperandNo = std::max(MaxOperandNo, Info.MIOperandNo + 1);
     }
     auto [It, Inserted] =
         OperandMap.try_emplace(std::move(OpList), OperandMap.size());
@@ -296,42 +378,22 @@ void InstrInfoEmitter::emitOperandNameMappings(
   OS << "}; // enum class OpName\n\n";
   OS << "LLVM_READONLY\n";
   OS << "int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name);\n";
+  OS << "LLVM_READONLY\n";
+  OS << "OpName getOperandIdxName(uint16_t Opcode, int16_t Idx);\n";
   OS << "} // end namespace llvm::" << Namespace << '\n';
   OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
 
   OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
   OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
   OS << "namespace llvm::" << Namespace << " {\n";
-  OS << "LLVM_READONLY\n";
-  OS << "int16_t getNamedOperandIdx(uint16_t Opcode, OpName Name) {\n";
-  OS << "  assert(Name != OpName::NUM_OPERAND_NAMES);\n";
-  if (NumOperandNames != 0) {
-    assert(MaxOperandNo <= INT16_MAX &&
-           "Too many operands for the operand name -> index table");
-    StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
-    OS << "  static constexpr " << Type << " OperandMap[][" << NumOperandNames
-       << "] = {\n";
-    for (const auto &[OpList, _] : OperandMap) {
-      // Emit a row of the OperandMap table.
-      OS << "    {";
-      for (unsigned ID = 0; ID < NumOperandNames; ++ID)
-        OS << (ID < OpList.size() ? OpList[ID] : -1) << ", ";
-      OS << "},\n";
-    }
-    OS << "  };\n";
 
-    Type = OperandMap.size() <= UINT8_MAX + 1 ? "uint8_t" : "uint16_t";
-    OS << "  static constexpr " << Type << " InstructionIndex[] = {";
-    for (auto [TableIndex, Entry] : enumerate(InstructionIndex))
-      OS << (TableIndex % 16 == 0 ? "\n    " : " ") << Entry << ',';
-    OS << "\n  };\n";
+  emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);
+
+  emitGetNamedOperandIdx(OS, Namespace, OperandNameToID, OperandMap,
+                         MaxOperandNo, NumOperandNames);
+  emitGetOperandIdxName(OS, Namespace, OperandNameToID, OperandMap,
+                        MaxOperandNo, NumOperandNames);
 
-    OS << "  return OperandMap[InstructionIndex[Opcode]][(unsigned)Name];\n";
-  } else {
-    // There are no operands, so no need to emit anything
-    OS << "  return -1;\n";
-  }
-  OS << "}\n";
   OS << "} // end namespace llvm::" << Namespace << '\n';
   OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
 }

@ro-i
Copy link
Contributor Author

ro-i commented Aug 22, 2025

I don't really like the separate definition of getInstructionIndexForOpLookup, but thought that it might make sense to save the space of defining the table twice

StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
OS << " static constexpr " << Type << " OperandMap[][" << NumOperandNames
<< "] = {\n";
for (const auto &[OpList, _] : OperandMap) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is _ a C++ thing? I'm not sure if you could use that to ignore unused variable warning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is currently no warning intended for unused member of structured bindings: #58953
This might change in the future, and then, _ will probably be supported to explicitly ignore structured binding members. Currently, it's just a visual helper for the reader.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this idiom is already used heavily in LLVM code. _ is a valid variable name in C++ I think, which is what this uses.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC there's a proposal to make this blessed syntax in a future C++

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was one time I indeed used that as an unused variable name, and then the compiler generates a warning of unused variable. Lol.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current behavior does seem a little inconsistent: https://godbolt.org/z/eM1xj54P7
Interestingly, a standalone variable with the name _ is not flagged as unused

StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t";
OS << " static constexpr " << Type << " OperandMap[][" << NumOperandNames
<< "] = {\n";
for (const auto &[OpList, _] : OperandMap) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC there's a proposal to make this blessed syntax in a future C++

raw_ostream &OS, const MapVector<SmallVector<int>, unsigned> &OperandMap,
ArrayRef<unsigned> InstructionIndex) {
StringRef Type = OperandMap.size() <= UINT8_MAX + 1 ? "uint8_t" : "uint16_t";
OS << "LLVM_READONLY static " << Type
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
OS << "LLVM_READONLY static " << Type
OS << "LLVM_READONLY static " << Type

I think this technically qualifies for readnone, but the optimizer will take care of it anyway

Copy link

github-actions bot commented Aug 23, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

ro-i and others added 5 commits August 25, 2025 03:09
This is meant as the inverse of getNamedOperandIdx and returns the
OpName for a given operand index for a given opcode.
Co-authored-by: Matt Arsenault <Matthew.Arsenault@amd.com>
@ro-i ro-i force-pushed the users/ro-i/idx-opname branch from a58bcb6 to 6a50747 Compare August 25, 2025 08:10
@ro-i
Copy link
Contributor Author

ro-i commented Aug 25, 2025

rebased on current main to (hopefully) fix the lldb test failures (that have nothing to do with this PR)

@arsenm
Copy link
Contributor

arsenm commented Aug 25, 2025

rebased on current main to (hopefully) fix the lldb test failures (that have nothing to do with this PR)

They don't and have been broken for days, just ignore them

@ro-i ro-i merged commit 2d5a3c8 into main Aug 25, 2025
8 of 9 checks passed
@ro-i ro-i deleted the users/ro-i/idx-opname branch August 25, 2025 10:10
@ro-i
Copy link
Contributor Author

ro-i commented Aug 25, 2025

Ok, done. Thanks for the reviews everyone

if (OpName == AMDGPU::OpName::NUM_OPERAND_NAMES)
continue;
int16_t RetrievedIdx = AMDGPU::getNamedOperandIdx(Opcode, OpName);
EXPECT_EQ(Idx, RetrievedIdx)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @ro-i ,

Warning on this line:

../../third-party/unittest/googletest/include/gtest/gtest.h:1379:11: error: comparison of integers of different signs: 'const unsigned int' and 'const short' [-Werror,-Wsign-compare]
 1379 |   if (lhs == rhs) {
      |       ~~~ ^  ~~~
../../third-party/unittest/googletest/include/gtest/gtest.h:1398:12: note: in instantiation of function template specialization 'testing::internal::CmpHelperEQ<unsigned int, short>' requested here
 1398 |     return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
      |            ^
../unittests/Target/AMDGPU/AMDGPUUnitTests.cpp:338:7: note: in instantiation of function template specialization 'testing::internal::EqHelper::Compare<unsigned int, short, nullptr>' requested here
  338 |       EXPECT_EQ(Idx, RetrievedIdx)
      |       ^
``

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants