From 9c05b2bc3b848f40731d0207170f6f2d08aba9f3 Mon Sep 17 00:00:00 2001 From: Konstantin Zhuravlyov Date: Sat, 14 Oct 2017 15:40:33 +0000 Subject: [PATCH] AMDGPU: Add support for isa version note - Emit NT_AMD_AMDGPU_ISA - Add assembler parsing for isa version directive - If isa version directive does not match command line arguments, then return error Differential Revision: https://reviews.llvm.org/D38748 llvm-svn: 315808 --- llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp | 22 ++++++++++---- .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 23 ++++++++++++++ .../MCTargetDesc/AMDGPUTargetStreamer.cpp | 30 +++++++++++++++++-- .../MCTargetDesc/AMDGPUTargetStreamer.h | 13 +++++++- .../Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp | 15 ++++++++++ llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h | 4 +++ llvm/test/CodeGen/AMDGPU/elf-notes.ll | 25 ++++++++++++++++ llvm/test/MC/AMDGPU/isa-version-hsa.s | 14 +++++++++ llvm/test/MC/AMDGPU/isa-version-pal.s | 13 ++++++++ llvm/test/MC/AMDGPU/isa-version-unk.s | 14 +++++++++ 10 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 llvm/test/CodeGen/AMDGPU/elf-notes.ll create mode 100644 llvm/test/MC/AMDGPU/isa-version-hsa.s create mode 100644 llvm/test/MC/AMDGPU/isa-version-pal.s create mode 100644 llvm/test/MC/AMDGPU/isa-version-unk.s diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp index 142543cc47e3..bbe0879499ea 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp @@ -132,6 +132,22 @@ void AMDGPUAsmPrinter::EmitStartOfAsmFile(Module &M) { } void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) { + if (TM.getTargetTriple().getArch() != Triple::amdgcn) + return; + + // Emit ISA Version (NT_AMD_AMDGPU_ISA). + std::string ISAVersionString; + raw_string_ostream ISAVersionStream(ISAVersionString); + IsaInfo::streamIsaVersion(getSTI(), ISAVersionStream); + getTargetStreamer().EmitISAVersion(ISAVersionStream.str()); + + // Emit HSA Metadata (NT_AMD_AMDGPU_HSA_METADATA). + if (TM.getTargetTriple().getOS() == Triple::AMDHSA) { + HSAMetadataStream.end(); + getTargetStreamer().EmitHSAMetadata(HSAMetadataStream.getHSAMetadata()); + } + + // Emit PAL Metadata (NT_AMD_AMDGPU_PAL_METADATA). if (TM.getTargetTriple().getOS() == Triple::AMDPAL) { // Copy the PAL metadata from the map where we collected it into a vector, // then write it as a .note. @@ -142,12 +158,6 @@ void AMDGPUAsmPrinter::EmitEndOfAsmFile(Module &M) { } getTargetStreamer().EmitPALMetadata(PALMetadataVector); } - - if (TM.getTargetTriple().getOS() != Triple::AMDHSA) - return; - - HSAMetadataStream.end(); - getTargetStreamer().EmitHSAMetadata(HSAMetadataStream.getHSAMetadata()); } bool AMDGPUAsmPrinter::isBlockOnlyReachableByFallthrough( diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 519c24b7c458..7f8c28e9c243 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -832,6 +832,7 @@ private: bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const; bool ParseDirectiveAMDGPUHsaKernel(); + bool ParseDirectiveISAVersion(); bool ParseDirectiveHSAMetadata(); bool ParseDirectivePALMetadata(); @@ -2452,6 +2453,25 @@ bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() { return false; } +bool AMDGPUAsmParser::ParseDirectiveISAVersion() { + auto ISAVersionStringFromASM = getLexer().getTok().getStringContents(); + + std::string ISAVersionStringFromSTI; + raw_string_ostream ISAVersionStreamFromSTI(ISAVersionStringFromSTI); + IsaInfo::streamIsaVersion(&getSTI(), ISAVersionStreamFromSTI); + + if (ISAVersionStringFromASM != ISAVersionStreamFromSTI.str()) { + return Error(getParser().getTok().getLoc(), + ".amd_amdgpu_isa directive does not match triple and/or mcpu " + "arguments specified through the command line"); + } + + getTargetStreamer().EmitISAVersion(ISAVersionStreamFromSTI.str()); + Lex(); + + return false; +} + bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() { std::string HSAMetadataString; raw_string_ostream YamlStream(HSAMetadataString); @@ -2527,6 +2547,9 @@ bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) { if (IDVal == ".amdgpu_hsa_kernel") return ParseDirectiveAMDGPUHsaKernel(); + if (IDVal == ".amd_amdgpu_isa") + return ParseDirectiveISAVersion(); + if (IDVal == AMDGPU::HSAMD::AssemblerDirectiveBegin) return ParseDirectiveHSAMetadata(); diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp index 4d4fdf6ed85a..d897956daccf 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp @@ -39,9 +39,6 @@ using namespace llvm::AMDGPU; // AMDGPUTargetStreamer //===----------------------------------------------------------------------===// -AMDGPUTargetStreamer::AMDGPUTargetStreamer(MCStreamer &S) - : MCTargetStreamer(S) {} - bool AMDGPUTargetStreamer::EmitHSAMetadata(StringRef HSAMetadataString) { HSAMD::Metadata HSAMetadata; if (HSAMD::fromString(HSAMetadataString, HSAMetadata)) @@ -94,6 +91,11 @@ void AMDGPUTargetAsmStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, } } +bool AMDGPUTargetAsmStreamer::EmitISAVersion(StringRef IsaVersionString) { + OS << "\t.amd_amdgpu_isa \"" << IsaVersionString << "\"\n"; + return true; +} + bool AMDGPUTargetAsmStreamer::EmitHSAMetadata( const AMDGPU::HSAMD::Metadata &HSAMetadata) { std::string HSAMetadataString; @@ -208,6 +210,28 @@ void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, Symbol->setType(ELF::STT_AMDGPU_HSA_KERNEL); } +bool AMDGPUTargetELFStreamer::EmitISAVersion(StringRef IsaVersionString) { + // Create two labels to mark the beginning and end of the desc field + // and a MCExpr to calculate the size of the desc field. + auto &Context = getContext(); + auto *DescBegin = Context.createTempSymbol(); + auto *DescEnd = Context.createTempSymbol(); + auto *DescSZ = MCBinaryExpr::createSub( + MCSymbolRefExpr::create(DescEnd, Context), + MCSymbolRefExpr::create(DescBegin, Context), Context); + + EmitAMDGPUNote( + DescSZ, + ELF::NT_AMD_AMDGPU_ISA, + [&](MCELFStreamer &OS) { + OS.EmitLabel(DescBegin); + OS.EmitBytes(IsaVersionString); + OS.EmitLabel(DescEnd); + } + ); + return true; +} + bool AMDGPUTargetELFStreamer::EmitHSAMetadata( const AMDGPU::HSAMD::Metadata &HSAMetadata) { std::string HSAMetadataString; diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h index 7791f0d03ac3..0919b754480d 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.h @@ -12,6 +12,7 @@ #include "AMDKernelCodeT.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/AMDGPUMetadata.h" namespace llvm { @@ -30,7 +31,8 @@ protected: MCContext &getContext() const { return Streamer.getContext(); } public: - AMDGPUTargetStreamer(MCStreamer &S); + AMDGPUTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {} + virtual void EmitDirectiveHSACodeObjectVersion(uint32_t Major, uint32_t Minor) = 0; @@ -43,6 +45,9 @@ public: virtual void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) = 0; + /// \returns True on success, false on failure. + virtual bool EmitISAVersion(StringRef IsaVersionString) = 0; + /// \returns True on success, false on failure. virtual bool EmitHSAMetadata(StringRef HSAMetadataString); @@ -68,6 +73,9 @@ public: void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; + /// \returns True on success, false on failure. + bool EmitISAVersion(StringRef IsaVersionString) override; + /// \returns True on success, false on failure. bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) override; @@ -97,6 +105,9 @@ public: void EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) override; + /// \returns True on success, false on failure. + bool EmitISAVersion(StringRef IsaVersionString) override; + /// \returns True on success, false on failure. bool EmitHSAMetadata(const AMDGPU::HSAMD::Metadata &HSAMetadata) override; diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp index 2c3e6ba01775..ce9dc4f744df 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -147,6 +147,21 @@ IsaVersion getIsaVersion(const FeatureBitset &Features) { return {7, 0, 0}; } +void streamIsaVersion(const MCSubtargetInfo *STI, raw_ostream &Stream) { + auto TargetTriple = STI->getTargetTriple(); + auto ISAVersion = IsaInfo::getIsaVersion(STI->getFeatureBits()); + + Stream << TargetTriple.getArchName() << '-' + << TargetTriple.getVendorName() << '-' + << TargetTriple.getOSName() << '-' + << TargetTriple.getEnvironmentName() << '-' + << "gfx" + << ISAVersion.Major + << ISAVersion.Minor + << ISAVersion.Stepping; + Stream.flush(); +} + unsigned getWavefrontSize(const FeatureBitset &Features) { if (Features.test(FeatureWavefrontSize16)) return 16; diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h index ea9dcdf8f3c2..aaa7b1495d70 100644 --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -19,6 +19,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include +#include #include namespace llvm { @@ -54,6 +55,9 @@ struct IsaVersion { /// \returns Isa version for given subtarget \p Features. IsaVersion getIsaVersion(const FeatureBitset &Features); +/// \brief Streams isa version string for given subtarget \p STI into \p Stream. +void streamIsaVersion(const MCSubtargetInfo *STI, raw_ostream &Stream); + /// \returns Wavefront size for given subtarget \p Features. unsigned getWavefrontSize(const FeatureBitset &Features); diff --git a/llvm/test/CodeGen/AMDGPU/elf-notes.ll b/llvm/test/CodeGen/AMDGPU/elf-notes.ll new file mode 100644 index 000000000000..3d9393cc3e1e --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/elf-notes.ll @@ -0,0 +1,25 @@ +; RUN: llc -mtriple=amdgcn-amd-unknown -mcpu=gfx800 < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s +; RUN: llc -mtriple=amdgcn-amd-unknown -mcpu=iceland < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx800 < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=iceland < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s +; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx800 < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s +; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=iceland < %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s +; RUN: llc -march=r600 < %s | FileCheck --check-prefix=R600 %s + +; OSABI-UNK: .amd_amdgpu_isa "amdgcn-amd-unknown--gfx800" +; OSABI-UNK-NOT: .amd_amdgpu_hsa_metadata +; OSABI-UNK-NOT: .amd_amdgpu_pal_metadata + +; OSABI-HSA: .amd_amdgpu_isa "amdgcn-amd-amdhsa--gfx800" +; OSABI-HSA: .amd_amdgpu_hsa_metadata + +; OSABI-PAL: .amd_amdgpu_isa "amdgcn-amd-amdpal--gfx800" +; OSABI-PAL: .amd_amdgpu_pal_metadata + +; R600-NOT: .amd_amdgpu_isa +; R600-NOT: .amd_amdgpu_hsa_metadata +; R600-NOT: .amd_amdgpu_hsa_metadata + +define amdgpu_kernel void @elf_notes() { + ret void +} diff --git a/llvm/test/MC/AMDGPU/isa-version-hsa.s b/llvm/test/MC/AMDGPU/isa-version-hsa.s new file mode 100644 index 000000000000..8917939f3643 --- /dev/null +++ b/llvm/test/MC/AMDGPU/isa-version-hsa.s @@ -0,0 +1,14 @@ +// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s +// RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx800 %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s +// RUN: llvm-mc -triple amdgcn-amd-amdhsa -mcpu=iceland %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx803 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s + + +// OSABI-HSA: .amd_amdgpu_isa "amdgcn-amd-amdhsa--gfx800" +// OSABI-UNK-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +// OSABI-HSA-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +// OSABI-PAL-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +.amd_amdgpu_isa "amdgcn-amd-amdhsa--gfx800" diff --git a/llvm/test/MC/AMDGPU/isa-version-pal.s b/llvm/test/MC/AMDGPU/isa-version-pal.s new file mode 100644 index 000000000000..1e5530690002 --- /dev/null +++ b/llvm/test/MC/AMDGPU/isa-version-pal.s @@ -0,0 +1,13 @@ +// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s +// RUN: llvm-mc -triple amdgcn-amd-amdpal -mcpu=gfx800 %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s +// RUN: llvm-mc -triple amdgcn-amd-amdpal -mcpu=iceland %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx803 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s + +// OSABI-PAL: .amd_amdgpu_isa "amdgcn-amd-amdpal--gfx800" +// OSABI-UNK-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +// OSABI-HSA-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +// OSABI-PAL-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +.amd_amdgpu_isa "amdgcn-amd-amdpal--gfx800" diff --git a/llvm/test/MC/AMDGPU/isa-version-unk.s b/llvm/test/MC/AMDGPU/isa-version-unk.s new file mode 100644 index 000000000000..f0fd9d22756b --- /dev/null +++ b/llvm/test/MC/AMDGPU/isa-version-unk.s @@ -0,0 +1,14 @@ +// RUN: llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx800 %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s +// RUN: llvm-mc -triple amdgcn-amd-unknown -mcpu=iceland %s | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-unknown -mcpu=gfx803 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-UNK-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdhsa -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-HSA-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=gfx800 %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s +// RUN: not llvm-mc -triple amdgcn-amd-amdpal -mcpu=iceland %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=OSABI-PAL-ERR --check-prefix=GFX800 %s + + +// OSABI-UNK: .amd_amdgpu_isa "amdgcn-amd-unknown--gfx800" +// OSABI-UNK-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +// OSABI-HSA-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +// OSABI-PAL-ERR: error: .amd_amdgpu_isa directive does not match triple and/or mcpu arguments specified through the command line +.amd_amdgpu_isa "amdgcn-amd-unknown--gfx800"