From 0f95014e38ba511a58321b74bfb6a88603e40054 Mon Sep 17 00:00:00 2001 From: Ronak Chauhan Date: Fri, 24 Jul 2020 15:21:46 +0530 Subject: [PATCH] [llvm-objdump][AMDGPU] Detect CPU string AMDGPU ISA isn't backwards compatible and hence -mcpu must always be specified during disassembly. However, the AMDGPU target CPU is stored in e_flags in the ELF object. This patch allows targets to implement CPU string detection, and also implements it for AMDGPU by looking at e_flags. Reviewed By: scott.linder Differential Revision: https://reviews.llvm.org/D84519 --- include/llvm/Object/ELFObjectFile.h | 4 + include/llvm/Object/ObjectFile.h | 1 + lib/Object/ELFObjectFile.cpp | 111 ++++++++++++++++++ .../llvm-objdump/ELF/AMDGPU/subtarget.ll | 83 +++++++++++++ tools/llvm-objdump/llvm-objdump.cpp | 4 + 5 files changed, 203 insertions(+) create mode 100644 test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 35a54c7045b..d8e1b7e8819 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -86,6 +86,10 @@ public: SubtargetFeatures getRISCVFeatures() const; + Optional tryGetCPUName() const override; + + StringRef getAMDGPUCPUName() const; + void setARMSubArch(Triple &TheTriple) const override; virtual uint16_t getEType() const = 0; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 8e893720171..744e33d2d9f 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -327,6 +327,7 @@ public: virtual StringRef getFileFormatName() const = 0; virtual Triple::ArchType getArch() const = 0; virtual SubtargetFeatures getFeatures() const = 0; + virtual Optional tryGetCPUName() const { return None; }; virtual void setARMSubArch(Triple &TheTriple) const { } virtual Expected getStartAddress() const { return errorCodeToError(object_error::parse_failed); diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 72eaeb78a21..91ed60a814a 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -355,6 +355,117 @@ SubtargetFeatures ELFObjectFileBase::getFeatures() const { } } +Optional ELFObjectFileBase::tryGetCPUName() const { + switch (getEMachine()) { + case ELF::EM_AMDGPU: + return getAMDGPUCPUName(); + default: + return None; + } +} + +StringRef ELFObjectFileBase::getAMDGPUCPUName() const { + assert(getEMachine() == ELF::EM_AMDGPU); + unsigned CPU = getPlatformFlags() & ELF::EF_AMDGPU_MACH; + + switch (CPU) { + // Radeon HD 2000/3000 Series (R600). + case ELF::EF_AMDGPU_MACH_R600_R600: + return "r600"; + case ELF::EF_AMDGPU_MACH_R600_R630: + return "r630"; + case ELF::EF_AMDGPU_MACH_R600_RS880: + return "rs880"; + case ELF::EF_AMDGPU_MACH_R600_RV670: + return "rv670"; + + // Radeon HD 4000 Series (R700). + case ELF::EF_AMDGPU_MACH_R600_RV710: + return "rv710"; + case ELF::EF_AMDGPU_MACH_R600_RV730: + return "rv730"; + case ELF::EF_AMDGPU_MACH_R600_RV770: + return "rv770"; + + // Radeon HD 5000 Series (Evergreen). + case ELF::EF_AMDGPU_MACH_R600_CEDAR: + return "cedar"; + case ELF::EF_AMDGPU_MACH_R600_CYPRESS: + return "cypress"; + case ELF::EF_AMDGPU_MACH_R600_JUNIPER: + return "juniper"; + case ELF::EF_AMDGPU_MACH_R600_REDWOOD: + return "redwood"; + case ELF::EF_AMDGPU_MACH_R600_SUMO: + return "sumo"; + + // Radeon HD 6000 Series (Northern Islands). + case ELF::EF_AMDGPU_MACH_R600_BARTS: + return "barts"; + case ELF::EF_AMDGPU_MACH_R600_CAICOS: + return "caicos"; + case ELF::EF_AMDGPU_MACH_R600_CAYMAN: + return "cayman"; + case ELF::EF_AMDGPU_MACH_R600_TURKS: + return "turks"; + + // AMDGCN GFX6. + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX600: + return "gfx600"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX601: + return "gfx601"; + + // AMDGCN GFX7. + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX700: + return "gfx700"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX701: + return "gfx701"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX702: + return "gfx702"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX703: + return "gfx703"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX704: + return "gfx704"; + + // AMDGCN GFX8. + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX801: + return "gfx801"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX802: + return "gfx802"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX803: + return "gfx803"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX810: + return "gfx810"; + + // AMDGCN GFX9. + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX900: + return "gfx900"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX902: + return "gfx902"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX904: + return "gfx904"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX906: + return "gfx906"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX908: + return "gfx908"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX909: + return "gfx909"; + + // AMDGCN GFX10. + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1010: + return "gfx1010"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1011: + return "gfx1011"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1012: + return "gfx1012"; + case ELF::EF_AMDGPU_MACH_AMDGCN_GFX1030: + return "gfx1030"; + + default: + llvm_unreachable("Unknown EF_AMDGPU_MACH value"); + } +} + // FIXME Encode from a tablegen description or target parser. void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const { if (TheTriple.getSubArch() != Triple::NoSubArch) diff --git a/test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll b/test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll new file mode 100644 index 00000000000..e49ee40782b --- /dev/null +++ b/test/tools/llvm-objdump/ELF/AMDGPU/subtarget.ll @@ -0,0 +1,83 @@ +define amdgpu_kernel void @test_kernel() { + ret void +} + +; Test subtarget detection. Disassembly is only supported for GFX8 and beyond. +; +; ----------------------------------GFX10-------------------------------------- +; +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1030 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1030 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1012 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1012 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1011 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1011 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1010 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx1010 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + + +; ----------------------------------GFX9--------------------------------------- +; +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx909 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx909 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx908 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx908 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx906 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx906 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx904 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx904 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx902 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx902 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx900 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + + +; ----------------------------------GFX8--------------------------------------- +; +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx810 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx810 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx803 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx802 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx802 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt + +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx801 -filetype=obj -O0 -o %t.o %s +; RUN: llvm-objdump -D --arch-name=amdgcn --mcpu=gfx801 %t.o > %t-specify.txt +; RUN: llvm-objdump -D %t.o > %t-detect.txt +; RUN: diff %t-specify.txt %t-detect.txt diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index ecdd227d08b..6b3ecd9cef1 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -2170,6 +2170,10 @@ static void disassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (!AsmInfo) reportError(Obj->getFileName(), "no assembly info for target " + TripleName); + + if (MCPU.empty()) + MCPU = Obj->tryGetCPUName().getValueOr("").str(); + std::unique_ptr STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString())); if (!STI)