[lld] 4f28303 - AMDGPU/LLD: Add target id and code object v4 support to linker

Konstantin Zhuravlyov via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 24 10:41:24 PDT 2021


Author: Konstantin Zhuravlyov
Date: 2021-03-24T13:41:10-04:00
New Revision: 4f283031335329a08e57eb121fbaf79592c2c286

URL: https://github.com/llvm/llvm-project/commit/4f283031335329a08e57eb121fbaf79592c2c286
DIFF: https://github.com/llvm/llvm-project/commit/4f283031335329a08e57eb121fbaf79592c2c286.diff

LOG: AMDGPU/LLD: Add target id and code object v4 support to linker

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

Added: 
    lld/test/ELF/amdgpu-tid.s

Modified: 
    lld/ELF/Arch/AMDGPU.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/AMDGPU.cpp b/lld/ELF/Arch/AMDGPU.cpp
index 4f4ce0094bbfd..c765d6e083002 100644
--- a/lld/ELF/Arch/AMDGPU.cpp
+++ b/lld/ELF/Arch/AMDGPU.cpp
@@ -22,6 +22,10 @@ using namespace lld::elf;
 
 namespace {
 class AMDGPU final : public TargetInfo {
+private:
+  uint32_t calcEFlagsV3() const;
+  uint32_t calcEFlagsV4() const;
+
 public:
   AMDGPU();
   uint32_t calcEFlags() const override;
@@ -44,8 +48,7 @@ static uint32_t getEFlags(InputFile *file) {
   return cast<ObjFile<ELF64LE>>(file)->getObj().getHeader().e_flags;
 }
 
-uint32_t AMDGPU::calcEFlags() const {
-  assert(!objectFiles.empty());
+uint32_t AMDGPU::calcEFlagsV3() const {
   uint32_t ret = getEFlags(objectFiles[0]);
 
   // Verify that all input files have the same e_flags.
@@ -58,6 +61,67 @@ uint32_t AMDGPU::calcEFlags() const {
   return ret;
 }
 
+uint32_t AMDGPU::calcEFlagsV4() const {
+  uint32_t retMach = getEFlags(objectFiles[0]) & EF_AMDGPU_MACH;
+  uint32_t retXnack = getEFlags(objectFiles[0]) & EF_AMDGPU_FEATURE_XNACK_V4;
+  uint32_t retSramEcc =
+      getEFlags(objectFiles[0]) & EF_AMDGPU_FEATURE_SRAMECC_V4;
+
+  // Verify that all input files have compatible e_flags (same mach, all
+  // features in the same category are either ANY, ANY and ON, or ANY and OFF).
+  for (InputFile *f : makeArrayRef(objectFiles).slice(1)) {
+    if (retMach != (getEFlags(f) & EF_AMDGPU_MACH)) {
+      error("incompatible mach: " + toString(f));
+      return 0;
+    }
+
+    if (retXnack == EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4 ||
+        (retXnack != EF_AMDGPU_FEATURE_XNACK_ANY_V4 &&
+            (getEFlags(f) & EF_AMDGPU_FEATURE_XNACK_V4)
+                != EF_AMDGPU_FEATURE_XNACK_ANY_V4)) {
+      if (retXnack != (getEFlags(f) & EF_AMDGPU_FEATURE_XNACK_V4)) {
+        error("incompatible xnack: " + toString(f));
+        return 0;
+      }
+    } else {
+      if (retXnack == EF_AMDGPU_FEATURE_XNACK_ANY_V4)
+        retXnack = getEFlags(f) & EF_AMDGPU_FEATURE_XNACK_V4;
+    }
+
+    if (retSramEcc == EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4 ||
+        (retSramEcc != EF_AMDGPU_FEATURE_SRAMECC_ANY_V4 &&
+            (getEFlags(f) & EF_AMDGPU_FEATURE_SRAMECC_V4) !=
+                EF_AMDGPU_FEATURE_SRAMECC_ANY_V4)) {
+      if (retSramEcc != (getEFlags(f) & EF_AMDGPU_FEATURE_SRAMECC_V4)) {
+        error("incompatible sramecc: " + toString(f));
+        return 0;
+      }
+    } else {
+      if (retSramEcc == EF_AMDGPU_FEATURE_SRAMECC_ANY_V4)
+        retSramEcc = getEFlags(f) & EF_AMDGPU_FEATURE_SRAMECC_V4;
+    }
+  }
+
+  return retMach | retXnack | retSramEcc;
+}
+
+uint32_t AMDGPU::calcEFlags() const {
+  assert(!objectFiles.empty());
+
+  uint8_t abiVersion = cast<ObjFile<ELF64LE>>(objectFiles[0])->getObj()
+      .getHeader().e_ident[EI_ABIVERSION];
+  switch (abiVersion) {
+  case ELFABIVERSION_AMDGPU_HSA_V2:
+  case ELFABIVERSION_AMDGPU_HSA_V3:
+    return calcEFlagsV3();
+  case ELFABIVERSION_AMDGPU_HSA_V4:
+    return calcEFlagsV4();
+  default:
+    error("unknown abi version: " + Twine(abiVersion));
+    return 0;
+  }
+}
+
 void AMDGPU::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const {
   switch (rel.type) {
   case R_AMDGPU_ABS32:

diff  --git a/lld/test/ELF/amdgpu-tid.s b/lld/test/ELF/amdgpu-tid.s
new file mode 100644
index 0000000000000..6623443a4541d
--- /dev/null
+++ b/lld/test/ELF/amdgpu-tid.s
@@ -0,0 +1,45 @@
+# REQUIRES: amdgpu
+
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=-xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-off0.o
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=-xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-off1.o
+# RUN: ld.lld -shared %t-xnack-off0.o %t-xnack-off1.o -o %t-xnack-off2.so
+# RUN: llvm-readobj --file-headers %t-xnack-off2.so | FileCheck --check-prefix=XNACK-OFF %s
+
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=+xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-on0.o
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=+xnack --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-on1.o
+# RUN: ld.lld -shared %t-xnack-on0.o %t-xnack-on1.o -o %t-xnack-on2.so
+# RUN: llvm-readobj --file-headers %t-xnack-on2.so | FileCheck --check-prefix=XNACK-ON %s
+
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 --amdhsa-code-object-version=4 -filetype=obj %s -o %t-xnack-any.o
+# RUN: ld.lld -shared %t-xnack-off0.o %t-xnack-any.o -o %t-xnack-off3.so
+# RUN: llvm-readobj --file-headers %t-xnack-off3.so | FileCheck --check-prefix=XNACK-OFF %s
+# RUN: ld.lld -shared %t-xnack-on0.o %t-xnack-any.o -o %t-xnack-on3.so
+# RUN: llvm-readobj --file-headers %t-xnack-on3.so | FileCheck --check-prefix=XNACK-ON %s
+
+# RUN: not ld.lld -shared %t-xnack-off0.o %t-xnack-on0.o -o /dev/null 2>&1 | FileCheck --check-prefix=XNACK-INCOMPATIBLE %s
+
+# XNACK-OFF:          EF_AMDGPU_FEATURE_XNACK_OFF_V4 (0x200)
+# XNACK-ON:           EF_AMDGPU_FEATURE_XNACK_ON_V4 (0x300)
+# XNACK-INCOMPATIBLE: incompatible xnack:
+
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=-sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-off0.o
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=-sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-off1.o
+# RUN: ld.lld -shared %t-sramecc-off0.o %t-sramecc-off1.o -o %t-sramecc-off2.so
+# RUN: llvm-readobj --file-headers %t-sramecc-off2.so | FileCheck --check-prefix=SRAMECC-OFF %s
+
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=+sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-on0.o
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 -mattr=+sramecc --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-on1.o
+# RUN: ld.lld -shared %t-sramecc-on0.o %t-sramecc-on1.o -o %t-sramecc-on2.so
+# RUN: llvm-readobj --file-headers %t-sramecc-on2.so | FileCheck --check-prefix=SRAMECC-ON %s
+
+# RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx906 --amdhsa-code-object-version=4 -filetype=obj %s -o %t-sramecc-any.o
+# RUN: ld.lld -shared %t-sramecc-off0.o %t-sramecc-any.o -o %t-sramecc-off3.so
+# RUN: llvm-readobj --file-headers %t-sramecc-off3.so | FileCheck --check-prefix=SRAMECC-OFF %s
+# RUN: ld.lld -shared %t-sramecc-on0.o %t-sramecc-any.o -o %t-sramecc-on3.so
+# RUN: llvm-readobj --file-headers %t-sramecc-on3.so | FileCheck --check-prefix=SRAMECC-ON %s
+
+# RUN: not ld.lld -shared %t-sramecc-off0.o %t-sramecc-on0.o -o /dev/null 2>&1 | FileCheck --check-prefix=SRAMECC-INCOMPATIBLE %s
+
+# SRAMECC-OFF:          EF_AMDGPU_FEATURE_SRAMECC_OFF_V4 (0x800)
+# SRAMECC-ON:           EF_AMDGPU_FEATURE_SRAMECC_ON_V4 (0xC00)
+# SRAMECC-INCOMPATIBLE: incompatible sramecc:


        


More information about the llvm-commits mailing list