[llvm] 8dd3d1c - [AMDGPU] Add symbolic names for gfx940 HWREGs

Stanislav Mekhanoshin via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 14 16:13:42 PDT 2022


Author: Stanislav Mekhanoshin
Date: 2022-03-14T16:13:33-07:00
New Revision: 8dd3d1cf1fec5e9c75bbf95b19d0c5099a592ac0

URL: https://github.com/llvm/llvm-project/commit/8dd3d1cf1fec5e9c75bbf95b19d0c5099a592ac0
DIFF: https://github.com/llvm/llvm-project/commit/8dd3d1cf1fec5e9c75bbf95b19d0c5099a592ac0.diff

LOG: [AMDGPU] Add symbolic names for gfx940 HWREGs

The namespaces of HWREGs is now overlapping with gfx10. Thus the
patch is longer than necessary to just support new names. It also
need to handle proper error messages, i.e. to issue a "specified
hardware register is not supported on this GPU" message.

This may need a major refactoring in the future.

Differential Revision: https://reviews.llvm.org/D121418

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
    llvm/lib/Target/AMDGPU/SIDefines.h
    llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
    llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
    llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
    llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
    llvm/test/MC/AMDGPU/gfx940_asm_features.s
    llvm/test/MC/AMDGPU/gfx940_err.s
    llvm/test/MC/Disassembler/AMDGPU/gfx940_dasm_features.txt

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index d188f4e3ab3a2..f46136df55291 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -1542,6 +1542,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
     int64_t Id;
     bool IsSymbolic = false;
     bool IsDefined = false;
+    StringRef Name;
 
     OperandInfoTy(int64_t Id_) : Id(Id_) {}
   };
@@ -6245,6 +6246,7 @@ AMDGPUAsmParser::parseHwregBody(OperandInfoTy &HwReg,
   if (isToken(AsmToken::Identifier) &&
       (HwReg.Id = getHwregId(getTokenStr(), getSTI())) >= 0) {
     HwReg.IsSymbolic = true;
+    HwReg.Name = getTokenStr();
     lex(); // skip register name
   } else if (!parseExpr(HwReg.Id, "a register name")) {
     return false;
@@ -6276,7 +6278,8 @@ AMDGPUAsmParser::validateHwreg(const OperandInfoTy &HwReg,
 
   using namespace llvm::AMDGPU::Hwreg;
 
-  if (HwReg.IsSymbolic && !isValidHwreg(HwReg.Id, getSTI())) {
+  if (HwReg.IsSymbolic &&
+      !isValidHwreg(HwReg.Id, getSTI(), HwReg.Name)) {
     Error(HwReg.Loc,
           "specified hardware register is not supported on this GPU");
     return false;

diff  --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h
index f6c2cf10fa0a1..56371514e5e55 100644
--- a/llvm/lib/Target/AMDGPU/SIDefines.h
+++ b/llvm/lib/Target/AMDGPU/SIDefines.h
@@ -378,6 +378,13 @@ enum Id { // HwRegCode, (6) [5:0]
   ID_TBA_HI = 17,
   ID_TMA_LO = 18,
   ID_TMA_HI = 19,
+  ID_XCC_ID = 20,
+  ID_SYMBOLIC_FIRST_GFX940_ = ID_XCC_ID,
+  ID_SQ_PERF_SNAPSHOT_DATA = 21,
+  ID_SQ_PERF_SNAPSHOT_DATA1 = 22,
+  ID_SQ_PERF_SNAPSHOT_PC_LO = 23,
+  ID_SQ_PERF_SNAPSHOT_PC_HI = 24,
+  ID_SYMBOLIC_LAST_GFX940_ = ID_SQ_PERF_SNAPSHOT_PC_HI + 1,
   ID_FLAT_SCR_LO = 20,
   ID_SYMBOLIC_FIRST_GFX10_ = ID_FLAT_SCR_LO,
   ID_FLAT_SCR_HI = 21,

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
index 18c348d1cf898..44f25d82da1e4 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
@@ -88,6 +88,16 @@ const char* const IdSymbolic[] = {
   "HW_REG_SHADER_CYCLES"
 };
 
+// This is gfx940 specific portion from ID_SYMBOLIC_FIRST_GFX940_ to
+// ID_SYMBOLIC_LAST_GFX940_
+const char* const IdSymbolicGFX940Specific[] = {
+  "HW_REG_XCC_ID",
+  "HW_REG_SQ_PERF_SNAPSHOT_DATA",
+  "HW_REG_SQ_PERF_SNAPSHOT_DATA1",
+  "HW_REG_SQ_PERF_SNAPSHOT_PC_LO",
+  "HW_REG_SQ_PERF_SNAPSHOT_PC_HI"
+};
+
 } // namespace Hwreg
 
 namespace MTBUFFormat {

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
index d1deb570a938d..2b46bb0782b65 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
@@ -28,6 +28,7 @@ extern const char *const OpGsSymbolic[OP_GS_LAST_];
 namespace Hwreg { // Symbolic names for the hwreg(...) syntax.
 
 extern const char* const IdSymbolic[];
+extern const char* const IdSymbolicGFX940Specific[];
 
 } // namespace Hwreg
 

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index ce034dca3691e..29eba61cafa0e 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -1044,12 +1044,24 @@ unsigned encodeWaitcnt(const IsaVersion &Version, const Waitcnt &Decoded) {
 
 namespace Hwreg {
 
+static const char* getHwregName(int64_t Id, const MCSubtargetInfo &STI) {
+  if (isGFX940(STI) && Id >= ID_SYMBOLIC_FIRST_GFX940_ &&
+      Id < ID_SYMBOLIC_LAST_GFX940_)
+    return IdSymbolicGFX940Specific[Id - ID_SYMBOLIC_FIRST_GFX940_];
+  return (Id < ID_SYMBOLIC_LAST_) ? IdSymbolic[Id] : nullptr;
+}
+
 int64_t getHwregId(const StringRef Name, const MCSubtargetInfo &STI) {
   if (isGFX10(STI) && Name == "HW_REG_HW_ID") // An alias
     return ID_HW_ID1;
   for (int Id = ID_SYMBOLIC_FIRST_; Id < ID_SYMBOLIC_LAST_; ++Id) {
     if (IdSymbolic[Id] && Name == IdSymbolic[Id])
       return Id;
+    // These are all defined, however may be invalid for subtarget and need
+    // further validation.
+    if (Id >= ID_SYMBOLIC_FIRST_GFX940_ && Id < ID_SYMBOLIC_LAST_GFX940_ &&
+        Name == IdSymbolicGFX940Specific[Id - ID_SYMBOLIC_FIRST_GFX940_])
+      return Id;
   }
   return ID_UNKNOWN_;
 }
@@ -1057,6 +1069,8 @@ int64_t getHwregId(const StringRef Name, const MCSubtargetInfo &STI) {
 static unsigned getLastSymbolicHwreg(const MCSubtargetInfo &STI) {
   if (isSI(STI) || isCI(STI) || isVI(STI))
     return ID_SYMBOLIC_FIRST_GFX9_;
+  else if (isGFX940(STI))
+    return ID_SYMBOLIC_LAST_GFX940_;
   else if (isGFX9(STI))
     return ID_SYMBOLIC_FIRST_GFX10_;
   else if (isGFX10(STI) && !isGFX10_BEncoding(STI))
@@ -1065,19 +1079,34 @@ static unsigned getLastSymbolicHwreg(const MCSubtargetInfo &STI) {
     return ID_SYMBOLIC_LAST_;
 }
 
-bool isValidHwreg(int64_t Id, const MCSubtargetInfo &STI) {
-  switch (Id) {
-  case ID_HW_ID:
-    return isSI(STI) || isCI(STI) || isVI(STI) || isGFX9(STI);
-  case ID_HW_ID1:
-  case ID_HW_ID2:
-    return isGFX10Plus(STI);
-  case ID_XNACK_MASK:
-    return isGFX10(STI) && !AMDGPU::isGFX10_BEncoding(STI);
-  default:
-    return ID_SYMBOLIC_FIRST_ <= Id && Id < getLastSymbolicHwreg(STI) &&
-           IdSymbolic[Id];
+bool isValidHwreg(int64_t Id, const MCSubtargetInfo &STI, StringRef Name) {
+  if (isGFX10(STI) && Name == "HW_REG_HW_ID") // An alias
+    return true;
+
+  const char *HWRegName = getHwregName(Id, STI);
+  if (!HWRegName || !Name.startswith(HWRegName))
+    return false;
+
+  if (isGFX10Plus(STI)) {
+    switch (Id) {
+    case ID_HW_ID1:
+    case ID_HW_ID2:
+      return true;
+    case ID_XNACK_MASK:
+      return !AMDGPU::isGFX10_BEncoding(STI);
+    default:
+      break;
+    }
   }
+
+  if (ID_SYMBOLIC_FIRST_ > Id || Id >= getLastSymbolicHwreg(STI))
+    return false;
+
+  if (isGFX940(STI) && Id >= ID_SYMBOLIC_FIRST_GFX10_ &&
+      Id < ID_SYMBOLIC_FIRST_GFX940_)
+    return false;
+
+  return true;
 }
 
 bool isValidHwreg(int64_t Id) {
@@ -1099,7 +1128,8 @@ uint64_t encodeHwreg(uint64_t Id, uint64_t Offset, uint64_t Width) {
 }
 
 StringRef getHwreg(unsigned Id, const MCSubtargetInfo &STI) {
-  return isValidHwreg(Id, STI) ? IdSymbolic[Id] : "";
+  const char *HWRegName = getHwregName(Id, STI);
+  return (HWRegName && isValidHwreg(Id, STI, HWRegName)) ? HWRegName : "";
 }
 
 void decodeHwreg(unsigned Val, unsigned &Id, unsigned &Offset, unsigned &Width) {

diff  --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 5526d18b2dcc8..0677c23d9b82d 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -612,8 +612,8 @@ namespace Hwreg {
 LLVM_READONLY
 int64_t getHwregId(const StringRef Name, const MCSubtargetInfo &STI);
 
-LLVM_READNONE
-bool isValidHwreg(int64_t Id, const MCSubtargetInfo &STI);
+LLVM_READONLY
+bool isValidHwreg(int64_t Id, const MCSubtargetInfo &STI, StringRef Name);
 
 LLVM_READNONE
 bool isValidHwreg(int64_t Id);

diff  --git a/llvm/test/MC/AMDGPU/gfx940_asm_features.s b/llvm/test/MC/AMDGPU/gfx940_asm_features.s
index 56d25976bfbef..28d0c0311a3c0 100644
--- a/llvm/test/MC/AMDGPU/gfx940_asm_features.s
+++ b/llvm/test/MC/AMDGPU/gfx940_asm_features.s
@@ -197,6 +197,47 @@ scratch_load_lds_ushort v2, off
 // GFX940: scratch_load_lds_sshort v2, off         ; encoding: [0x00,0x60,0xa4,0xdc,0x02,0x00,0x7f,0x00]
 scratch_load_lds_sshort v2, off
 
+// NOT-GFX940: error: specified hardware register is not supported on this GPU
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_XCC_ID)   ; encoding: [0x14,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(HW_REG_XCC_ID)
+
+// NOT-GFX940: error: specified hardware register is not supported on this GPU
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA) ; encoding: [0x15,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA)
+
+// NOT-GFX940: error: specified hardware register is not supported on this GPU
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA1) ; encoding: [0x16,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA1)
+
+// NOT-GFX940: error: specified hardware register is not supported on this GPU
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_LO) ; encoding: [0x17,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_LO)
+
+// NOT-GFX940: error: specified hardware register is not supported on this GPU
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_HI) ; encoding: [0x18,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_HI)
+
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_TMA_HI)   ; encoding: [0x13,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(19)
+
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_XCC_ID)   ; encoding: [0x14,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(20)
+
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA) ; encoding: [0x15,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(21)
+
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA1) ; encoding: [0x16,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(22)
+
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_LO) ; encoding: [0x17,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(23)
+
+// GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_HI) ; encoding: [0x18,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(24)
+
+// GFX940: s_getreg_b32 s1, hwreg(25)              ; encoding: [0x19,0xf8,0x81,0xb8]
+s_getreg_b32 s1, hwreg(25)
+
 // NOT-GFX940: error: instruction not supported on this GPU
 // GFX940: v_mov_b64_e32 v[2:3], v[4:5]            ; encoding: [0x04,0x71,0x04,0x7e]
 v_mov_b64 v[2:3], v[4:5]

diff  --git a/llvm/test/MC/AMDGPU/gfx940_err.s b/llvm/test/MC/AMDGPU/gfx940_err.s
index 832754d4a7600..2b3ad0a193e32 100644
--- a/llvm/test/MC/AMDGPU/gfx940_err.s
+++ b/llvm/test/MC/AMDGPU/gfx940_err.s
@@ -57,3 +57,21 @@ buffer_wbl2 glc
 
 buffer_wbl2 scc
 // GFX940: error: invalid operand for instruction
+
+s_getreg_b32 s1, hwreg(HW_REG_FLAT_SCR_LO)
+// GFX940: error: specified hardware register is not supported on this GPU
+
+s_getreg_b32 s1, hwreg(HW_REG_FLAT_SCR_HI)
+// GFX940: error: specified hardware register is not supported on this GPU
+
+s_getreg_b32 s1, hwreg(HW_REG_XNACK_MASK)
+// GFX940: error: specified hardware register is not supported on this GPU
+
+s_getreg_b32 s1, hwreg(HW_REG_HW_ID1)
+// GFX940: error: specified hardware register is not supported on this GPU
+
+s_getreg_b32 s1, hwreg(HW_REG_HW_ID2)
+// GFX940: error: specified hardware register is not supported on this GPU
+
+s_getreg_b32 s1, hwreg(HW_REG_POPS_PACKER)
+// GFX940: error: specified hardware register is not supported on this GPU

diff  --git a/llvm/test/MC/Disassembler/AMDGPU/gfx940_dasm_features.txt b/llvm/test/MC/Disassembler/AMDGPU/gfx940_dasm_features.txt
index 39dcf53452a4b..36b218a4a59b9 100644
--- a/llvm/test/MC/Disassembler/AMDGPU/gfx940_dasm_features.txt
+++ b/llvm/test/MC/Disassembler/AMDGPU/gfx940_dasm_features.txt
@@ -141,6 +141,21 @@
 # GFX940: scratch_load_lds_sshort v2, off         ; encoding: [0x00,0x60,0xa4,0xdc,0x02,0x00,0x7f,0x00]
 0x00,0x60,0xa4,0xdc,0x02,0x00,0x7f,0x00
 
+# GFX940: s_getreg_b32 s1, hwreg(HW_REG_XCC_ID)   ; encoding: [0x14,0xf8,0x81,0xb8]
+0x14,0xf8,0x81,0xb8
+
+# GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA) ; encoding: [0x15,0xf8,0x81,0xb8]
+0x15,0xf8,0x81,0xb8
+
+# GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_DATA1) ; encoding: [0x16,0xf8,0x81,0xb8]
+0x16,0xf8,0x81,0xb8
+
+# GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_LO) ; encoding: [0x17,0xf8,0x81,0xb8]
+0x17,0xf8,0x81,0xb8
+
+# GFX940: s_getreg_b32 s1, hwreg(HW_REG_SQ_PERF_SNAPSHOT_PC_HI) ; encoding: [0x18,0xf8,0x81,0xb8]
+0x18,0xf8,0x81,0xb8
+
 # GFX940: v_mov_b64_e32 v[2:3], v[4:5]            ; encoding: [0x04,0x71,0x04,0x7e]
 0x04,0x71,0x04,0x7e
 


        


More information about the llvm-commits mailing list