[llvm] [AMDGPU] Export selected AMDGPUBaseInfo utilities from libLLVM (PR #217016)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 18 05:50:23 PDT 2026
Martin Paul =?utf-8?q?Lücke?= <martin.luecke at amd.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/217016 at github.com>
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-amdgpu
Author: Martin Paul Lücke (martin-luecke)
<details>
<summary>Changes</summary>
ROCm AMDGPU binary-transformation path uses LLVM’s MC information to decode instructions, map hardware registers to LLVM pseudo registers, map between instruction encoding forms, and reconstruct code-object ABI state. The required utilities are available when linking directly against the AMDGPU component libraries, but their symbols are hidden when the same consumer links against the monolithic `libLLVM`.
This exports a narrow set of existing `AMDGPUBaseInfo` utilities needed for these operations. This includes named-operand lookup, opcode-form mappings, register queries, subtarget predicates, and code-object implicit-argument layout helpers. Move the selected opcode-mapping declarations to `AMDGPUBaseInfo.h`, where their generated definitions are instantiated.
Because `getNamedOperandIdx` is generated by TableGen, add an opt-in `InstrInfo` setting that applies `LLVM_ABI` to that lookup. The setting remains disabled by default, so this does not change the exported interfaces of other targets.
For `S_SET_VGPR_MSB`, add a semantic query that maps its four fields to MC operand indices instead of exporting the underlying operand-name tables. Migrate `AMDGPUInstPrinter` to this query so the table interpretation remains centralized in AMDGPUBaseInfo.
---
Full diff: https://github.com/llvm/llvm-project/pull/217016.diff
9 Files Affected:
- (modified) llvm/include/llvm/Target/Target.td (+4)
- (modified) llvm/lib/Target/AMDGPU/AMDGPU.td (+1)
- (modified) llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp (+6-11)
- (modified) llvm/lib/Target/AMDGPU/SIInstrInfo.h (-17)
- (modified) llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp (+21)
- (modified) llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h (+55-19)
- (modified) llvm/test/TableGen/get-named-operand-idx.td (+19-4)
- (modified) llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp (+49)
- (modified) llvm/utils/TableGen/InstrInfoEmitter.cpp (+14-6)
``````````diff
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 7d1e7a28b7b6e..27456052c1cba 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -1308,6 +1308,10 @@ class InstrInfo {
//
// This option is a temporary migration help. It will go away.
bit guessInstructionProperties = true;
+
+ // Export the generated getNamedOperandIdx function from shared LLVM
+ // libraries.
+ bit ExportNamedOperandLookup = false;
}
// Standard Pseudo Instructions.
diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.td b/llvm/lib/Target/AMDGPU/AMDGPU.td
index 4806e1e9901ef..78afbafb485ba 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPU.td
+++ b/llvm/lib/Target/AMDGPU/AMDGPU.td
@@ -2521,6 +2521,7 @@ def FeatureISAVersion13_Generic: FeatureSet<
//===----------------------------------------------------------------------===//
def AMDGPUInstrInfo : InstrInfo {
+ let ExportNamedOperandLookup = true;
let guessInstructionProperties = 1;
}
diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
index 2764ff2d68ce0..ded847bda78cf 100644
--- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
+++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp
@@ -364,20 +364,15 @@ static MCRegister getRegFromMIA(MCRegister Reg, unsigned OpNo,
if (!(Enc & AMDGPU::HWEncoding::IS_VGPR))
return Reg;
- auto Ops = AMDGPU::getVGPRLoweringOperandTables(Desc);
- if (!Ops.first)
- return Reg;
- unsigned Opc = Desc.getOpcode();
+ const AMDGPU::VGPRMSBOperandIndices OperandIndices =
+ AMDGPU::getVGPRMSBOperandIndices(Desc);
unsigned I;
- for (I = 0; I < 4; ++I) {
- if (Ops.first[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
- (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.first[I]) == OpNo)
- break;
- if (Ops.second && Ops.second[I] != AMDGPU::OpName::NUM_OPERAND_NAMES &&
- (unsigned)AMDGPU::getNamedOperandIdx(Opc, Ops.second[I]) == OpNo)
+ for (I = 0; I != OperandIndices.size(); ++I) {
+ auto [XOperandIndex, YOperandIndex] = OperandIndices[I];
+ if (XOperandIndex == OpNo || YOperandIndex == OpNo)
break;
}
- if (I == 4)
+ if (I == OperandIndices.size())
return Reg;
unsigned OpMSBs = (VgprMSBs >> (I * 2)) & 3;
if (!OpMSBs)
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index 6c7b2d7d2279e..8fabfbaa87285 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -1825,24 +1825,12 @@ bool execMayBeModifiedBeforeAnyUse(const MachineRegisterInfo &MRI,
namespace AMDGPU {
- LLVM_READONLY
- int32_t getVOPe64(uint32_t Opcode);
-
LLVM_READONLY
int32_t getVOPe32(uint32_t Opcode);
LLVM_READONLY
int32_t getSDWAOp(uint32_t Opcode);
- LLVM_READONLY
- int32_t getDPPOp32(uint32_t Opcode);
-
- LLVM_READONLY
- int32_t getDPPOp64(uint32_t Opcode);
-
- LLVM_READONLY
- int32_t getBasicFromSDWAOp(uint32_t Opcode);
-
LLVM_READONLY
int32_t getCommuteRev(uint32_t Opcode);
@@ -1866,11 +1854,6 @@ namespace AMDGPU {
LLVM_READONLY
int32_t getGlobalSaddrOp(uint32_t Opcode);
- /// \returns VADDR form of a FLAT Global instruction given an \p Opcode
- /// of a SADDR form.
- LLVM_READONLY
- int32_t getGlobalVaddrOp(uint32_t Opcode);
-
LLVM_READONLY
int32_t getVCMPXNoSDstOp(uint32_t Opcode);
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index b2b1e4237367d..16248eebd2ad2 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -3658,6 +3658,27 @@ getVGPRLoweringOperandTables(const MCInstrDesc &Desc) {
return {};
}
+VGPRMSBOperandIndices getVGPRMSBOperandIndices(const MCInstrDesc &Desc) {
+ auto [XOperandNames, YOperandNames] = getVGPRLoweringOperandTables(Desc);
+ auto GetOperandIndex = [&](const AMDGPU::OpName *OperandNames,
+ unsigned Slot) -> std::optional<unsigned> {
+ if (!OperandNames ||
+ OperandNames[Slot] == AMDGPU::OpName::NUM_OPERAND_NAMES)
+ return std::nullopt;
+ int16_t OperandIndex =
+ getNamedOperandIdx(Desc.getOpcode(), OperandNames[Slot]);
+ if (OperandIndex < 0)
+ return std::nullopt;
+ return static_cast<unsigned>(OperandIndex);
+ };
+
+ VGPRMSBOperandIndices Indices;
+ for (unsigned Slot = 0; Slot != Indices.size(); ++Slot)
+ Indices[Slot] = {GetOperandIndex(XOperandNames, Slot),
+ GetOperandIndex(YOperandNames, Slot)};
+ return Indices;
+}
+
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode) {
const MCInstrDesc &Desc = MII.get(Opcode);
if (SIInstrFlags::isSMRD(Desc))
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 35194739d692e..8e9d829c24628 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -18,6 +18,7 @@
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Alignment.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/AMDGPUTargetParser.h"
#include <array>
#include <functional>
@@ -83,20 +84,23 @@ unsigned getAMDHSACodeObjectVersion(unsigned ABIVersion);
/// \returns The default HSA code object version. This should only be used when
/// we lack a more accurate CodeObjectVersion value (e.g. from the IR module
/// flag or a .amdhsa_code_object_version directive)
-unsigned getDefaultAMDHSACodeObjectVersion();
+LLVM_ABI unsigned getDefaultAMDHSACodeObjectVersion();
/// \returns ABIVersion suitable for use in ELF's e_ident[EI_ABIVERSION]. \param
/// CodeObjectVersion is a value returned by getAMDHSACodeObjectVersion().
uint8_t getELFABIVersion(const Triple &OS, unsigned CodeObjectVersion);
/// \returns The offset of the multigrid_sync_arg argument from implicitarg_ptr
-unsigned getMultigridSyncArgImplicitArgPosition(unsigned COV);
+LLVM_ABI unsigned getMultigridSyncArgImplicitArgPosition(unsigned COV);
/// \returns The offset of the hostcall pointer argument from implicitarg_ptr
-unsigned getHostcallImplicitArgPosition(unsigned COV);
+LLVM_ABI unsigned getHostcallImplicitArgPosition(unsigned COV);
-unsigned getDefaultQueueImplicitArgPosition(unsigned COV);
-unsigned getCompletionActionImplicitArgPosition(unsigned COV);
+/// \returns The offset of the default queue pointer from implicitarg_ptr
+LLVM_ABI unsigned getDefaultQueueImplicitArgPosition(unsigned COV);
+
+/// \returns The offset of the completion action pointer from implicitarg_ptr
+LLVM_ABI unsigned getCompletionActionImplicitArgPosition(unsigned COV);
struct GcnBufferFormatInfo {
unsigned Format;
@@ -619,8 +623,27 @@ LLVM_READONLY
const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t Format,
const MCSubtargetInfo &STI);
-LLVM_READONLY
-int32_t getMCOpcode(uint32_t Opcode, unsigned Gen);
+/// \returns The opcode for \p Opcode in the \p Gen SIEncodingFamily. Returns
+/// -1 if \p Opcode is already native and INSTRUCTION_LIST_END if it has no
+/// encoding in that family.
+LLVM_ABI LLVM_READONLY int32_t getMCOpcode(uint32_t Opcode, unsigned Gen);
+
+/// \returns The e64 form of \p Opcode, or -1 if no mapping exists.
+LLVM_ABI LLVM_READONLY int32_t getVOPe64(uint32_t Opcode);
+
+/// \returns The DPP form of an ordinary e32 \p Opcode, or -1 if no mapping
+/// exists.
+LLVM_ABI LLVM_READONLY int32_t getDPPOp32(uint32_t Opcode);
+
+/// \returns The DPP form of a VOP3 \p Opcode, or -1 if no mapping exists.
+LLVM_ABI LLVM_READONLY int32_t getDPPOp64(uint32_t Opcode);
+
+/// \returns The ordinary form of an SDWA \p Opcode, or -1 if no mapping exists.
+LLVM_ABI LLVM_READONLY int32_t getBasicFromSDWAOp(uint32_t Opcode);
+
+/// \returns VADDR form of a FLAT Global instruction given an \p Opcode
+/// of a SADDR form, or -1 if no mapping exists.
+LLVM_ABI LLVM_READONLY int32_t getGlobalVaddrOp(uint32_t Opcode);
LLVM_READONLY
unsigned getVOPDOpcode(unsigned Opc, bool VOPD3);
@@ -629,8 +652,8 @@ LLVM_READONLY
int getVOPDFull(unsigned OpX, unsigned OpY, unsigned EncodingFamily,
bool VOPD3);
-LLVM_READONLY
-bool isVOPD(unsigned Opc);
+/// \returns true if \p Opc is a VOPD instruction.
+LLVM_ABI LLVM_READONLY bool isVOPD(unsigned Opc);
LLVM_READNONE
bool isMAC(unsigned Opc);
@@ -937,8 +960,10 @@ class InstInfo {
} // namespace VOPD
-LLVM_READONLY
-std::pair<unsigned, unsigned> getVOPDComponents(unsigned VOPDOpcode);
+/// \returns the X and Y component opcodes for \p VOPDOpcode, which must
+/// identify a VOPD instruction.
+LLVM_ABI LLVM_READONLY std::pair<unsigned, unsigned>
+getVOPDComponents(unsigned VOPDOpcode);
LLVM_READONLY
// Get properties of 2 single VOP1/VOP2 instructions
@@ -1542,19 +1567,19 @@ bool hasSMRDSignedImmOffset(const MCSubtargetInfo &ST);
/// Is Reg - scalar register
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI);
-/// \returns if \p Reg occupies the high 16-bits of a 32-bit register.
-bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI);
+/// \returns true if \p Reg denotes the high 16 bits of a 32-bit register.
+LLVM_ABI bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI);
/// If \p Reg is a pseudo reg, return the correct hardware register given
/// \p STI otherwise return \p Reg.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI);
-/// Convert hardware register \p Reg to a pseudo register
-LLVM_READNONE
-MCRegister mc2PseudoReg(MCRegister Reg);
+/// \returns the pseudo-register equivalent of \p Reg, or \p Reg if no mapping
+/// exists.
+LLVM_ABI LLVM_READNONE MCRegister mc2PseudoReg(MCRegister Reg);
-LLVM_READNONE
-bool isInlineValue(MCRegister Reg);
+/// \returns true if \p Reg is a named inline value.
+LLVM_ABI LLVM_READNONE bool isInlineValue(MCRegister Reg);
/// Is this an AMDGPU specific source operand? These include registers,
/// inline constants, literals and mandatory literals (KImm).
@@ -1580,7 +1605,7 @@ bool isSISrcInlinableOperand(const MCInstrDesc &Desc, unsigned OpNo);
unsigned getRegBitWidth(unsigned RCID);
/// Get the size in bits of a register from the register class \p RC.
-unsigned getRegBitWidth(const MCRegisterClass &RC);
+LLVM_ABI unsigned getRegBitWidth(const MCRegisterClass &RC);
LLVM_READNONE
inline unsigned getOperandSize(const MCOperandInfo &OpInfo) {
@@ -1797,6 +1822,17 @@ std::optional<unsigned> convertSetRegImmToVgprMSBs(const MCInst &MI,
std::pair<const AMDGPU::OpName *, const AMDGPU::OpName *>
getVGPRLoweringOperandTables(const MCInstrDesc &Desc);
+/// MC operand indices associated with the four two-bit S_SET_VGPR_MSB fields.
+/// Elements 0 through 3 correspond to src0, src1, src2, and dst. Each pair
+/// contains the X and Y component indices for one field. An index is absent
+/// when the instruction has no corresponding operand.
+using VGPRMSBOperandIndices =
+ std::array<std::pair<std::optional<unsigned>, std::optional<unsigned>>, 4>;
+
+/// \returns the S_SET_VGPR_MSB operand-index mapping for \p Desc.
+LLVM_ABI VGPRMSBOperandIndices
+getVGPRMSBOperandIndices(const MCInstrDesc &Desc);
+
/// \returns true if a memory instruction supports scale_offset modifier.
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode);
diff --git a/llvm/test/TableGen/get-named-operand-idx.td b/llvm/test/TableGen/get-named-operand-idx.td
index 5e6a9859f3603..5d2b905e1662f 100644
--- a/llvm/test/TableGen/get-named-operand-idx.td
+++ b/llvm/test/TableGen/get-named-operand-idx.td
@@ -1,10 +1,17 @@
-// RUN: llvm-tblgen -gen-instr-info -I %p/../../include %s | FileCheck %s
+// RUN: llvm-tblgen -gen-instr-info -I %p/../../include \
+// RUN: -D EXPORT_NAMED_OPERAND_LOOKUP %s | FileCheck %s
+// RUN: llvm-tblgen -gen-instr-info -I %p/../../include %s | \
+// RUN: FileCheck %s --check-prefix=NOEXPORT
// Check that OpName enum and getNamedOperandIdx are as expected.
include "llvm/Target/Target.td"
-def archInstrInfo : InstrInfo { }
+def archInstrInfo : InstrInfo {
+#ifdef EXPORT_NAMED_OPERAND_LOOKUP
+ let ExportNamedOperandLookup = true;
+#endif
+}
def arch : Target {
let InstructionSet = archInstrInfo;
@@ -64,13 +71,17 @@ defm : RemapAllTargetPseudoPointerOperands<RegClass>;
// CHECK-NEXT: NUM_OPERAND_NAMES = 5,
// CHECK-NEXT: }; // enum class OpName
// CHECK-EMPTY:
-// CHECK-NEXT: LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name);
+// CHECK-NEXT: LLVM_ABI LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name);
// CHECK-NEXT: LLVM_READONLY OpName getOperandIdxName(uint32_t Opcode, int16_t Idx);
// CHECK-EMPTY:
// CHECK-NEXT: } // namespace llvm::MyNamespace
// CHECK-EMPTY:
// CHECK-NEXT: #endif // GET_INSTRINFO_OPERAND_ENUM
+// NOEXPORT-LABEL: #ifdef GET_INSTRINFO_OPERAND_ENUM
+// NOEXPORT-NOT: LLVM_ABI LLVM_READONLY int16_t getNamedOperandIdx
+// NOEXPORT: LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name);
+
// CHECK-LABEL: #ifdef GET_INSTRINFO_NAMED_OPS
// CHECK-NEXT: #undef GET_INSTRINFO_NAMED_OPS
// CHECK-EMPTY:
@@ -102,7 +113,7 @@ defm : RemapAllTargetPseudoPointerOperands<RegClass>;
// CHECK-NEXT: };
// CHECK-NEXT: return InstructionIndex[Opcode];
// CHECK-NEXT: }
-// CHECK-NEXT: LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name) {
+// CHECK-NEXT: LLVM_ABI LLVM_READONLY int16_t getNamedOperandIdx(uint32_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, },
@@ -126,3 +137,7 @@ defm : RemapAllTargetPseudoPointerOperands<RegClass>;
// CHECK-NEXT: } // namespace llvm::MyNamespace
// CHECK-EMPTY:
// CHECK-NEXT: #endif // GET_INSTRINFO_NAMED_OPS
+
+// NOEXPORT-LABEL: #ifdef GET_INSTRINFO_NAMED_OPS
+// NOEXPORT-NOT: LLVM_ABI LLVM_READONLY int16_t getNamedOperandIdx
+// NOEXPORT: LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName Name) {
diff --git a/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp b/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp
index 51fda88e66eca..0b87d3231fd2f 100644
--- a/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp
+++ b/llvm/unittests/Target/AMDGPU/AMDGPUUnitTests.cpp
@@ -10,6 +10,7 @@
#include "AMDGPUGenSubtargetInfo.inc"
#include "AMDGPUTargetMachine.h"
#include "GCNSubtarget.h"
+#include "Utils/AMDGPUBaseInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/TargetParser/AMDGPUTargetParser.h"
@@ -375,3 +376,51 @@ TEST_F(AMDGPUTestBase, TestGetNamedOperandIdx) {
}
}
}
+
+TEST_F(AMDGPUTestBase, TestGetVGPRMSBOperandIndices) {
+ std::unique_ptr<const GCNTargetMachine> TM =
+ createAMDGPUTargetMachine(Triple("amdgpu9.00-amd-"), "", "");
+ ASSERT_NE(TM, nullptr);
+ const MCInstrInfo *MCII = TM->getMCInstrInfo();
+
+ const MCInstrDesc &Move = MCII->get(AMDGPU::V_MOV_B32_e32);
+ const AMDGPU::VGPRMSBOperandIndices MoveIndices =
+ AMDGPU::getVGPRMSBOperandIndices(Move);
+ EXPECT_EQ(MoveIndices[0].first,
+ static_cast<unsigned>(AMDGPU::getNamedOperandIdx(
+ Move.getOpcode(), AMDGPU::OpName::src0)));
+ EXPECT_FALSE(MoveIndices[0].second);
+ EXPECT_FALSE(MoveIndices[1].first);
+ EXPECT_EQ(MoveIndices[3].first,
+ static_cast<unsigned>(AMDGPU::getNamedOperandIdx(
+ Move.getOpcode(), AMDGPU::OpName::vdst)));
+
+ const MCInstrDesc &FMAMK = MCII->get(AMDGPU::V_FMAMK_F32);
+ const AMDGPU::VGPRMSBOperandIndices FMAMKIndices =
+ AMDGPU::getVGPRMSBOperandIndices(FMAMK);
+ EXPECT_FALSE(FMAMKIndices[1].first);
+ EXPECT_EQ(FMAMKIndices[2].first,
+ static_cast<unsigned>(AMDGPU::getNamedOperandIdx(
+ FMAMK.getOpcode(), AMDGPU::OpName::src1)));
+
+ const MCInstrDesc &VOPD =
+ MCII->get(AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12);
+ const AMDGPU::VGPRMSBOperandIndices VOPDIndices =
+ AMDGPU::getVGPRMSBOperandIndices(VOPD);
+ EXPECT_EQ(VOPDIndices[0].first,
+ static_cast<unsigned>(AMDGPU::getNamedOperandIdx(
+ VOPD.getOpcode(), AMDGPU::OpName::src0X)));
+ EXPECT_EQ(VOPDIndices[0].second,
+ static_cast<unsigned>(AMDGPU::getNamedOperandIdx(
+ VOPD.getOpcode(), AMDGPU::OpName::src0Y)));
+}
+
+TEST_F(AMDGPUTestBase, TestIsHi16Reg) {
+ std::unique_ptr<const GCNTargetMachine> TM =
+ createAMDGPUTargetMachine(Triple("amdgpu9.00-amd-"), "", "");
+ ASSERT_NE(TM, nullptr);
+ const MCRegisterInfo &MRI = TM->getMCRegisterInfo();
+
+ EXPECT_TRUE(AMDGPU::isHi16Reg(AMDGPU::VGPR0_HI16, MRI));
+ EXPECT_FALSE(AMDGPU::isHi16Reg(AMDGPU::VGPR0_LO16, MRI));
+}
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 272912aa90f63..81a396004af69 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -274,9 +274,12 @@ static void emitGetInstructionIndexForOpLookup(
static void
emitGetNamedOperandIdx(raw_ostream &OS,
const MapVector<SmallVector<int>, unsigned> &OperandMap,
- unsigned MaxOperandNo, unsigned NumOperandNames) {
- OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName "
- "Name) {\n";
+ unsigned MaxOperandNo, unsigned NumOperandNames,
+ bool ExportNamedOperandLookup) {
+ if (ExportNamedOperandLookup)
+ OS << "LLVM_ABI ";
+ OS << "LLVM_READONLY int16_t "
+ "getNamedOperandIdx(uint32_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
@@ -399,6 +402,8 @@ void InstrInfoEmitter::emitOperandNameMappings(
const size_t NumOperandNames = OperandNameToID.size();
const unsigned MaxNumOperands = MaxOperandNo + 1;
+ const bool ExportNamedOperandLookup =
+ Target.getInstructionSet()->getValueAsBit("ExportNamedOperandLookup");
const SmallString<32> Namespace({"llvm::", Target.getInstNamespace()});
{
@@ -414,8 +419,10 @@ void InstrInfoEmitter::emitOperandNameMappings(
OS << " NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
OS << "}; // enum class OpName\n\n";
- OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint32_t Opcode, OpName "
- "Name);\n";
+ if (ExportNamedOperandLookup)
+ OS << "LLVM_ABI ";
+ OS << "LLVM_READONLY int16_t "
+ "getNamedOperandIdx(uint32_t Opcode, OpName Name);\n";
OS << "LLVM_READONLY OpName getOperandIdxName(uint32_t Opcode, int16_t "
"Idx);\n";
}
@@ -425,7 +432,8 @@ void InstrInfoEmitter::emitOperandNameMappings(
NamespaceEmitter NS(OS, Namespace);
emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);
- emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames);
+ emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames,
+ ExportNamedOperandLookup);
emitGetOperandIdxName(OS, OperandNameToID, OperandMap, MaxNumOperands,
NumOperandNames);
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/217016
More information about the llvm-commits
mailing list