diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -375,6 +375,12 @@ bool needsSEHMoves(); + /// Since emitting CFI unwind information is entangled with supporting the + /// exceptions, this returns true for platforms which use CFI unwind + /// information for debugging purpose when + /// `MCAsmInfo::ExceptionsType == ExceptionHandling::None`. + bool needsCFIForDebug() const; + /// Print to the current output stream assembly representations of the /// constants in the constant pool MCP. This is used to print out constants /// which have been "spilled to memory" by the code generator. diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -425,6 +425,10 @@ /// Exception handling format for the target. Defaults to None. ExceptionHandling ExceptionsType = ExceptionHandling::None; + /// True if target uses CFI unwind information for debugging purpose when + /// `ExceptionsType == ExceptionHandling::None`. + bool UsesCFIForDebug = false; + /// Windows exception handling data (.pdata) encoding. Defaults to Invalid. WinEH::EncodingType WinEHEncodingType = WinEH::EncodingType::Invalid; @@ -728,6 +732,8 @@ ExceptionsType = EH; } + bool doesUseCFIForDebug() const { return UsesCFIForDebug; } + /// Returns true if the exception handling method for the platform uses call /// frame information to unwind. bool usesCFIForEH() const { diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -351,6 +351,9 @@ } switch (MAI->getExceptionHandlingType()) { + case ExceptionHandling::None: + // We may want to emit CFI for debug. + LLVM_FALLTHROUGH; case ExceptionHandling::SjLj: case ExceptionHandling::DwarfCFI: case ExceptionHandling::ARM: @@ -372,7 +375,9 @@ EHStreamer *ES = nullptr; switch (MAI->getExceptionHandlingType()) { case ExceptionHandling::None: - break; + if (!needsCFIForDebug()) + break; + LLVM_FALLTHROUGH; case ExceptionHandling::SjLj: case ExceptionHandling::DwarfCFI: ES = new DwarfCFIException(this); @@ -1062,9 +1067,15 @@ return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry(); } +bool AsmPrinter::needsCFIForDebug() const { + return MAI->getExceptionHandlingType() == ExceptionHandling::None && + MAI->doesUseCFIForDebug() && ModuleCFISection == CFISection::Debug; +} + void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) { ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType(); - if (ExceptionHandlingType != ExceptionHandling::DwarfCFI && + if (!needsCFIForDebug() && + ExceptionHandlingType != ExceptionHandling::DwarfCFI && ExceptionHandlingType != ExceptionHandling::ARM) return; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -120,8 +120,13 @@ shouldEmitLSDA = shouldEmitPersonality && LSDAEncoding != dwarf::DW_EH_PE_omit; - shouldEmitCFI = MF->getMMI().getContext().getAsmInfo()->usesCFIForEH() && - (shouldEmitPersonality || shouldEmitMoves); + const MCAsmInfo &MAI = *MF->getMMI().getContext().getAsmInfo(); + if (MAI.getExceptionHandlingType() != ExceptionHandling::None) + shouldEmitCFI = + MAI.usesCFIForEH() && (shouldEmitPersonality || shouldEmitMoves); + else + shouldEmitCFI = Asm->needsCFIForDebug() && shouldEmitMoves; + beginFragment(&*MF->begin(), getExceptionSym); } diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCAsmInfo.cpp @@ -42,6 +42,7 @@ HasNoDeadStrip = true; //===--- Dwarf Emission Directives -----------------------------------===// SupportsDebugInformation = true; + UsesCFIForDebug = true; DwarfRegNumForCFI = true; UseIntegratedAssembler = false; diff --git a/llvm/test/CodeGen/AMDGPU/debug_frame.ll b/llvm/test/CodeGen/AMDGPU/debug_frame.ll --- a/llvm/test/CodeGen/AMDGPU/debug_frame.ll +++ b/llvm/test/CodeGen/AMDGPU/debug_frame.ll @@ -1,14 +1,9 @@ -; RUN: llc -mtriple=amdgcn-amd-amdhsa -filetype=obj -o - < %s | llvm-readelf -S - | FileCheck --check-prefixes=NOEXCEPTIONS_NOFORCE-DEBUG %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa -filetype=obj --force-dwarf-frame-section -o - < %s | llvm-readelf -S - | FileCheck --check-prefixes=NOEXCEPTIONS_FORCE-DEBUG %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa -filetype=obj --exception-model=dwarf -o - < %s | llvm-readelf -S - | FileCheck --check-prefixes=EXCEPTIONS_NOFORCE-DEBUG %s -; RUN: llc -mtriple=amdgcn-amd-amdhsa -filetype=obj --force-dwarf-frame-section --exception-model=dwarf -o - < %s | llvm-readelf -S - | FileCheck --check-prefixes=EXCEPTIONS_FORCE-DEBUG %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa -o - < %s | FileCheck %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa --force-dwarf-frame-section -o - < %s | FileCheck %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa --exception-model=dwarf -o - < %s | FileCheck %s +; RUN: llc -mtriple=amdgcn-amd-amdhsa --force-dwarf-frame-section --exception-model=dwarf -o - < %s | FileCheck %s -; Test that demonstrates we produce a .debug_frame only when exceptions are enabled even if --force-dwarf-frame-section is enabled - -; NOEXCEPTIONS_NOFORCE-DEBUG-NOT: .debug_frame -; NOEXCEPTIONS_FORCE-DEBUG-NOT: .debug_frame -; EXCEPTIONS_NOFORCE-DEBUG: .debug_frame -; EXCEPTIONS_FORCE-DEBUG: .debug_frame +; CHECK: .cfi_sections .debug_frame define void @f() nounwind !dbg !0 { entry: diff --git a/llvm/test/CodeGen/AMDGPU/ptr-arg-dbg-value.ll b/llvm/test/CodeGen/AMDGPU/ptr-arg-dbg-value.ll --- a/llvm/test/CodeGen/AMDGPU/ptr-arg-dbg-value.ll +++ b/llvm/test/CodeGen/AMDGPU/ptr-arg-dbg-value.ll @@ -8,9 +8,23 @@ ; with the fragment expressions. define hidden void @ptr_arg_split_subregs(%struct.A* %arg1) #0 !dbg !9 { ; CHECK-LABEL: ptr_arg_split_subregs: -; CHECK: ; %bb.0: -; CHECK: ;DEBUG_VALUE: ptr_arg_split_subregs:a <- [DW_OP_LLVM_fragment 32 32] [$vgpr1+0] -; CHECK: ;DEBUG_VALUE: ptr_arg_split_subregs:a <- [DW_OP_LLVM_fragment 0 32] [$vgpr0+0] +; CHECK: .Lfunc_begin0: +; CHECK: .loc 1 5 0 ; example.cpp:5:0 +; CHECK-NEXT: .cfi_sections .debug_frame +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: ;DEBUG_VALUE: ptr_arg_split_subregs:a <- [DW_OP_LLVM_fragment 32 32] [$vgpr1+0] +; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) +; CHECK-NEXT: v_mov_b32_e32 v2, 1 +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: ;DEBUG_VALUE: ptr_arg_split_subregs:a <- [DW_OP_LLVM_fragment 0 32] [$vgpr0+0] +; CHECK-NEXT: .loc 1 7 13 prologue_end ; example.cpp:7:13 +; CHECK-NEXT: flat_store_dword v[0:1], v2 offset:396 +; CHECK-NEXT: .loc 1 8 5 ; example.cpp:8:5 +; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) +; CHECK-NEXT: s_setpc_b64 s[30:31] +; CHECK-NEXT: .Ltmp1: +; CHECK: .cfi_endproc call void @llvm.dbg.declare(metadata %struct.A* %arg1, metadata !20, metadata !DIExpression()), !dbg !21 %gep1 = getelementptr inbounds %struct.A, %struct.A* %arg1, i32 0, i32 0, i32 99, !dbg !22 store i32 1, i32* %gep1, align 4, !dbg !23 @@ -27,6 +41,7 @@ ; CHECK-LABEL: ptr_arg_split_reg_mem: ; CHECK: .Lfunc_begin1: ; CHECK-NEXT: .loc 1 10 0 ; example.cpp:10:0 +; CHECK-NEXT: .cfi_startproc ; CHECK-NEXT: ; %bb.0: ; CHECK-NEXT: ;DEBUG_VALUE: ptr_arg_split_reg_mem:b <- [$vgpr31+0] ; CHECK-NEXT: ;DEBUG_VALUE: ptr_arg_split_reg_mem:b <- [$vgpr31+0] @@ -41,6 +56,7 @@ ; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) ; CHECK-NEXT: s_setpc_b64 s[30:31] ; CHECK-NEXT: .Ltmp3: +; CHECK: .cfi_endproc call void @llvm.dbg.declare(metadata %struct.A* %arg2, metadata !26, metadata !DIExpression()), !dbg !27 %gep2 = getelementptr inbounds %struct.A, %struct.A* %arg2, i32 0, i32 0, i32 99, !dbg !28 store i32 1, i32* %gep2, align 4, !dbg !29 @@ -53,6 +69,7 @@ ; CHECK-LABEL: ptr_arg_in_memory: ; CHECK: .Lfunc_begin2: ; CHECK-NEXT: .loc 1 15 0 ; example.cpp:15:0 +; CHECK-NEXT: .cfi_startproc ; CHECK-NEXT: ; %bb.0: ; CHECK-NEXT: s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0) ; CHECK-NEXT: buffer_load_dword v1, off, s[0:3], s32 offset:4 @@ -66,6 +83,7 @@ ; CHECK-NEXT: s_waitcnt vmcnt(0) lgkmcnt(0) ; CHECK-NEXT: s_setpc_b64 s[30:31] ; CHECK-NEXT: .Ltmp5: +; CHECK: .cfi_endproc call void @llvm.dbg.declare(metadata %struct.A* %arg3, metadata !32, metadata !DIExpression()), !dbg !33 %gep3 = getelementptr inbounds %struct.A, %struct.A* %arg3, i32 0, i32 0, i32 99, !dbg !34 store i32 1, i32* %gep3, align 4, !dbg !35 diff --git a/llvm/test/CodeGen/AMDGPU/split-arg-dbg-value.ll b/llvm/test/CodeGen/AMDGPU/split-arg-dbg-value.ll --- a/llvm/test/CodeGen/AMDGPU/split-arg-dbg-value.ll +++ b/llvm/test/CodeGen/AMDGPU/split-arg-dbg-value.ll @@ -6,6 +6,8 @@ ; GCN: .Lfunc_begin0: ; GCN-NEXT: .file 0 ; GCN-NEXT: .loc 0 3 0 ; /tmp/dbg.cl:3:0 +; GCN-NEXT: .cfi_sections .debug_frame +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_v4f32_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 96 32] $vgpr3 ; GCN-NEXT: ;DEBUG_VALUE: split_v4f32_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 64 32] $vgpr2 @@ -16,6 +18,7 @@ ; GCN-NEXT: .loc 0 4 5 prologue_end ; /tmp/dbg.cl:4:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp1: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata <4 x float> %arg, metadata !18, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !19 ret <4 x float> %arg, !dbg !20 } @@ -24,6 +27,7 @@ ; GCN-LABEL: split_v4f32_multi_arg: ; GCN: .Lfunc_begin1: ; GCN-NEXT: .loc 0 7 0 ; /tmp/dbg.cl:7:0 +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_v4f32_multi_arg:arg1 <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 32 32] $vgpr5 ; GCN-NEXT: ;DEBUG_VALUE: split_v4f32_multi_arg:arg1 <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 0 32] $vgpr4 @@ -45,6 +49,7 @@ ; GCN-NEXT: .loc 0 8 5 is_stmt 0 ; /tmp/dbg.cl:8:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp7: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata <4 x float> %arg0, metadata !29, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !31 call void @llvm.dbg.value(metadata <2 x float> %arg1, metadata !30, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !31 %tmp = shufflevector <2 x float> %arg1, <2 x float> undef, <4 x i32> , !dbg !32 @@ -56,6 +61,7 @@ ; GCN-LABEL: split_v4f16_arg: ; GCN: .Lfunc_begin2: ; GCN-NEXT: .loc 0 11 0 is_stmt 1 ; /tmp/dbg.cl:11:0 +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_v4f16_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 32 32] $vgpr1 ; GCN-NEXT: ;DEBUG_VALUE: split_v4f16_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 0 32] $vgpr0 @@ -64,6 +70,7 @@ ; GCN-NEXT: .loc 0 12 5 prologue_end ; /tmp/dbg.cl:12:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp9: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata <4 x half> %arg, metadata !42, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !43 ret <4 x half> %arg, !dbg !44 } @@ -72,6 +79,7 @@ ; GCN-LABEL: split_f64_arg: ; GCN: .Lfunc_begin3: ; GCN-NEXT: .loc 0 15 0 ; /tmp/dbg.cl:15:0 +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_f64_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 32 32] $vgpr1 ; GCN-NEXT: ;DEBUG_VALUE: split_f64_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 0 32] $vgpr0 @@ -80,6 +88,7 @@ ; GCN-NEXT: .loc 0 16 5 prologue_end ; /tmp/dbg.cl:16:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp11: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata double %arg, metadata !50, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !51 ret double %arg, !dbg !52 } @@ -88,6 +97,7 @@ ; GCN-LABEL: split_v2f64_arg: ; GCN: .Lfunc_begin4: ; GCN-NEXT: .loc 0 19 0 ; /tmp/dbg.cl:19:0 +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_v2f64_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 96 32] $vgpr3 ; GCN-NEXT: ;DEBUG_VALUE: split_v2f64_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 64 32] $vgpr2 @@ -98,6 +108,7 @@ ; GCN-NEXT: .loc 0 20 5 prologue_end ; /tmp/dbg.cl:20:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp13: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata <2 x double> %arg, metadata !59, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !60 ret <2 x double> %arg, !dbg !61 } @@ -106,6 +117,7 @@ ; GCN-LABEL: split_i64_arg: ; GCN: .Lfunc_begin5: ; GCN-NEXT: .loc 0 23 0 ; /tmp/dbg.cl:23:0 +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_i64_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 32 32] $vgpr1 ; GCN-NEXT: ;DEBUG_VALUE: split_i64_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 0 32] $vgpr0 @@ -114,6 +126,7 @@ ; GCN-NEXT: .loc 0 24 5 prologue_end ; /tmp/dbg.cl:24:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp15: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata i64 %arg, metadata !67, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !68 ret i64 %arg, !dbg !69 } @@ -122,6 +135,7 @@ ; GCN-LABEL: split_ptr_arg: ; GCN: .Lfunc_begin6: ; GCN-NEXT: .loc 0 27 0 ; /tmp/dbg.cl:27:0 +; GCN-NEXT: .cfi_startproc ; GCN-NEXT: ; %bb.0: ; GCN-NEXT: ;DEBUG_VALUE: split_ptr_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 32 32] $vgpr1 ; GCN-NEXT: ;DEBUG_VALUE: split_ptr_arg:arg <- [DW_OP_constu 1, DW_OP_swap, DW_OP_xderef, DW_OP_LLVM_fragment 0 32] $vgpr0 @@ -130,6 +144,7 @@ ; GCN-NEXT: .loc 0 28 5 prologue_end ; /tmp/dbg.cl:28:5 ; GCN-NEXT: s_setpc_b64 s[30:31] ; GCN-NEXT: .Ltmp17: +; GCN: .cfi_endproc call void @llvm.dbg.value(metadata i8 addrspace(1)* %arg, metadata !76, metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !77 ret i8 addrspace(1)* %arg, !dbg !78 } diff --git a/llvm/test/DebugInfo/AMDGPU/cfi.ll b/llvm/test/DebugInfo/AMDGPU/cfi.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/AMDGPU/cfi.ll @@ -0,0 +1,34 @@ +; RUN: llc -mcpu=gfx900 -mtriple=amdgcn-amd-amdhsa -filetype=obj -o - %s | llvm-dwarfdump -debug-frame - | FileCheck %s + +; CHECK: .debug_frame contents: +; CHECK: 00000000 0000000c ffffffff CIE +; CHECK-NEXT: Format: DWARF32 +; CHECK-NEXT: Version: 4 +; CHECK-NEXT: Augmentation: "" +; CHECK-NEXT: Address size: 8 +; CHECK-NEXT: Segment desc size: 0 +; CHECK-NEXT: Code alignment factor: 4 +; CHECK-NEXT: Data alignment factor: 4 +; CHECK-NEXT: Return address column: 16 +; CHECK-EMPTY: +; CHECK: DW_CFA_nop: +; CHECK-EMPTY: +; CHECK: 00000010 {{[0-9]+}} 00000000 FDE cie=00000000 pc=00000000...{{[0-9]+}} +; CHECK-NEXT: Format: DWARF32 +; CHECK-EMPTY: +; CHECK: .eh_frame contents: +; CHECK-NOT: CIE + +define void @func() #0 { + ret void +} + +attributes #0 = { nounwind } + +!llvm.module.flags = !{!0, !1} +!llvm.dbg.cu = !{!2} + +!0 = !{i32 7, !"Dwarf Version", i32 5} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug) +!3 = !DIFile(filename: "file", directory: "dir") diff --git a/llvm/test/MC/ELF/AMDGPU/cfi.s b/llvm/test/MC/ELF/AMDGPU/cfi.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ELF/AMDGPU/cfi.s @@ -0,0 +1,29 @@ +# RUN: llvm-mc -filetype=asm -mcpu=gfx900 -triple amdgcn-amd-amdhsa %s -o - | FileCheck --check-prefix=ASM %s +# RUN: llvm-mc -filetype=obj -mcpu=gfx900 -triple amdgcn-amd-amdhsa %s -o %t +# RUN: llvm-readelf -S -r -x .debug_frame %t | FileCheck --check-prefix=READELF %s + +f: + .cfi_sections .debug_frame + .cfi_startproc + s_nop 0 + .cfi_endproc + +# ASM: f: +# ASM-NEXT: .cfi_sections .debug_frame +# ASM-NEXT: .cfi_startproc +# ASM-NEXT: s_nop 0 +# ASM-NEXT: .cfi_endproc + +# READELF: Section Headers: +# READELF: Name Type Address Off Size ES Flg Lk Inf Al +# READELF: .debug_frame PROGBITS 0000000000000000 000048 000028 00 0 0 8 + +# READELF: Relocation section '.rela.debug_frame' at offset 0xd0 contains 2 entries: +# READELF-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend +# READELF-NEXT: 0000000000000014 0000000300000006 R_AMDGPU_ABS32 0000000000000000 .debug_frame + 0 +# READELF-NEXT: 0000000000000018 0000000100000003 R_AMDGPU_ABS64 0000000000000000 .text + 0 + +# READELF: Hex dump of section '.debug_frame': +# READELF-NEXT: 0x00000000 0c000000 ffffffff 04000800 04041000 ................ +# READELF-NEXT: 0x00000010 14000000 00000000 00000000 00000000 ................ +# READELF-NEXT: 0x00000020 04000000 00000000 ........ diff --git a/llvm/test/MC/ELF/AMDGPU/lit.local.cfg b/llvm/test/MC/ELF/AMDGPU/lit.local.cfg new file mode 100644 --- /dev/null +++ b/llvm/test/MC/ELF/AMDGPU/lit.local.cfg @@ -0,0 +1,3 @@ +# We have to reset config.unsupported here because the parent directory is +# predicated on 'X86'. +config.unsupported = 'AMDGPU' not in config.root.targets