aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/DebugInfo/X86
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/DebugInfo/X86')
-rw-r--r--llvm/test/DebugInfo/X86/base-type-size.ll3
-rw-r--r--llvm/test/DebugInfo/X86/cleanup-retained-nodes.ll45
-rw-r--r--llvm/test/DebugInfo/X86/codeview-empty-dbg-cu-crash.ll39
-rw-r--r--llvm/test/DebugInfo/X86/derived-in-subrange.ll88
-rw-r--r--llvm/test/DebugInfo/X86/dimodule-external-fortran.ll2
-rw-r--r--llvm/test/DebugInfo/X86/dwarf-call-target-clobbered.mir96
-rw-r--r--llvm/test/DebugInfo/X86/dwarf-call-target-mem-loc.mir92
-rw-r--r--llvm/test/DebugInfo/X86/dwarf-callsite-related-attrs-indirect.ll8
-rw-r--r--llvm/test/DebugInfo/X86/dwarf-gnu-call-target-clobbered.mir58
-rw-r--r--llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll4
-rw-r--r--llvm/test/DebugInfo/X86/fission-simple-template-names.ll79
-rw-r--r--llvm/test/DebugInfo/X86/fission-template.ll3
-rw-r--r--llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll12
-rw-r--r--llvm/test/DebugInfo/X86/live-debug-values-constprop.mir9
-rw-r--r--llvm/test/DebugInfo/X86/live-debug-values-remove-range.ll2
-rw-r--r--llvm/test/DebugInfo/X86/live-debug-vars-intervals.mir2
-rw-r--r--llvm/test/DebugInfo/X86/llparser-cleanup-retained-nodes.ll35
-rw-r--r--llvm/test/DebugInfo/X86/local-type-as-template-parameter.ll161
-rw-r--r--llvm/test/DebugInfo/X86/no-prologue-end-after-line0-calls.mir132
-rw-r--r--llvm/test/DebugInfo/X86/salvage-add-node-indirect.ll4
-rw-r--r--llvm/test/DebugInfo/X86/uefi-no-codeview-crash.ll15
-rw-r--r--llvm/test/DebugInfo/X86/x86fixupsetcc-debug-instr-num.mir1
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