AMDGPU/SI: Use .hsatext section instead of .text for HSA
authorTom Stellard <thomas.stellard@amd.com>
Fri, 25 Sep 2015 21:41:28 +0000 (21:41 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Fri, 25 Sep 2015 21:41:28 +0000 (21:41 +0000)
Reviewers: arsenm, grosbach, rafael

Subscribers: arsenm, llvm-commits

Differential Revision: http://reviews.llvm.org/D12424

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248619 91177308-0d34-0410-b5e6-96231b3b80d8

20 files changed:
lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.cpp [new file with mode: 0644]
lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.h [new file with mode: 0644]
lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
lib/Target/AMDGPU/AMDGPUTargetMachine.h
lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
lib/Target/AMDGPU/CMakeLists.txt
lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp [new file with mode: 0644]
lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h [new file with mode: 0644]
lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp
lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.h
lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp
lib/Target/AMDGPU/MCTargetDesc/AMDGPUTargetStreamer.cpp
lib/Target/AMDGPU/MCTargetDesc/CMakeLists.txt
lib/Target/AMDGPU/MCTargetDesc/LLVMBuild.txt
lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
lib/Target/AMDGPU/Utils/LLVMBuild.txt
test/CodeGen/AMDGPU/hsa.ll
test/MC/AMDGPU/hsa-text.s [new file with mode: 0644]
test/MC/AMDGPU/hsa.s

diff --git a/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.cpp b/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.cpp
new file mode 100644 (file)
index 0000000..fa54f4a
--- /dev/null
@@ -0,0 +1,35 @@
+//===-- AMDGPUHSATargetObjectFile.cpp - AMDGPU Object Files ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPUHSATargetObjectFile.h"
+#include "Utils/AMDGPUBaseInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/Support/ELF.h"
+
+using namespace llvm;
+
+void AMDGPUHSATargetObjectFile::Initialize(MCContext &Ctx,
+                                           const TargetMachine &TM){
+  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
+  InitializeELF(TM.Options.UseInitArray);
+
+  TextSection = AMDGPU::getHSATextSection(Ctx);
+
+}
+
+MCSection *AMDGPUHSATargetObjectFile::SelectSectionForGlobal(
+                                        const GlobalValue *GV, SectionKind Kind,
+                                        Mangler &Mang,
+                                        const TargetMachine &TM) const {
+  if (Kind.isText() && !GV->hasComdat())
+    return getTextSection();
+
+  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GV, Kind, Mang, TM);
+}
diff --git a/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.h b/lib/Target/AMDGPU/AMDGPUHSATargetObjectFile.h
new file mode 100644 (file)
index 0000000..d13aba5
--- /dev/null
@@ -0,0 +1,35 @@
+//===-- AMDGPUHSATargetObjectFile.h - AMDGPU HSA Object Info ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares the AMDGPU-specific subclass of
+/// TargetLoweringObjectFile use for targeting the HSA-runtime.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUHSATARGETOBJECTFILE_H
+#define LLVM_LIB_TARGET_AMDGPU_AMDGPUHSATARGETOBJECTFILE_H
+
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+class AMDGPUHSATargetObjectFile final : public TargetLoweringObjectFileELF {
+public:
+  void Initialize(MCContext &Ctx, const TargetMachine &TM);
+
+  MCSection *SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
+                                    Mangler &Mang,
+                                    const TargetMachine &TM) const override;
+};
+
+} // end namespace llvm
+
+#endif
index f8fc3bea9ff1344ce0aea3949588bf3c7dc11832..25a395941e9f6def4fd5c9504799e618f0da73d5 100644 (file)
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AMDGPUTargetMachine.h"
+#include "AMDGPUHSATargetObjectFile.h"
 #include "AMDGPU.h"
 #include "AMDGPUTargetTransformInfo.h"
 #include "R600ISelLowering.h"
@@ -43,6 +44,13 @@ extern "C" void LLVMInitializeAMDGPUTarget() {
   RegisterTargetMachine<GCNTargetMachine> Y(TheGCNTarget);
 }
 
+static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
+  if (TT.getOS() == Triple::AMDHSA)
+    return make_unique<AMDGPUHSATargetObjectFile>();
+
+  return make_unique<TargetLoweringObjectFileELF>();
+}
+
 static ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) {
   return new ScheduleDAGMILive(C, make_unique<R600SchedStrategy>());
 }
@@ -72,15 +80,13 @@ AMDGPUTargetMachine::AMDGPUTargetMachine(const Target &T, const Triple &TT,
                                          CodeGenOpt::Level OptLevel)
     : LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options, RM, CM,
                         OptLevel),
-      TLOF(new TargetLoweringObjectFileELF()), Subtarget(TT, CPU, FS, *this),
+      TLOF(createTLOF(getTargetTriple())), Subtarget(TT, CPU, FS, *this),
       IntrinsicInfo() {
   setRequiresStructuredCFG(true);
   initAsmInfo();
 }
 
-AMDGPUTargetMachine::~AMDGPUTargetMachine() {
-  delete TLOF;
-}
+AMDGPUTargetMachine::~AMDGPUTargetMachine() { }
 
 //===----------------------------------------------------------------------===//
 // R600 Target Machine (R600 -> Cayman)
index 14792e347a7a075357aff7e39b7d7ddcd42ea896..236e3f82403063ae8f8e48cb247707f01c781be1 100644 (file)
@@ -32,7 +32,7 @@ class AMDGPUTargetMachine : public LLVMTargetMachine {
 private:
 
 protected:
-  TargetLoweringObjectFile *TLOF;
+  std::unique_ptr<TargetLoweringObjectFile> TLOF;
   AMDGPUSubtarget Subtarget;
   AMDGPUIntrinsicInfo IntrinsicInfo;
 
@@ -52,7 +52,7 @@ public:
   TargetIRAnalysis getTargetIRAnalysis() override;
 
   TargetLoweringObjectFile *getObjFileLowering() const override {
-    return TLOF;
+    return TLOF.get();
   }
 };
 
index de1ea0b7f448de9baf942f9ef798ade903fbf5bd..c74d16d43860f86a9777f961305e14b8113d7295 100644 (file)
@@ -344,6 +344,7 @@ private:
   bool ParseDirectiveHSACodeObjectISA();
   bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
   bool ParseDirectiveAMDKernelCodeT();
+  bool ParseSectionDirectiveHSAText();
 
 public:
   AMDGPUAsmParser(MCSubtargetInfo &STI, MCAsmParser &_Parser,
@@ -903,6 +904,12 @@ bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
   return false;
 }
 
+bool AMDGPUAsmParser::ParseSectionDirectiveHSAText() {
+  getParser().getStreamer().SwitchSection(
+      AMDGPU::getHSATextSection(getContext()));
+  return false;
+}
+
 bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
   StringRef IDVal = DirectiveID.getString();
 
@@ -915,6 +922,9 @@ bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
   if (IDVal == ".amd_kernel_code_t")
     return ParseDirectiveAMDKernelCodeT();
 
+  if (IDVal == ".hsatext" || IDVal == ".text")
+    return ParseSectionDirectiveHSAText();
+
   return true;
 }
 
index dd6db61fb30d51cb33048927a3d3b23345237743..e8780b7cbeca2a87034b6b5a1c3c669a72507803 100644 (file)
@@ -17,6 +17,7 @@ add_llvm_target(AMDGPUCodeGen
   AMDGPUAlwaysInlinePass.cpp
   AMDGPUAsmPrinter.cpp
   AMDGPUFrameLowering.cpp
+  AMDGPUHSATargetObjectFile.cpp
   AMDGPUIntrinsicInfo.cpp
   AMDGPUISelDAGToDAG.cpp
   AMDGPUMCInstLower.cpp
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp
new file mode 100644 (file)
index 0000000..9ff9fe7
--- /dev/null
@@ -0,0 +1,26 @@
+//===-------- AMDGPUELFStreamer.cpp - ELF Object Output -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AMDGPUELFStreamer.h"
+#include "Utils/AMDGPUBaseInfo.h"
+
+using namespace llvm;
+
+void AMDGPUELFStreamer::InitSections(bool NoExecStack) {
+  // Start with the .hsatext section by default.
+  SwitchSection(AMDGPU::getHSATextSection(getContext()));
+}
+
+MCELFStreamer *llvm::createAMDGPUELFStreamer(MCContext &Context,
+                                           MCAsmBackend &MAB,
+                                           raw_pwrite_stream &OS,
+                                           MCCodeEmitter *Emitter,
+                                           bool RelaxAll) {
+  return new AMDGPUELFStreamer(Context, MAB, OS, Emitter);
+}
diff --git a/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h b/lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h
new file mode 100644 (file)
index 0000000..488d7e7
--- /dev/null
@@ -0,0 +1,40 @@
+//===-------- AMDGPUELFStreamer.h - ELF Object Output ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a custom MCELFStreamer which allows us to insert some hooks before
+// emitting data into an actual object file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUELFSTREAMER_H
+#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUELFSTREAMER_H
+
+#include "llvm/MC/MCELFStreamer.h"
+
+namespace llvm {
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCSubtargetInfo;
+
+class AMDGPUELFStreamer : public MCELFStreamer {
+public:
+  AMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB, raw_pwrite_stream &OS,
+                  MCCodeEmitter *Emitter)
+      : MCELFStreamer(Context, MAB, OS, Emitter) { }
+
+  virtual void InitSections(bool NoExecStac) override;
+};
+
+MCELFStreamer *createAMDGPUELFStreamer(MCContext &Context, MCAsmBackend &MAB,
+                                     raw_pwrite_stream &OS,
+                                     MCCodeEmitter *Emitter, bool RelaxAll);
+} // namespace llvm.
+
+#endif
index 028a86dfc7ad519833dbde7b8405d4a5233d02e9..d79ffdf52a74b0d27a5b8938cd22d0af8dc363d1 100644 (file)
@@ -41,3 +41,8 @@ AMDGPUMCAsmInfo::AMDGPUMCAsmInfo(const Triple &TT) : MCAsmInfoELF() {
   //===--- Dwarf Emission Directives -----------------------------------===//
   SupportsDebugInformation = true;
 }
+
+bool AMDGPUMCAsmInfo::shouldOmitSectionDirective(StringRef SectionName) const {
+  return SectionName == ".hsatext" ||
+         MCAsmInfo::shouldOmitSectionDirective(SectionName);
+}
index 119dd425916ee9297e4185d00fb083a10ce02249..a546961705d70a1d84c40cb1aec93ac2274a50f2 100644 (file)
@@ -27,6 +27,7 @@ class Triple;
 class AMDGPUMCAsmInfo : public MCAsmInfoELF {
 public:
   explicit AMDGPUMCAsmInfo(const Triple &TT);
+  bool shouldOmitSectionDirective(StringRef SectionName) const override;
 };
 } // namespace llvm
 #endif
index c709741f37779221a66017b102c2b54705e83126..f70409470276d621361882eed29a74e92b0a2907 100644 (file)
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "AMDGPUMCTargetDesc.h"
+#include "AMDGPUELFStreamer.h"
 #include "AMDGPUMCAsmInfo.h"
 #include "AMDGPUTargetStreamer.h"
 #include "InstPrinter/AMDGPUInstPrinter.h"
@@ -85,6 +86,15 @@ static MCTargetStreamer * createAMDGPUObjectTargetStreamer(
   return new AMDGPUTargetELFStreamer(S);
 }
 
+static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context,
+                                    MCAsmBackend &MAB, raw_pwrite_stream &OS,
+                                    MCCodeEmitter *Emitter, bool RelaxAll) {
+  if (T.getOS() == Triple::AMDHSA)
+    return createAMDGPUELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
+
+  return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
+}
+
 extern "C" void LLVMInitializeAMDGPUTargetMC() {
   for (Target *T : {&TheAMDGPUTarget, &TheGCNTarget}) {
     RegisterMCAsmInfo<AMDGPUMCAsmInfo> X(*T);
@@ -95,6 +105,7 @@ extern "C" void LLVMInitializeAMDGPUTargetMC() {
     TargetRegistry::RegisterMCSubtargetInfo(*T, createAMDGPUMCSubtargetInfo);
     TargetRegistry::RegisterMCInstPrinter(*T, createAMDGPUMCInstPrinter);
     TargetRegistry::RegisterMCAsmBackend(*T, createAMDGPUAsmBackend);
+    TargetRegistry::RegisterELFStreamer(*T, createMCStreamer);
   }
 
   // R600 specific registration
index 09e6cb1f1ffc135cdc2181937373ac7cb174a6e6..135ac7b821bfc15377eee772408306e39b22e7a8 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "AMDGPUTargetStreamer.h"
 #include "SIDefines.h"
+#include "Utils/AMDGPUBaseInfo.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFStreamer.h"
@@ -291,7 +292,10 @@ AMDGPUTargetELFStreamer::EmitAMDKernelCodeT(const amd_kernel_code_t &Header) {
 
   MCStreamer &OS = getStreamer();
   OS.PushSection();
-  OS.SwitchSection(OS.getContext().getObjectFileInfo()->getTextSection());
+  // The MCObjectFileInfo that is available to the assembler is a generic
+  // implementation and not AMDGPUHSATargetObjectFile, so we can't use
+  // MCObjectFileInfo::getTextSection() here for fetching the HSATextSection.
+  OS.SwitchSection(AMDGPU::getHSATextSection(OS.getContext()));
   OS.EmitBytes(StringRef((const char*)&Header, sizeof(Header)));
   OS.PopSection();
 }
index 8306a051ff98c1e534136db92e7955892840a5ab..c823ee7e0080b24cf8d9987ee61559942b37ac4b 100644 (file)
@@ -2,6 +2,7 @@
 add_llvm_library(LLVMAMDGPUDesc
   AMDGPUAsmBackend.cpp
   AMDGPUELFObjectWriter.cpp
+  AMDGPUELFStreamer.cpp
   AMDGPUMCCodeEmitter.cpp
   AMDGPUMCTargetDesc.cpp
   AMDGPUMCAsmInfo.cpp
index 4217bb362975bb33dc8d7d9da67e1df01aa3d8ff..aa9a02198d041e273f71ed0321844b0c286f4070 100644 (file)
@@ -19,5 +19,5 @@
 type = Library
 name = AMDGPUDesc
 parent = AMDGPU
-required_libraries = MC AMDGPUAsmPrinter AMDGPUInfo Support
+required_libraries = MC AMDGPUAsmPrinter AMDGPUInfo AMDGPUUtils Support
 add_to_library_groups = AMDGPU
index b76b4007003f9b0c78b0149a0d6f867ab13faddc..e70f79d5a7be7d33a62599a19f0816c29ed74b39 100644 (file)
@@ -7,6 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 #include "AMDGPUBaseInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/SubtargetFeature.h"
 
 #define GET_SUBTARGETINFO_ENUM
@@ -56,5 +58,13 @@ void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header,
   Header.private_segment_alignment = 4;
 }
 
+MCSection *getHSATextSection(MCContext &Ctx) {
+  return Ctx.getELFSection(".hsatext", ELF::SHT_PROGBITS,
+                           ELF::SHF_ALLOC | ELF::SHF_WRITE |
+                           ELF::SHF_EXECINSTR |
+                           ELF::SHF_AMDGPU_HSA_AGENT |
+                           ELF::SHF_AMDGPU_HSA_CODE);
+}
+
 } // End namespace AMDGPU
 } // End namespace llvm
index f57028cc5bfd20ae7c9d74d0b360f77284edeecb..59a32a6b592d2475deb0bae82c223b265b1034f1 100644 (file)
@@ -15,6 +15,8 @@
 namespace llvm {
 
 class FeatureBitset;
+class MCContext;
+class MCSection;
 
 namespace AMDGPU {
 
@@ -27,6 +29,7 @@ struct IsaVersion {
 IsaVersion getIsaVersion(const FeatureBitset &Features);
 void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header,
                                const FeatureBitset &Features);
+MCSection *getHSATextSection(MCContext &Ctx);
 
 } // end namespace AMDGPU
 } // end namespace llvm
index dec5360e3bc7ff7b40752fe3824b7d6d7f0fa2e4..f8d78165d9e36766338e6aa4d826dbc10c13bf07 100644 (file)
@@ -19,5 +19,5 @@
 type = Library
 name = AMDGPUUtils
 parent = AMDGPU
-required_libraries = Support
+required_libraries = MC Support
 add_to_library_groups = AMDGPU
index 653a6bb1b609813e3d7b844a0c93a117bca5b15b..5c749829381746a0bd61a9b70d5ce88273fa31f2 100644 (file)
@@ -6,6 +6,17 @@
 ; The SHT_NOTE section contains the output from the .hsa_code_object_*
 ; directives.
 
+; ELF: Section {
+; ELF: Name: .hsatext
+; ELF: Type: SHT_PROGBITS (0x1)
+; ELF: Flags [ (0xC00007)
+; ELF: SHF_ALLOC (0x2)
+; ELF: SHF_AMDGPU_HSA_AGENT (0x800000)
+; ELF: SHF_AMDGPU_HSA_CODE (0x400000)
+; ELF: SHF_EXECINSTR (0x4)
+; ELF: SHF_WRITE (0x1)
+; ELF: }
+
 ; ELF: SHT_NOTE
 ; ELF: 0000: 04000000 08000000 01000000 414D4400
 ; ELF: 0010: 01000000 00000000 04000000 1B000000
@@ -17,6 +28,8 @@
 ; HSA-CI: .hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
 ; HSA-VI: .hsa_code_object_isa 8,0,1,"AMD","AMDGPU"
 
+; HSA: .hsatext
+
 ; HSA: {{^}}simple:
 ; HSA: .amd_kernel_code_t
 ; HSA: .end_amd_kernel_code_t
diff --git a/test/MC/AMDGPU/hsa-text.s b/test/MC/AMDGPU/hsa-text.s
new file mode 100644 (file)
index 0000000..1d2f1f1
--- /dev/null
@@ -0,0 +1,34 @@
+// RUN: llvm-mc -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | FileCheck %s --check-prefix=ASM
+// RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | llvm-readobj -s -sd | FileCheck %s --check-prefix=ELF
+
+// For compatibility reasons we treat convert .text sections to .hsatext
+
+// ELF: Section {
+
+// We want to avoid emitting an empty .text section.
+// ELF-NOT: Name: .text
+
+// ELF: Name: .hsatext
+// ELF: Type: SHT_PROGBITS (0x1)
+// ELF: Flags [ (0xC00007)
+// ELF: SHF_ALLOC (0x2)
+// ELF: SHF_AMDGPU_HSA_AGENT (0x800000)
+// ELF: SHF_AMDGPU_HSA_CODE (0x400000)
+// ELF: SHF_EXECINSTR (0x4)
+// ELF: SHF_WRITE (0x1)
+// ELF: Size: 260
+// ELF: }
+
+.hsa_code_object_version 1,0
+// ASM: .hsa_code_object_version 1,0
+
+.hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
+// ASM: .hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
+
+.text
+// ASM: .hsatext
+
+.amd_kernel_code_t
+.end_amd_kernel_code_t
+
+s_endpgm
index 7dfea0fe787e7bb41b2d4c25730da18529ca2964..ae50673492bea1a90f0c969206e78953b251432a 100644 (file)
@@ -1,6 +1,17 @@
 // RUN: llvm-mc -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | FileCheck %s --check-prefix=ASM
 // RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri -show-encoding %s | llvm-readobj -s -sd | FileCheck %s --check-prefix=ELF
 
+// ELF: Section {
+// ELF: Name: .hsatext
+// ELF: Type: SHT_PROGBITS (0x1)
+// ELF: Flags [ (0xC00007)
+// ELF: SHF_ALLOC (0x2)
+// ELF: SHF_AMDGPU_HSA_AGENT (0x800000)
+// ELF: SHF_AMDGPU_HSA_CODE (0x400000)
+// ELF: SHF_EXECINSTR (0x4)
+// ELF: SHF_WRITE (0x1)
+// ELF: }
+
 // ELF: SHT_NOTE
 // ELF: 0000: 04000000 08000000 01000000 414D4400
 // ELF: 0010: 01000000 00000000 04000000 1B000000
@@ -14,7 +25,9 @@
 .hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
 // ASM: .hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
 
-.text
+.hsatext
+// ASM: .hsatext
+
 amd_kernel_code_t_test_all:
 ; Test all amd_kernel_code_t members with non-default values.
 .amd_kernel_code_t