diff options
Diffstat (limited to 'llvm/test/DebugInfo/X86')
22 files changed, 871 insertions, 19 deletions
diff --git a/llvm/test/DebugInfo/X86/base-type-size.ll b/llvm/test/DebugInfo/X86/base-type-size.ll index 3a8dc37..2f0ff2f 100644 --- a/llvm/test/DebugInfo/X86/base-type-size.ll +++ b/llvm/test/DebugInfo/X86/base-type-size.ll @@ -11,7 +11,10 @@ ; CHECK: DW_TAG_base_type ; CHECK-NEXT: DW_AT_name ("DW_ATE_unsigned_1") ; CHECK-NEXT: DW_AT_encoding (DW_ATE_unsigned) +;; TODO: Should this type use bit_size? +; CHECK-NOT: DW_AT_bit_size ; CHECK-NEXT: DW_AT_byte_size (0x01) +; CHECK-NOT: DW_AT_bit_size target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/DebugInfo/X86/cleanup-retained-nodes.ll b/llvm/test/DebugInfo/X86/cleanup-retained-nodes.ll new file mode 100644 index 0000000..86c5ca9 --- /dev/null +++ b/llvm/test/DebugInfo/X86/cleanup-retained-nodes.ll @@ -0,0 +1,45 @@ +; RUN: llvm-as %s -o %t.bc +; RUN: llvm-as %p/../Inputs/cleanup-retained-nodes.ll -o %t.global.bc +; RUN: llvm-link %t.global.bc %t.bc %t.bc -o - | llvm-dis - -o - \ +; RUN: | FileCheck %s --implicit-check-not=DICompositeType + +; During module loading, if a local type appears in retainedNodes +; field of multiple DISubprograms due to ODR-uniquing, +; retainedNodes should be cleaned up, so that only one DISubprogram +; will have this type in its retainedNodes. + +; CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, {{.*}}, identifier: "type_global_in_another_module") +; CHECK: [[EMPTY:![0-9]+]] = !{} +; CHECK: [[BAR1:![0-9]+]] = distinct !DISubprogram(name: "bar", {{.*}}, retainedNodes: [[RN_BAR1:![0-9]+]]) +; CHECK: [[RN_BAR1]] = !{[[T1:![0-9]+]], [[T1]], [[T1]], [[T2:![0-9]+]]} +; CHECK: [[T1]] = distinct !DICompositeType(tag: DW_TAG_class_type, scope: [[BAR1]], {{.*}}, identifier: "local_type") +; CHECK: [[T2]] = distinct !DICompositeType(tag: DW_TAG_class_type, scope: [[LB:![0-9]+]], {{.*}}, identifier: "local_type_in_block") +; CHECK: [[LB]] = !DILexicalBlock(scope: [[BAR1]] +; CHECK: {{![0-9]+}} = distinct !DISubprogram(name: "bar", {{.*}}, retainedNodes: [[EMPTY]]) + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@llvm.used = appending global [1 x ptr] [ptr @bar] + +define internal void @bar(ptr %this) !dbg !10 { + ret void +} + +!llvm.module.flags = !{!0, !1, !2} +!llvm.dbg.cu = !{!8} + +!0 = !{i32 7, !"Dwarf Version", i32 2} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = !{i32 1, !"wchar_size", i32 4} +!3 = !DICompositeType(tag: DW_TAG_class_type, scope: !10, file: !9, line: 212, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "type_global_in_another_module") +!4 = !DICompositeType(tag: DW_TAG_class_type, scope: !5, file: !9, line: 211, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "local_type_in_block") +!5 = !DILexicalBlock(scope: !10) +; All repeating occurences of a uniqued type in retainedNodes must be checked. +!6 = !{!12, !12, !12, !4, !3} +!7 = !{} +!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !9, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!9 = !DIFile(filename: "tmp.cpp", directory: "/tmp/") +!10 = distinct !DISubprogram(name: "bar", scope: !9, file: !9, line: 68, type: !11, scopeLine: 68, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !8, retainedNodes: !6) +!11 = !DISubroutineType(types: !7) +!12 = !DICompositeType(tag: DW_TAG_class_type, scope: !10, file: !9, line: 210, size: 8, flags: DIFlagTypePassByValue, elements: !7, identifier: "local_type") diff --git a/llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll b/llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll new file mode 100644 index 0000000..9117f12 --- /dev/null +++ b/llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll @@ -0,0 +1,39 @@ +; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s + +; CHECK: .file "<stdin>" +; CHECK-NEXT: .section .debug$S,"dr" +; CHECK-NEXT: .p2align 2, 0x0 +; CHECK-NEXT: .long 4 # Debug section magic +; CHECK-NEXT: .long 241 +; CHECK-NEXT: .long .Ltmp1-.Ltmp0 # Subsection size +; CHECK-NEXT: .Ltmp0: +; CHECK-NEXT: .short .Ltmp3-.Ltmp2 # Record length +; CHECK-NEXT: .Ltmp2: +; CHECK-NEXT: .short 4353 # Record kind: S_OBJNAME +; CHECK-NEXT: .long 0 # Signature +; CHECK-NEXT: .byte 0 # Object name +; CHECK-NEXT: .p2align 2, 0x0 +; CHECK-NEXT: .Ltmp3: +; CHECK-NEXT: .short .Ltmp5-.Ltmp4 # Record length +; CHECK-NEXT: .Ltmp4: +; CHECK-NEXT: .short 4412 # Record kind: S_COMPILE3 +; CHECK-NEXT: .long 3 # Flags and language +; CHECK-NEXT: .short 208 # CPUType +; CHECK-NEXT: .short 0 # Frontend version +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short {{[0-9]+}} # Backend version +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .short 0 +; CHECK-NEXT: .asciz "0" # Null-terminated compiler version string +; CHECK-NEXT: .p2align 2, 0x0 +; CHECK-NEXT: .Ltmp5: +; CHECK-NEXT: .Ltmp1: +; CHECK-NEXT: .p2align 2, 0x0 + +!llvm.dbg.cu = !{} +!llvm.module.flags = !{!0} + +!0 = !{i32 2, !"Debug Info Version", i32 3} diff --git a/llvm/test/DebugInfo/X86/derived-in-subrange.ll b/llvm/test/DebugInfo/X86/derived-in-subrange.ll new file mode 100644 index 0000000..fb4c1d4 --- /dev/null +++ b/llvm/test/DebugInfo/X86/derived-in-subrange.ll @@ -0,0 +1,88 @@ +; RUN: llvm-as < %s | llvm-dis | llc -mtriple=x86_64 -O0 -filetype=obj -o - | llvm-dwarfdump -v -debug-info - | FileCheck %s + +; A test to verify the use of a DIDerivedType as a bound of a +; DISubrangeType. + +; CHECK: DW_TAG_array_type +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] {{.*}} +; CHECK: DW_TAG_subrange_type {{.*}} +; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] {{.*}} +; CHECK-NEXT: DW_AT_upper_bound [DW_FORM_ref4] {{.*}} + +; ModuleID = 'vla.ads' +source_filename = "vla.ads" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%vla__array_type_FP = type { ptr, ptr } +%vla__record_type_I = type <{ i32 }> + +@vla_E = dso_local global i16 0, align 2, !dbg !0 + +; Function Attrs: inlinehint +define dso_local void @vla__array_typeIP(%vla__array_type_FP %_init) #0 !dbg !10 { +entry: + %0 = extractvalue %vla__array_type_FP %_init, 1, !dbg !15 + %1 = call ptr @llvm.invariant.start.p0(i64 8, ptr %0), !dbg !15 + ret void, !dbg !15 +} + +; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare ptr @llvm.invariant.start.p0(i64 immarg, ptr nocapture) #1 + +; Function Attrs: inlinehint +define dso_local void @vla__record_typeIP(ptr noalias nocapture nonnull %_init, i32 %l1) #0 !dbg !16 { +entry: + #dbg_declare(ptr %_init, !31, !DIExpression(), !32) + #dbg_value(i32 %l1, !33, !DIExpression(), !34) + %0 = getelementptr inbounds %vla__record_type_I, ptr %_init, i32 0, i32 0, !dbg !32 + store i32 %l1, ptr %0, align 4, !dbg !32, !tbaa !35 + ret void, !dbg !32 +} + +attributes #0 = { inlinehint } +attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } + +!llvm.module.flags = !{!6, !7, !8, !9} +!llvm.dbg.cu = !{!2} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "vla_E", scope: !2, file: !3, line: 16, type: !5, isLocal: false, isDefinition: true, align: 16) +!2 = distinct !DICompileUnit(language: DW_LANG_Ada95, file: !3, producer: "GNAT/LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false) +!3 = !DIFile(filename: "vla.ads", directory: "") +!4 = !{!0} +!5 = !DIBasicType(name: "short_integer", size: 16, encoding: DW_ATE_signed) +!6 = !{i32 8, !"PIC Level", i32 2} +!7 = !{i32 7, !"PIE Level", i32 2} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = distinct !DISubprogram(name: "vla__array_typeIP", scope: !3, file: !3, line: 17, type: !11, scopeLine: 17, spFlags: DISPFlagDefinition, unit: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64, align: 64, dwarfAddressSpace: 0) +!14 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "vla__array_type") +!15 = !DILocation(line: 17, column: 9, scope: !10) +!16 = distinct !DISubprogram(name: "vla__record_typeIP", scope: !3, file: !3, line: 18, type: !17, scopeLine: 18, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !30) +!17 = !DISubroutineType(types: !18) +!18 = !{null, !19, !23} +!19 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !20, size: 64, align: 64, dwarfAddressSpace: 0) +!20 = !DICompositeType(tag: DW_TAG_structure_type, name: "vla__record_type", file: !3, line: 18, size: !DIExpression(DW_OP_push_object_address, DW_OP_deref_size, 4, DW_OP_constu, 32, DW_OP_mul, DW_OP_constu, 32, DW_OP_plus), align: 32, elements: !21, identifier: "vla__record_type") +!21 = !{!22, !26} +!22 = !DIDerivedType(tag: DW_TAG_member, name: "l1", file: !3, line: 18, baseType: !23) +!23 = !DISubrangeType(name: "natural", file: !24, line: 1, size: 32, align: 32, baseType: !25, lowerBound: i64 0, upperBound: i64 2147483647) +!24 = !DIFile(filename: "system.ads", directory: "/home/tromey/AdaCore/gnat-llvm/llvm-interface//lib/gnat-llvm/x86_64-unknown-linux-gnu/rts-native/adainclude/") +!25 = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed) +!26 = !DIDerivedType(tag: DW_TAG_member, name: "a1", file: !3, line: 19, baseType: !27, offset: 32) +!27 = !DICompositeType(tag: DW_TAG_array_type, scope: !20, file: !3, line: 19, baseType: !25, align: 32, elements: !28) +!28 = !{!29} +!29 = !DISubrangeType(baseType: !25, lowerBound: i64 1, upperBound: !22) +!30 = !{} +!31 = !DILocalVariable(name: "_init", arg: 1, scope: !16, file: !3, line: 18, type: !20, flags: DIFlagArtificial) +!32 = !DILocation(line: 18, column: 9, scope: !16) +!33 = !DILocalVariable(name: "l1", arg: 2, scope: !16, file: !3, line: 18, type: !23, flags: DIFlagArtificial) +!34 = !DILocation(line: 18, column: 22, scope: !16) +!35 = !{!36, !36, i64 0, i64 4} +!36 = !{!37, i64 4, !"natural#T5"} +!37 = !{!38, i64 4, !"natural#TN"} +!38 = !{!39, i64 4, !"integerB#TN"} +!39 = !{!"Ada Root"} diff --git a/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll b/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll index 810feca..60010c5 100644 --- a/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll +++ b/llvm/test/DebugInfo/X86/dimodule-external-fortran.ll @@ -29,7 +29,7 @@ ; CHECK: DW_TAG_imported_module ; CHECK-NEXT: DW_AT_decl_file ; CHECK-NEXT: DW_AT_decl_line -; CHECK-NEXT: DW_AT_import ([[DIE_ID]]) +; CHECK-NEXT: DW_AT_import ([[DIE_ID]] "external_module") ; When the debugger sees the module being imported is a declaration, ; it should go to the global scope to find the module's definition. diff --git a/llvm/test/DebugInfo/X86/dwarf-call-target-clobbered.mir b/llvm/test/DebugInfo/X86/dwarf-call-target-clobbered.mir new file mode 100644 index 0000000..ff5c78d --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarf-call-target-clobbered.mir @@ -0,0 +1,96 @@ +# RUN: llc %s --start-after=livedebugvalues -o - --filetype=obj | llvm-dwarfdump - | FileCheck %s + +## Check that DW_AT_call_target_clobbered is used for a location expression +## using a volatile register, otherwise DW_AT_call_target is used. + +## Generated from this C++ with llc -stop-after=livedebugvalues -simplify-mir: +## __attribute__((disable_tail_calls)) void call_mem(void (**f)()) { +## (*f)(); +## (*f)(); +## } + +## Which disassembles to - +## 0000000000000000 <_Z8call_memPPFvvE>: +## 0: 53 pushq %rbx +## 1: 48 89 fb movq %rdi, %rbx +## 4: ff 17 callq *(%rdi) +## 6: ff 13 callq *(%rbx) +## 8: 5b popq %rbx +## 9: c3 retq + +# CHECK: DW_TAG_call_site +# CHECK-NEXT: DW_AT_call_target_clobbered (DW_OP_breg5 RDI+0) +# CHECK: DW_TAG_call_site +# CHECK-NEXT: DW_AT_call_target (DW_OP_breg3 RBX+0) + +--- | + target triple = "x86_64-unknown-linux-gnu" + + define dso_local void @_Z8call_memPPFvvE(ptr noundef readonly captures(none) %f) local_unnamed_addr !dbg !5 { + entry: + %0 = load ptr, ptr %f, align 8, !dbg !13 + call void %0(), !dbg !13 + %1 = load ptr, ptr %f, align 8, !dbg !14 + call void %1(), !dbg !14 + ret void + } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2, !3} + !llvm.ident = !{!4} + + !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 22.0.0git", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "test.cpp", directory: "/") + !2 = !{i32 7, !"Dwarf Version", i32 5} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{!"clang version 22.0.0git"} + !5 = distinct !DISubprogram(name: "call_mem", linkageName: "_Z8call_memPPFvvE", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) + !6 = !DISubroutineType(types: !7) + !7 = !{null, !8} + !8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64) + !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) + !10 = !DISubroutineType(types: !11) + !11 = !{null} + !12 = !{} + !13 = !DILocation(line: 2, scope: !5) + !14 = !DILocation(line: 3, scope: !5) +... +--- +name: _Z8call_memPPFvvE +alignment: 16 +tracksRegLiveness: true +noPhis: true +isSSA: false +noVRegs: true +hasFakeUses: false +debugInstrRef: true +tracksDebugUserValues: true +liveins: + - { reg: '$rdi' } +frameInfo: + stackSize: 8 + offsetAdjustment: -8 + maxAlignment: 1 + adjustsStack: true + hasCalls: true + maxCallFrameSize: 0 + cvBytesOfCalleeSavedRegisters: 8 + isCalleeSavedInfoValid: true +fixedStack: + - { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16, callee-saved-register: '$rbx' } +machineFunctionInfo: + amxProgModel: None +body: | + bb.0.entry: + liveins: $rdi, $rbx + + frame-setup PUSH64r killed $rbx, implicit-def $rsp, implicit $rsp + frame-setup CFI_INSTRUCTION def_cfa_offset 16 + CFI_INSTRUCTION offset $rbx, -16 + $rbx = MOV64rr $rdi + CALL64m $rdi, 1, $noreg, 0, $noreg, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, debug-location !13 :: (load (s64) from %ir.f) + CALL64m killed renamable $rbx, 1, $noreg, 0, $noreg, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, debug-location !14 :: (load (s64) from %ir.f) + $rbx = frame-destroy POP64r implicit-def $rsp, implicit $rsp + frame-destroy CFI_INSTRUCTION def_cfa_offset 8 + RET64 +... diff --git a/llvm/test/DebugInfo/X86/dwarf-call-target-mem-loc.mir b/llvm/test/DebugInfo/X86/dwarf-call-target-mem-loc.mir new file mode 100644 index 0000000..1923baf --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarf-call-target-mem-loc.mir @@ -0,0 +1,92 @@ +# RUN: llc %s --start-after=livedebugvalues -o - --filetype=obj | llvm-dwarfdump - | FileCheck %s + +## Check the memory location of the target address for the indirect call +## (virtual in this case) is described by a DW_AT_call_target_clobbered +## expression. + +# CHECK: DW_TAG_call_site +# CHECK-NEXT: DW_AT_call_target_clobbered (DW_OP_breg0 RAX+8) + +## Generated from this C++ with llc -stop-after=livedebugvalues -simplify-mir: +## struct Base { +## virtual int zz() { return x; } +## [[clang::noinline]] +## virtual int v() { return zz(); } +## int x; +## }; +## struct Child: public Base { +## [[clang::noinline]] +## virtual int v() { return x * 2; } +## int x; +## }; +## +## [[clang::noinline]] +## [[clang::disable_tail_calls]] +## int foo(Base* b) { +## return b->v(); +## } + +--- | + target triple = "x86_64-unknown-linux-gnu" + + define dso_local noundef i32 @_Z3fooP4Base(ptr noundef %b) local_unnamed_addr !dbg !5 { + entry: + %vtable = load ptr, ptr %b, align 8, !dbg !12 + %vfn = getelementptr inbounds nuw i8, ptr %vtable, i64 8, !dbg !12 + %0 = load ptr, ptr %vfn, align 8, !dbg !12 + %call = call noundef i32 %0(ptr noundef nonnull align 8 dereferenceable(12) %b), !dbg !12 + ret i32 %call, !dbg !12 + } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2, !3} + !llvm.ident = !{!4} + + !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 22.0.0git", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "test.cpp", directory: "/") + !2 = !{i32 7, !"Dwarf Version", i32 5} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{!"clang version 22.0.0git"} + !5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooP4Base", scope: !1, file: !1, line: 15, type: !6, scopeLine: 15, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11, keyInstructions: true) + !6 = !DISubroutineType(types: !7) + !7 = !{!8, !9} + !8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) + !9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) + !10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Base", file: !1, line: 1, size: 128, flags: DIFlagFwdDecl | DIFlagNonTrivial, identifier: "_ZTS4Base") + !11 = !{} + !12 = !DILocation(line: 16, scope: !5) +... +--- +name: _Z3fooP4Base +alignment: 16 +tracksRegLiveness: true +noPhis: true +isSSA: false +noVRegs: true +hasFakeUses: false +debugInstrRef: true +tracksDebugUserValues: true +liveins: + - { reg: '$rdi' } +frameInfo: + stackSize: 8 + offsetAdjustment: -8 + maxAlignment: 1 + adjustsStack: true + hasCalls: true + maxCallFrameSize: 0 + isCalleeSavedInfoValid: true +machineFunctionInfo: + amxProgModel: None +body: | + bb.0.entry: + liveins: $rdi + + frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp + frame-setup CFI_INSTRUCTION def_cfa_offset 16 + renamable $rax = MOV64rm renamable $rdi, 1, $noreg, 0, $noreg, debug-location !12 :: (load (s64) from %ir.b) + CALL64m killed renamable $rax, 1, $noreg, 8, $noreg, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !12 :: (load (s64) from %ir.vfn) + $rcx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !12 + frame-destroy CFI_INSTRUCTION def_cfa_offset 8, debug-location !12 + RET64 $eax, debug-location !12 +... diff --git a/llvm/test/DebugInfo/X86/dwarf-callsite-related-attrs-indirect.ll b/llvm/test/DebugInfo/X86/dwarf-callsite-related-attrs-indirect.ll index 6c81e2e..70f91c6 100644 --- a/llvm/test/DebugInfo/X86/dwarf-callsite-related-attrs-indirect.ll +++ b/llvm/test/DebugInfo/X86/dwarf-callsite-related-attrs-indirect.ll @@ -8,7 +8,7 @@ ; RUN: llvm-dwarfdump -statistics %t.o | FileCheck %s -check-prefix=STATS ; VERIFY: No errors. -; STATS: "#call site DIEs": 1, +; STATS: "#call site DIEs": 2, ; OBJ: DW_TAG_subprogram ; OBJ: DW_AT_name ("call_reg") @@ -18,7 +18,7 @@ entry: #dbg_value(ptr %f, !17, !DIExpression(), !18) ; OBJ: DW_TAG_call_site -; OBJ: DW_AT_call_target +; OBJ: DW_AT_call_target{{(_clobbered)?}} (DW_OP_reg[[#]] {{.*}}) ; OBJ: DW_AT_call_return_pc call void (...) %f() #1, !dbg !19 ret void, !dbg !20 @@ -31,6 +31,10 @@ define dso_local void @call_mem(ptr noundef readonly captures(none) %f) local_un entry: #dbg_value(ptr %f, !26, !DIExpression(), !27) %0 = load ptr, ptr %f, align 8, !dbg !28, !tbaa !29 + +; OBJ: DW_TAG_call_site +; OBJ: DW_AT_call_target{{(_clobbered)?}} (DW_OP_breg[[#]] {{.*}}) +; OBJ: DW_AT_call_return_pc call void (...) %0() #1, !dbg !28 ret void, !dbg !33 } diff --git a/llvm/test/DebugInfo/X86/dwarf-gnu-call-target-clobbered.mir b/llvm/test/DebugInfo/X86/dwarf-gnu-call-target-clobbered.mir new file mode 100644 index 0000000..fa642bd --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarf-gnu-call-target-clobbered.mir @@ -0,0 +1,58 @@ +# RUN: llc %s -start-after=livedebugvalues -debugger-tune=gdb --filetype=obj -o - \ +# RUN: | llvm-dwarfdump - | FileCheck %s + +# Generated from IR crash reproducer with `llc -stop-after=livedebugvalues -simplify-mir`. +# Check the GNU equivalent of DW_AT_call_target_clobbered is emitted without +# hitting assertions (DWARF version 4, -debugger-tune=gdb). + +# CHECK: DW_AT_GNU_call_site_target_clobbered + +--- | + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" + target triple = "x86_64-unknown-linux-gnu" + + define void @foo(ptr %p) !dbg !5 { + entry: + %call = tail call ptr %p(i64 0) + ret void + } + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!3, !4} + + !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2, splitDebugInlining: false) + !1 = !DIFile(filename: "test.cpp", directory: ".") + !2 = !{} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{i32 7, !"Dwarf Version", i32 4} + !5 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 479, type: !6, scopeLine: 479, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2, keyInstructions: true) + !6 = distinct !DISubroutineType(types: !7) + !7 = !{null} +... +--- +name: foo +alignment: 16 +tracksRegLiveness: true +noPhis: true +isSSA: false +noVRegs: true +hasFakeUses: false +debugInstrRef: true +tracksDebugUserValues: true +liveins: + - { reg: '$rdi' } +frameInfo: + maxAlignment: 1 + maxCallFrameSize: 0 + hasTailCall: true + isCalleeSavedInfoValid: true +machineFunctionInfo: + amxProgModel: None +body: | + bb.0.entry: + liveins: $rdi + + $rax = MOV64rr $rdi + dead $edi = XOR32rr undef $edi, undef $edi, implicit-def dead $eflags, implicit-def $rdi + TAILJMPr64 killed renamable $rax, csr_64, implicit $rsp, implicit $ssp, implicit $rsp, implicit $ssp, implicit $rdi +... diff --git a/llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll b/llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll index 09591db..4f5d617 100644 --- a/llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll +++ b/llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll @@ -13,9 +13,9 @@ ; CHECK: DW_TAG_subprogram ; CHECK: DW_AT_name ("use_renamed") ; CHECK: DW_TAG_imported_module -; CHECK: DW_AT_import ([[MYMOD]]) +; CHECK: DW_AT_import ([[MYMOD]] "mymod") ; CHECK: DW_TAG_imported_declaration -; CHECK: DW_AT_import ([[VAR1]]) +; CHECK: DW_AT_import ([[VAR1]] "var1") ; CHECK: DW_AT_name ("var4") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/llvm/test/DebugInfo/X86/fission-simple-template-names.ll b/llvm/test/DebugInfo/X86/fission-simple-template-names.ll new file mode 100644 index 0000000..8a6327a --- /dev/null +++ b/llvm/test/DebugInfo/X86/fission-simple-template-names.ll @@ -0,0 +1,79 @@ +; Check that we handle template types for split-dwarf-inlining and simple-template-names correctly. +; RUN: llc -split-dwarf-file=%t.dwo -O2 < %s -dwarf-version=5 -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s +; +; The test case is generated from the following code +; clang -cc1 -emit-llvm -fdebug-info-for-profiling -fsplit-dwarf-inlining -gsimple-template-names=simple -debug-info-kind=constructor -dwarf-version=5 -split-dwarf-file temp.dwo -O2 +; +; void f1(); +; +; template <typename T> +; void f2() { +; f1(); +; } +; +; void f3() { +; f2<int>(); +; } + +; CHECK: .debug_info contents: +; CHECK: DW_TAG_skeleton_unit +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT_linkage_name ("_Z2f2IiEvv") +; CHECK-NEXT: DW_AT_name ("f2") +; CHECK: DW_TAG_template_type_parameter +; CHECK-NEXT: DW_AT_type (0x{{.*}} "int") +; CHECK-NEXT: DW_AT_name ("T") +; CHECK: .debug_info.dwo contents: +; CHECK: DW_TAG_compile_unit +; CHECK: DW_TAG_subprogram +; CHECK-NEXT: DW_AT_linkage_name ("_Z2f2IiEvv") +; CHECK-NEXT: DW_AT_name ("f2") +; CHECK: DW_TAG_template_type_parameter +; CHECK-NEXT: DW_AT_type (0x{{.*}} "int") +; CHECK-NEXT: DW_AT_name ("T") + +; ModuleID = 'fission-simple-template-names.cpp' +source_filename = "fission-simple-template-names.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: mustprogress nounwind +define dso_local void @_Z2f3v() local_unnamed_addr #0 !dbg !10 { +entry: + tail call void @_Z2f1v() #2, !dbg !14 + ret void, !dbg !20 +} + +declare !dbg !21 void @_Z2f1v() local_unnamed_addr #1 + +attributes #0 = { mustprogress nounwind "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } +attributes #2 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4} +!llvm.ident = !{!5} +!llvm.errno.tbaa = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 22.0.0", isOptimized: true, runtimeVersion: 0, splitDebugFilename: "temp.dwo", emissionKind: FullDebug, debugInfoForProfiling: true, nameTableKind: None) +!1 = !DIFile(filename: "<stdin>", directory: "", checksumkind: CSK_MD5, checksum: "f34ede93f4bfefbee3dbe78d1a033274") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{!"clang version 22.0.0"} +!6 = !{!7, !7, i64 0} +!7 = !{!"int", !8, i64 0} +!8 = !{!"omnipotent char", !9, i64 0} +!9 = !{!"Simple C++ TBAA"} +!10 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !11, file: !11, line: 8, type: !12, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0) +!11 = !DIFile(filename: "fission-simple-template-names.cpp", directory: "", checksumkind: CSK_MD5, checksum: "f34ede93f4bfefbee3dbe78d1a033274") +!12 = !DISubroutineType(types: !13) +!13 = !{null} +!14 = !DILocation(line: 5, column: 3, scope: !15, inlinedAt: !19) +!15 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2IiEvv", scope: !11, file: !11, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed | DIFlagNameIsSimplified, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, templateParams: !16) +!16 = !{!17} +!17 = !DITemplateTypeParameter(name: "T", type: !18) +!18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!19 = distinct !DILocation(line: 9, column: 3, scope: !10) +!20 = !DILocation(line: 10, column: 1, scope: !10) +!21 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !11, file: !11, line: 1, type: !12, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized) diff --git a/llvm/test/DebugInfo/X86/fission-template.ll b/llvm/test/DebugInfo/X86/fission-template.ll index b45b650..3e249d6 100644 --- a/llvm/test/DebugInfo/X86/fission-template.ll +++ b/llvm/test/DebugInfo/X86/fission-template.ll @@ -20,9 +20,6 @@ ; CHECK: DW_TAG_subprogram ; CHECK-NEXT: DW_AT_linkage_name ("_Z2f2IiEvv") ; CHECK-NEXT: DW_AT_name ("f2<int>") -; CHECK: DW_TAG_template_type_parameter -; CHECK-NEXT: DW_AT_type (0x{{.*}} "int") -; CHECK-NEXT: DW_AT_name ("T") ; CHECK: .debug_info.dwo contents: ; CHECK: DW_TAG_compile_unit ; CHECK: DW_TAG_subprogram diff --git a/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll b/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll index dbbef2b..594607c 100644 --- a/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll +++ b/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll @@ -281,15 +281,19 @@ lala: !11 = !{!13} !13 = !DILocalVariable(name: "baz", scope: !7, file: !1, line: 6, type: !10) !14 = !DILocation(line: 1, scope: !7) -!20 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!20 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !23) !21 = !DILocalVariable(name: "xyzzy", scope: !20, file: !1, line: 6, type: !10) !22 = !DILocation(line: 1, scope: !20) -!30 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!23 = !{!21} +!30 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !33) !31 = !DILocalVariable(name: "xyzzy", scope: !30, file: !1, line: 6, type: !10) !32 = !DILocation(line: 1, scope: !30) -!40 = distinct !DISubprogram(name: "qux", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!33 = !{!31} +!40 = distinct !DISubprogram(name: "qux", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !46) !41 = !DILocalVariable(name: "socks", scope: !40, file: !1, line: 6, type: !10) !42 = !DILocation(line: 1, scope: !40) -!43 = distinct !DISubprogram(name: "inlined", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11) +!43 = distinct !DISubprogram(name: "inlined", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !47) !44 = !DILocation(line: 0, scope: !43, inlinedAt: !42) !45 = !DILocalVariable(name: "knees", scope: !43, file: !1, line: 6, type: !10) +!46 = !{!41} +!47 = !{!45} diff --git a/llvm/test/DebugInfo/X86/live-debug-values-constprop.mir b/llvm/test/DebugInfo/X86/live-debug-values-constprop.mir index 8a05376..2900f0b 100644 --- a/llvm/test/DebugInfo/X86/live-debug-values-constprop.mir +++ b/llvm/test/DebugInfo/X86/live-debug-values-constprop.mir @@ -82,15 +82,18 @@ !14 = !DISubroutineType(types: !15) !15 = !{!16} !16 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) - !40 = distinct !DISubprogram(name: "bar", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true) + !40 = distinct !DISubprogram(name: "bar", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !43, type: !14, isDefinition: true) !41 = !DILocalVariable(name: "towel", scope: !40, file: !2, line: 1, type: !16) !42 = !DILocation(line: 40, scope: !40) - !80 = distinct !DISubprogram(name: "baz", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true) + !43 = !{!41} + !80 = distinct !DISubprogram(name: "baz", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !83, type: !14, isDefinition: true) !81 = !DILocalVariable(name: "socks", scope: !80, file: !2, line: 1, type: !16) !82 = !DILocation(line: 40, scope: !80) - !120 = distinct !DISubprogram(name: "qux", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !13, type: !14, isDefinition: true) + !83 = !{!81} + !120 = distinct !DISubprogram(name: "qux", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !123, type: !14, isDefinition: true) !121 = !DILocalVariable(name: "shoes", scope: !120, file: !2, line: 1, type: !16) !122 = !DILocation(line: 40, scope: !120) + !123 = !{!121} ... --- diff --git a/llvm/test/DebugInfo/X86/live-debug-values-remove-range.ll b/llvm/test/DebugInfo/X86/live-debug-values-remove-range.ll index e656c62..145b504 100644 --- a/llvm/test/DebugInfo/X86/live-debug-values-remove-range.ll +++ b/llvm/test/DebugInfo/X86/live-debug-values-remove-range.ll @@ -108,6 +108,6 @@ exit: !106 = !DILocation(line: 1, scope: !104) !113 = !{!103} !203 = !DILocalVariable(name: "teacake", scope: !204, file: !2, line: 1, type: !16) -!204 = distinct !DISubprogram(name: "toad", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !113, type: !14, isDefinition: true) +!204 = distinct !DISubprogram(name: "toad", scope: !2, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1, retainedNodes: !213, type: !14, isDefinition: true) !206 = !DILocation(line: 1, scope: !204) !213 = !{!203} diff --git a/llvm/test/DebugInfo/X86/live-debug-vars-intervals.mir b/llvm/test/DebugInfo/X86/live-debug-vars-intervals.mir index 3beaf89..ab57a96 100644 --- a/llvm/test/DebugInfo/X86/live-debug-vars-intervals.mir +++ b/llvm/test/DebugInfo/X86/live-debug-vars-intervals.mir @@ -91,7 +91,7 @@ !10 = !{!11} !11 = !DILocalVariable(name: "x", arg: 1, scope: !6, file: !1, line: 3, type: !9) !12 = !DILocation(line: 3, column: 12, scope: !6) - !13 = distinct !DISubprogram(name: "f2", scope: !1, file: !1, line: 20, type: !7, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) + !13 = distinct !DISubprogram(name: "f2", scope: !1, file: !1, line: 20, type: !7, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !{!14}) !14 = !DILocalVariable(name: "x", arg: 1, scope: !13, file: !1, line: 21, type: !9) !15 = !DILocation(line: 23, column: 12, scope: !13) diff --git a/llvm/test/DebugInfo/X86/llparser-cleanup-retained-nodes.ll b/llvm/test/DebugInfo/X86/llparser-cleanup-retained-nodes.ll new file mode 100644 index 0000000..ee529ad --- /dev/null +++ b/llvm/test/DebugInfo/X86/llparser-cleanup-retained-nodes.ll @@ -0,0 +1,35 @@ +; RUN: llvm-link %s %s -S -o - | FileCheck %s --implicit-check-not=DICompositeType + +; During module loading, if a local type appears in retainedNodes +; field of multiple DISubprograms due to ODR-uniquing, +; LLParser should clean up retainedNodes, so that only one DISubprogram +; will have this type in its retainedNodes. + +; CHECK: [[BAR1:![0-9]+]] = distinct !DISubprogram(name: "bar", {{.*}}, retainedNodes: [[RN_BAR1:![0-9]+]]) +; CHECK: [[EMPTY:![0-9]+]] = !{} +; CHECK: [[RN_BAR1]] = !{[[T1:![0-9]+]]} +; CHECK: [[T1]] = distinct !DICompositeType(tag: DW_TAG_class_type, scope: [[BAR1]], {{.*}}, identifier: "local_type") +; CHECK: {{![0-9]+}} = distinct !DISubprogram(name: "bar", {{.*}}, retainedNodes: [[EMPTY]]) + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@llvm.used = appending global [1 x ptr] [ptr @bar] + +define internal void @bar(ptr %this) !dbg !5 { + ret void +} + +!llvm.module.flags = !{!0, !1, !2} +!llvm.dbg.cu = !{!3} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{i32 7, !"Dwarf Version", i32 2} +!2 = !{i32 2, !"Debug Info Version", i32 3} +!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !4, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!4 = !DIFile(filename: "tmp.cpp", directory: "/tmp/") +!5 = distinct !DISubprogram(name: "bar", scope: !4, file: !4, line: 68, type: !6, scopeLine: 68, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !9) +!6 = !DISubroutineType(types: !8) +!7 = !DICompositeType(tag: DW_TAG_class_type, scope: !5, file: !4, line: 210, size: 8, flags: DIFlagTypePassByValue, elements: !8, identifier: "local_type") +!8 = !{} +!9 = !{!7} diff --git a/llvm/test/DebugInfo/X86/local-type-as-template-parameter.ll b/llvm/test/DebugInfo/X86/local-type-as-template-parameter.ll new file mode 100644 index 0000000..7963efd --- /dev/null +++ b/llvm/test/DebugInfo/X86/local-type-as-template-parameter.ll @@ -0,0 +1,161 @@ +; REQUIRES: system-linux +; RUN: %llc_dwarf -mtriple=x86_64-linux -O0 -filetype=obj < %s \ +; RUN: | llvm-dwarfdump --show-children --name=foo - \ +; RUN: | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s + +; The test ensures that AsmPrinter doesn't crashed compiling this. +; It also demonstrates misplacement for a local type (see https://github.com/llvm/llvm-project/issues/55680 for details). + +; The test compiled from: + +; template<typename T> +; struct A { +; A(T &in) : a(in) {} +; T a; +; }; +; +; __attribute__((always_inline)) +; void foo() { +; struct B { int i; }; +; B objB; +; A<B> objA(objB); +; } +; +; int main() { +; foo(); +; } + +; Concrete out-of-line tree of foo(). +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_abstract_origin {{.*}} "_Z3foov" + +;;; FIXME: 'struct B' should be in the abstract tree below, not here. +; CHECK: DW_TAG_structure_type +; CHECK: DW_AT_name ("B") +; CHECK: DW_TAG_member +; CHECK: NULL +; +; CHECK: DW_TAG_variable +; CHECK: DW_AT_abstract_origin {{.*}} "objB" +; CHECK: DW_TAG_variable +; CHECK: DW_AT_abstract_origin {{.*}} "objA" + +; CHECK: NULL + +; Abstract tree of foo(). +; CHECK: DW_TAG_subprogram +; CHECK: DW_AT_name ("foo") +; CHECK: DW_AT_inline (DW_INL_inlined) + +; CHECK: DW_TAG_variable +; CHECK: DW_AT_name ("objB") +; CHECK: DW_TAG_variable +; CHECK: DW_AT_name ("objA") + +; CHECK: NULL + +; CHECK: DW_TAG_inlined_subroutine +; CHECK: DW_AT_abstract_origin {{.*}} "_Z3foov" +; CHECK: DW_TAG_variable +; CHECK: DW_AT_abstract_origin {{.*}} "objB" +; CHECK: DW_TAG_variable +; CHECK: DW_AT_abstract_origin {{.*}} "objA" +; CHECK: NULL + +%struct.B = type { i32 } +%struct.A = type { %struct.B } + +define dso_local void @_Z3foov() !dbg !7 { +entry: + %objB = alloca %struct.B, align 4 + %objA = alloca %struct.A, align 4 + call void @llvm.dbg.declare(metadata ptr %objB, metadata !30, metadata !DIExpression()), !dbg !31 + call void @llvm.dbg.declare(metadata ptr %objA, metadata !32, metadata !DIExpression()), !dbg !33 + call void @_ZN1AIZ3foovE1BEC2ERS0_(ptr noundef nonnull align 4 dereferenceable(4) %objA, ptr noundef nonnull align 4 dereferenceable(4) %objB), !dbg !33 + ret void, !dbg !34 +} + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +define internal void @_ZN1AIZ3foovE1BEC2ERS0_(ptr noundef nonnull align 4 dereferenceable(4) %this, ptr noundef nonnull align 4 dereferenceable(4) %in) unnamed_addr align 2 !dbg !35 { +entry: + %this.addr = alloca ptr, align 8 + %in.addr = alloca ptr, align 8 + store ptr %this, ptr %this.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %this.addr, metadata !36, metadata !DIExpression()), !dbg !38 + store ptr %in, ptr %in.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %in.addr, metadata !39, metadata !DIExpression()), !dbg !40 + %this1 = load ptr, ptr %this.addr, align 8 + %a = getelementptr inbounds %struct.A, ptr %this1, i32 0, i32 0, !dbg !41 + %0 = load ptr, ptr %in.addr, align 8, !dbg !42 + call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a, ptr align 4 %0, i64 4, i1 false), !dbg !41 + ret void, !dbg !43 +} + +define dso_local noundef i32 @main() !dbg !44 { +entry: + %objB.i = alloca %struct.B, align 4 + %objA.i = alloca %struct.A, align 4 + call void @llvm.dbg.declare(metadata ptr %objB.i, metadata !30, metadata !DIExpression()), !dbg !47 + call void @llvm.dbg.declare(metadata ptr %objA.i, metadata !32, metadata !DIExpression()), !dbg !49 + call void @_ZN1AIZ3foovE1BEC2ERS0_(ptr noundef nonnull align 4 dereferenceable(4) %objA.i, ptr noundef nonnull align 4 dereferenceable(4) %objB.i), !dbg !49 + ret i32 0, !dbg !50 +} + +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!22, !23, !24, !25, !26, !27, !28} +!llvm.ident = !{!29} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 15.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "/", checksumkind: CSK_MD5, checksum: "aec7fd397e86f8655ef7f4bb4233b849") +!2 = !{!3} +!3 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A<B>", file: !1, line: 2, size: 32, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !4, templateParams: !20) +!4 = !{!5, !15} +!5 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !3, file: !1, line: 4, baseType: !6, size: 32) +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B", scope: !7, file: !1, line: 9, size: 32, flags: DIFlagTypePassByValue, elements: !12) +!7 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{} +!11 = !{!6} +!12 = !{!13} +!13 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !6, file: !1, line: 9, baseType: !14, size: 32) +!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!15 = !DISubprogram(name: "A", scope: !3, file: !1, line: 3, type: !16, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit) +!16 = !DISubroutineType(types: !17) +!17 = !{null, !18, !19} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!19 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !6, size: 64) +!20 = !{!21} +!21 = !DITemplateTypeParameter(name: "T", type: !6) +!22 = !{i32 7, !"Dwarf Version", i32 5} +!23 = !{i32 2, !"Debug Info Version", i32 3} +!24 = !{i32 1, !"wchar_size", i32 4} +!25 = !{i32 7, !"PIC Level", i32 2} +!26 = !{i32 7, !"PIE Level", i32 2} +!27 = !{i32 7, !"uwtable", i32 2} +!28 = !{i32 7, !"frame-pointer", i32 2} +!29 = !{!"clang version 15.0.0"} +!30 = !DILocalVariable(name: "objB", scope: !7, file: !1, line: 10, type: !6) +!31 = !DILocation(line: 10, column: 5, scope: !7) +!32 = !DILocalVariable(name: "objA", scope: !7, file: !1, line: 11, type: !3) +!33 = !DILocation(line: 11, column: 8, scope: !7) +!34 = !DILocation(line: 12, column: 1, scope: !7) +!35 = distinct !DISubprogram(name: "A", linkageName: "_ZN1AIZ3foovE1BEC2ERS0_", scope: !3, file: !1, line: 3, type: !16, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, declaration: !15, retainedNodes: !10) +!36 = !DILocalVariable(name: "this", arg: 1, scope: !35, type: !37, flags: DIFlagArtificial | DIFlagObjectPointer) +!37 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, size: 64) +!38 = !DILocation(line: 0, scope: !35) +!39 = !DILocalVariable(name: "in", arg: 2, scope: !35, file: !1, line: 3, type: !19) +!40 = !DILocation(line: 3, column: 8, scope: !35) +!41 = !DILocation(line: 3, column: 14, scope: !35) +!42 = !DILocation(line: 3, column: 16, scope: !35) +!43 = !DILocation(line: 3, column: 21, scope: !35) +!44 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 14, type: !45, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !10) +!45 = !DISubroutineType(types: !46) +!46 = !{!14} +!47 = !DILocation(line: 10, column: 5, scope: !7, inlinedAt: !48) +!48 = distinct !DILocation(line: 15, column: 3, scope: !44) +!49 = !DILocation(line: 11, column: 8, scope: !7, inlinedAt: !48) +!50 = !DILocation(line: 16, column: 1, scope: !44) diff --git a/llvm/test/DebugInfo/X86/no-prologue-end-after-line0-calls.mir b/llvm/test/DebugInfo/X86/no-prologue-end-after-line0-calls.mir new file mode 100644 index 0000000..abd7eb2 --- /dev/null +++ b/llvm/test/DebugInfo/X86/no-prologue-end-after-line0-calls.mir @@ -0,0 +1,132 @@ +# RUN: llc %s -start-after=livedebugvalues -o - | FileCheck %s +# +## Original code, compiled clang -O2 -g -c +## +## void ext(); +## int main(int argc, char **argv) { +## if (argc == 1) +## ext(); +## else +## ext(); +## return 0; +## } +## +## In the code sequence above, the call to ext is given line zero during +## optimisation, because the code is duplicated down all function paths thus +## gets merged. We get something like this as the output: +## +## 0: 50 push %rax +## 1: 31 c0 xor %eax,%eax +## 3: e8 00 00 00 00 call 8 <main+0x8> +## 4: R_X86_64_PLT32 ext-0x4 +## 8: 31 c0 xor %eax,%eax +## a: 59 pop %rcx +## b: c3 ret +## +## And we could choose to set prologue_end on address 8, the clearing of the +## return register, because it's the first "real" instruction that isn't line +## zero. But this then causes debuggers to skip over the call instruction when +## entering the function, which is catastrophic. +## +## Instead: force the call itself to have a source location (the function scope +## line number), and put a prologue_end there. While it's not the original +## source of the call, it's better to have a prologue_end that means we'll stop +## in the prologue than to step over the call. This gives consumers the +## opportunity to recognise "this is a crazy function" and act accordingly. +## +## Check lines: ensure that we set prologue_end. The first entry is the +## start-of-function scope line, the second entry is the prologue_end on the +## call. +# +# +# CHECK: main: +# CHECK-NEXT: .Lfunc_begin0: +# CHECK-NEXT: .file 0 "/tmp/test.c" +# CHECK-NEXT: .loc 0 2 0 +# CHECK-NEXT: .cfi_startproc +# CHECK-NEXT: # %bb.0: +# CHECK-NEXT: pushq %rax +# CHECK-NEXT: .cfi_def_cfa_offset 16 +# CHECK-NEXT: .Ltmp0: +# CHECK-NEXT: .loc 0 0 0 is_stmt 0 +# CHECK-NEXT: xorl %eax, %eax +# CHECK-NEXT: .loc 0 2 0 prologue_end is_stmt 1 +# CHECK-NEXT: callq ext@PLT + +--- | + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" + target triple = "x86_64-unknown-linux-gnu" + + ; Function Attrs: nounwind uwtable + define dso_local noundef i32 @main(i32 noundef %argc, ptr noundef readnone captures(none) %argv) local_unnamed_addr !dbg !10 { + entry: + tail call void (...) @ext(), !dbg !22 + ret i32 0, !dbg !24 + } + + declare !dbg !25 void @ext(...) local_unnamed_addr + + !llvm.dbg.cu = !{!0} + !llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} + !llvm.ident = !{!9} + + !0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) + !1 = !DIFile(filename: "/tmp/test.c", directory: "") + !2 = !{i32 7, !"Dwarf Version", i32 5} + !3 = !{i32 2, !"Debug Info Version", i32 3} + !4 = !{i32 1, !"wchar_size", i32 4} + !5 = !{i32 8, !"PIC Level", i32 2} + !6 = !{i32 7, !"PIE Level", i32 2} + !7 = !{i32 7, !"uwtable", i32 2} + !8 = !{i32 7, !"debug-info-assignment-tracking", i1 true} + !9 = !{!"clang"} + !10 = distinct !DISubprogram(name: "main", scope: !11, file: !11, line: 2, type: !12, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18, keyInstructions: true) + !11 = !DIFile(filename: "/tmp/test.c", directory: "") + !12 = !DISubroutineType(types: !13) + !13 = !{!14, !14, !15} + !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) + !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) + !16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64) + !17 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) + !18 = !{!19, !20} + !19 = !DILocalVariable(name: "argc", arg: 1, scope: !10, file: !11, line: 2, type: !14) + !20 = !DILocalVariable(name: "argv", arg: 2, scope: !10, file: !11, line: 2, type: !15) + !21 = !DILocation(line: 0, scope: !10) + !22 = !DILocation(line: 0, scope: !23) + !23 = distinct !DILexicalBlock(scope: !10, file: !11, line: 3, column: 7) + !24 = !DILocation(line: 7, column: 4, scope: !10, atomGroup: 2, atomRank: 1) + !25 = !DISubprogram(name: "ext", scope: !11, file: !11, line: 1, type: !26, spFlags: DISPFlagOptimized) + !26 = !DISubroutineType(types: !27) + !27 = !{null} +... +--- +name: main +alignment: 16 +tracksRegLiveness: true +noPhis: true +isSSA: false +noVRegs: true +hasFakeUses: false +debugInstrRef: true +tracksDebugUserValues: true +frameInfo: + stackSize: 8 + offsetAdjustment: -8 + maxAlignment: 1 + adjustsStack: true + hasCalls: true + maxCallFrameSize: 0 + isCalleeSavedInfoValid: true +machineFunctionInfo: + amxProgModel: None +body: | + bb.0.entry: + frame-setup PUSH64r undef $rax, implicit-def $rsp, implicit $rsp + frame-setup CFI_INSTRUCTION def_cfa_offset 16 + dead $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, implicit-def $al, debug-location !22 + CALL64pcrel32 target-flags(x86-plt) @ext, csr_64, implicit $rsp, implicit $ssp, implicit killed $al, implicit-def $rsp, implicit-def $ssp, debug-location !22 + $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags, debug-location !24 + $rcx = frame-destroy POP64r implicit-def $rsp, implicit $rsp, debug-location !24 + frame-destroy CFI_INSTRUCTION def_cfa_offset 8, debug-location !24 + RET64 $eax, debug-location !24 +... diff --git a/llvm/test/DebugInfo/X86/salvage-add-node-indirect.ll b/llvm/test/DebugInfo/X86/salvage-add-node-indirect.ll index cae8a47..1a49b03 100644 --- a/llvm/test/DebugInfo/X86/salvage-add-node-indirect.ll +++ b/llvm/test/DebugInfo/X86/salvage-add-node-indirect.ll @@ -30,7 +30,7 @@ define i64 @test_constant(ptr %rdata) { ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2.land.lhs.true.i: ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags - ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[MOV32r0_]], %subreg.sub_32bit + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG killed [[MOV32r0_]], %subreg.sub_32bit ; CHECK-NEXT: $rax = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET 0, $rax entry: @@ -67,7 +67,7 @@ define i64 @test_non_constant(ptr %rdata, i64 %i.194) { ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2.land.lhs.true.i: ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags - ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[MOV32r0_]], %subreg.sub_32bit + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG killed [[MOV32r0_]], %subreg.sub_32bit ; CHECK-NEXT: $rax = COPY [[SUBREG_TO_REG]] ; CHECK-NEXT: RET 0, $rax entry: diff --git a/llvm/test/DebugInfo/X86/uefi-no-codeview-crash.ll b/llvm/test/DebugInfo/X86/uefi-no-codeview-crash.ll new file mode 100644 index 0000000..37ef201 --- /dev/null +++ b/llvm/test/DebugInfo/X86/uefi-no-codeview-crash.ll @@ -0,0 +1,15 @@ +;; This test ensures that the backend does not crash when CodeView is enabled +;; through module flags but llvm.dbg.cu is missing. + +; RUN: llc < %s -mtriple=x86_64-unknown-uefi | FileCheck %s + +define void @foo() { +entry: + ret void +} + +!llvm.module.flags = !{!0} +!0 = !{i32 2, !"CodeView", i32 1} + +; CHECK-LABEL: foo: +; CHECK: retq diff --git a/llvm/test/DebugInfo/X86/x86fixupsetcc-debug-instr-num.mir b/llvm/test/DebugInfo/X86/x86fixupsetcc-debug-instr-num.mir index b7149f01..7488609 100644 --- a/llvm/test/DebugInfo/X86/x86fixupsetcc-debug-instr-num.mir +++ b/llvm/test/DebugInfo/X86/x86fixupsetcc-debug-instr-num.mir @@ -1,4 +1,5 @@ # RUN: llc %s --run-pass=x86-fixup-setcc -o - | FileCheck %s +# RUN: llc %s -passes=x86-fixup-setcc -o - | FileCheck %s ## Check the debug-isntr-number transfers from MOVZX32rr8 to the SETCC ## after the mov is replaced with an INSERT_SUBREG, updating the substitutions |
