Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1353,11 +1353,9 @@ // We must emit temporary symbol for the end of this basic block, if either // we have BBLabels enabled or if this basic blocks marks the end of a - // section (except the section containing the entry basic block as the end - // symbol for that section is CurrentFnEnd). + // section. if (MF->hasBBLabels() || - (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection() && - !MBB.sameSection(&MF->front()))) + (MAI->hasDotTypeDotSizeDirective() && MBB.isEndSection())) OutStreamer->emitLabel(MBB.getEndSymbol()); if (MBB.isEndSection()) { Index: llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -290,16 +290,10 @@ // doing that violates the ranges that are calculated in the history map. // However, we currently do not emit debug values for constant arguments // directly at the start of the function, so this code is still useful. - // FIXME: If the first mention of an argument is in a unique section basic - // block, we cannot always assign the CurrentFnBeginLabel as it lies in a - // different section. Temporarily, we disable generating loc list - // information or DW_AT_const_value when the block is in a different - // section. const DILocalVariable *DIVar = Entries.front().getInstr()->getDebugVariable(); if (DIVar->isParameter() && - getDISubprogram(DIVar->getScope())->describes(&MF->getFunction()) && - Entries.front().getInstr()->getParent()->sameSection(&MF->front())) { + getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) { if (!IsDescribedByReg(Entries.front().getInstr())) LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin(); if (Entries.front().getInstr()->getDebugExpression()->isFragment()) { @@ -385,22 +379,25 @@ DenseMap::iterator I = LabelsAfterInsn.find(CurMI); - CurMI = nullptr; // No label needed. - if (I == LabelsAfterInsn.end()) - return; - - // Label already assigned. - if (I->second) + if (I == LabelsAfterInsn.end() || I->second) { + CurMI = nullptr; return; + } - // We need a label after this instruction. - if (!PrevLabel) { + // We need a label after this instruction. With basic block sections, just + // use the end symbol of the section if this is the last instruction of the + // section. This reduces the need for an additional label and also helps + // merging ranges. + if (CurMI->getParent()->isEndSection() && CurMI->getNextNode() == nullptr) { + PrevLabel = CurMI->getParent()->getEndSymbol(); + } else if (!PrevLabel) { PrevLabel = MMI->getContext().createTempSymbol(); Asm->OutStreamer->emitLabel(PrevLabel); } I->second = PrevLabel; + CurMI = nullptr; } void DebugHandlerBase::endFunction(const MachineFunction *MF) { Index: llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1739,7 +1739,31 @@ SmallVector Values; for (auto &R : OpenRanges) Values.push_back(R.second); - DebugLoc.emplace_back(StartLabel, EndLabel, Values); + + // With Basic block sections, it is posssible that the StartLabel and the + // Instr are not in the same section. This happens when the StartLabel is + // the function begin label and the dbg value appears in a basic block + // that is not the entry. In this case, the range needs to be split to + // span each individual section in the range from StartLabel to EndLabel. + if (Asm->MF->hasBBSections() && StartLabel == Asm->getFunctionBegin() && + !Instr->getParent()->sameSection(&Asm->MF->front())) { + const MCSymbol *BeginSectionLabel = StartLabel; + + for (const MachineBasicBlock &MBB : *Asm->MF) { + if (MBB.isBeginSection() && &MBB != &Asm->MF->front()) + BeginSectionLabel = MBB.getSymbol(); + + if (MBB.sameSection(Instr->getParent())) { + DebugLoc.emplace_back(BeginSectionLabel, EndLabel, Values); + break; + } + if (MBB.isEndSection()) + DebugLoc.emplace_back(BeginSectionLabel, MBB.getEndSymbol(), + Values); + } + } else { + DebugLoc.emplace_back(StartLabel, EndLabel, Values); + } // Attempt to coalesce the ranges of two otherwise identical // DebugLocEntries. @@ -1756,8 +1780,46 @@ DebugLoc.pop_back(); } - return DebugLoc.size() == 1 && isSafeForSingleLocation && - validThroughout(LScopes, StartDebugMI, EndMI, getInstOrdering()); + if (!isSafeForSingleLocation || + !validThroughout(LScopes, StartDebugMI, EndMI, getInstOrdering())) + return false; + + if (DebugLoc.size() == 1) + return true; + + if (!Asm->MF->hasBBSections()) + return false; + + // Check here to see if loclist can be merged into a single range. If not, + // we must keep the split loclists per section. This does exactly what + // MergeRanges does without sections. We don't actually merge the ranges + // as the split ranges must be kept intact if this cannot be collapsed + // into a single range. + const MachineBasicBlock *RangeMBB = nullptr; + if (DebugLoc[0].getBeginSym() == Asm->getFunctionBegin()) + RangeMBB = &Asm->MF->front(); + else + RangeMBB = Entries.begin()->getInstr()->getParent(); + auto *CurEntry = DebugLoc.begin(); + auto *NextEntry = std::next(CurEntry); + while (NextEntry != DebugLoc.end()) { + // Get the last machine basic block of this section. + while (!RangeMBB->isEndSection()) + RangeMBB = RangeMBB->getNextNode(); + if (!RangeMBB->getNextNode()) + return false; + // CurEntry should end the current section and NextEntry should start + // the next section and the Values must match for these two ranges to be + // merged. + if (CurEntry->getEndSym() != RangeMBB->getEndSymbol() || + NextEntry->getBeginSym() != RangeMBB->getNextNode()->getSymbol() || + CurEntry->getValues() != NextEntry->getValues()) + return false; + RangeMBB = RangeMBB->getNextNode(); + CurEntry = NextEntry; + NextEntry = std::next(CurEntry); + } + return true; } DbgEntity *DwarfDebug::createConcreteEntity(DwarfCompileUnit &TheCU, Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loc-const-value-1.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loc-const-value-1.ll @@ -0,0 +1,82 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_const_value (7) +; CHECK-NEXT: DW_AT_name ("i") + +; Source to generate the IR below: +; void f1(); +; extern bool b; +; extern int x; +; void test() { +; // i is a const throughout the whole scope and should +; // use DW_AT_const_value +; int i = 7; +; f1(); +; if (b) +; f1(); +; } +; +; $ clang++ -S -emit-llvm -g -O2 simple.cc +; + +@b = external dso_local local_unnamed_addr global i8, align 1 + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 7, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !14 + %0 = load i8, i8* @b, align 1, !dbg !15, !tbaa !17, !range !21 + %tobool.not = icmp eq i8 %0, 0, !dbg !15 + br i1 %tobool.not, label %if.end, label %if.then, !dbg !22 + +if.then: ; preds = %entry + tail call void @_Z2f1v(), !dbg !23 + br label %if.end, !dbg !23 + +if.end: ; preds = %if.then, %entry + ret void, !dbg !24 +} + +declare !dbg !25 dso_local void @_Z2f1v() local_unnamed_addr + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "simple.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 14, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocation(line: 15, column: 5, scope: !7) +!15 = !DILocation(line: 16, column: 9, scope: !16) +!16 = distinct !DILexicalBlock(scope: !7, file: !1, line: 16, column: 9) +!17 = !{!18, !18, i64 0} +!18 = !{!"bool", !19, i64 0} +!19 = !{!"omnipotent char", !20, i64 0} +!20 = !{!"Simple C++ TBAA"} +!21 = !{i8 0, i8 2} +!22 = !DILocation(line: 16, column: 9, scope: !7) +!23 = !DILocation(line: 17, column: 7, scope: !16) +!24 = !DILocation(line: 18, column: 1, scope: !7) +!25 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loc-const-value-2.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loc-const-value-2.ll @@ -0,0 +1,60 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_const_value (7) +; CHECK-NEXT: DW_AT_name ("i") + + +; void f1(); +; void test() { +; // constant value with a single location description +; // Shouldn't change with BB-sections +; int i = 7; +; f1(); +; } +; $ clang++ -S -emit-llvm -g -O2 const_value_2.cc + + + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 7, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !14 + ret void, !dbg !15 +} + +declare !dbg !16 dso_local void @_Z2f1v() local_unnamed_addr + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "const_value_2.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 8, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocation(line: 9, column: 3, scope: !7) +!15 = !DILocation(line: 10, column: 1, scope: !7) +!16 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loc-split-range.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loc-split-range.ll @@ -0,0 +1,90 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s --check-prefix=CHECK --check-prefix=SECTIONS +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s --check-prefix=CHECK --check-prefix=SECTIONS + +; CHECK: DW_AT_location +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_constu 0x9d, DW_OP_stack_value +; SECTIONS: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_constu 0x9d, DW_OP_stack_value +; SECTIONS-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_constu 0x9d, DW_OP_stack_value +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_constu 0x9f, DW_OP_stack_value +; CHECK-NEXT: DW_AT_name ("buflen") + +; This IR is generated by copying basic-block-sections-debug-loc.ll and +; manually adding one more dbg value in block 2 and modifying the value. +; With just one dbg value a DW_AT_const_val would be emitted, so we add +; one more dbg value with a different value to split the ranges. +; The extra dbg value is added to split the range and to check if the +; ranges are split correctly with sections. With basic block sections, +; the dbg value 157 (0x9d) gets split into one more range. + +define dso_local void @_ZL4ncatPcjz(i8* %0, i32 %1, ...) unnamed_addr align 32 !dbg !22 { +.critedge3: + call void @llvm.dbg.value(metadata i32 157, metadata !27, metadata !DIExpression()), !dbg !46 + call void @llvm.va_start(i8* nonnull undef), !dbg !47 + br label %2 + +2: ; preds = %2, %.critedge3 + call void @llvm.dbg.value(metadata i32 159, metadata !27, metadata !DIExpression()), !dbg !46 + br label %2 +} + +declare void @llvm.va_start(i8*) + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!20, !21} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2) +!1 = !DIFile(filename: "bug.cpp", directory: "/proc/self/cwd") +!2 = !{!3, !6, !9, !10, !11, !13, !16, !17, !15} +!3 = !DIDerivedType(tag: DW_TAG_typedef, name: "int32_t", file: !4, line: 38, baseType: !5) +!4 = !DIFile(filename: "stdint.h", directory: "/proc/self/cwd") +!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8) +!8 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_unsigned_char) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64) +!10 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint32_t", file: !4, line: 51, baseType: !12) +!12 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!13 = !DIDerivedType(tag: DW_TAG_typedef, name: "UChar", file: !14, line: 372, baseType: !15) +!14 = !DIFile(filename: "umachine.h", directory: "/proc/self/cwd") +!15 = !DIBasicType(name: "char16_t", size: 16, encoding: DW_ATE_UTF) +!16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !3, size: 64) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "UBool", file: !14, line: 261, baseType: !18) +!18 = !DIDerivedType(tag: DW_TAG_typedef, name: "int8_t", file: !4, line: 36, baseType: !19) +!19 = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char) +!20 = !{i32 2, !"Debug Info Version", i32 3} +!21 = !{i32 7, !"PIC Level", i32 2} +!22 = distinct !DISubprogram(name: "ncat", linkageName: "_ZL4ncatPcjz", scope: !1, file: !1, line: 37, type: !23, scopeLine: 37, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !25) +!23 = !DISubroutineType(types: !24) +!24 = !{!3, !9, !11, null} +!25 = !{!26, !27, !28, !41, !42, !43, !44} +!26 = !DILocalVariable(name: "buffer", arg: 1, scope: !22, file: !1, line: 37, type: !9) +!27 = !DILocalVariable(name: "buflen", arg: 2, scope: !22, file: !1, line: 37, type: !11) +!28 = !DILocalVariable(name: "args", scope: !22, file: !1, line: 38, type: !29) +!29 = !DIDerivedType(tag: DW_TAG_typedef, name: "va_list", file: !30, line: 14, baseType: !31) +!30 = !DIFile(filename: "stdarg.h", directory: "/proc/self/cwd") +!31 = !DIDerivedType(tag: DW_TAG_typedef, name: "__builtin_va_list", file: !1, line: 38, baseType: !32) +!32 = !DICompositeType(tag: DW_TAG_array_type, baseType: !33, size: 192, elements: !39) +!33 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "__va_list_tag", file: !1, line: 38, size: 192, flags: DIFlagTypePassByValue, elements: !34, identifier: "_ZTS13__va_list_tag") +!34 = !{!35, !36, !37, !38} +!35 = !DIDerivedType(tag: DW_TAG_member, name: "gp_offset", scope: !33, file: !1, line: 38, baseType: !12, size: 32) +!36 = !DIDerivedType(tag: DW_TAG_member, name: "fp_offset", scope: !33, file: !1, line: 38, baseType: !12, size: 32, offset: 32) +!37 = !DIDerivedType(tag: DW_TAG_member, name: "overflow_arg_area", scope: !33, file: !1, line: 38, baseType: !10, size: 64, offset: 64) +!38 = !DIDerivedType(tag: DW_TAG_member, name: "reg_save_area", scope: !33, file: !1, line: 38, baseType: !10, size: 64, offset: 128) +!39 = !{!40} +!40 = !DISubrange(count: 1) +!41 = !DILocalVariable(name: "str", scope: !22, file: !1, line: 39, type: !9) +!42 = !DILocalVariable(name: "p", scope: !22, file: !1, line: 40, type: !9) +!43 = !DILocalVariable(name: "e", scope: !22, file: !1, line: 41, type: !6) +!44 = !DILocalVariable(name: "c", scope: !45, file: !1, line: 49, type: !8) +!45 = distinct !DILexicalBlock(scope: !22, file: !1, line: 48, column: 45) +!46 = !DILocation(line: 0, scope: !22) +!47 = !DILocation(line: 47, column: 3, scope: !22) Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loc.ll =================================================================== --- llvm/test/DebugInfo/X86/basic-block-sections-debug-loc.ll +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loc.ll @@ -1,19 +1,21 @@ ;; The dbg value for buflen in the non-entry basic block spans the entire ;; function and is emitted as DW_AT_const_value. Even with basic block ;; sections, this can be done as the entire function is represented as ranges. -;; FIXME: Basic block sections should have the same behavior as the default. ; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t ; RUN: llvm-dwarfdump %t | FileCheck %s ; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t -; RUN: llvm-dwarfdump %t | FileCheck --check-prefix=MISSING %s +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s ; CHECK: DW_AT_const_value (157) ; CHECK-NEXT: DW_AT_name ("buflen") -; MISSING-NOT: DW_AT_const_value (157) -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-grtev4-linux-gnu" +;; We do not have the source to reproduce this as this was IR was obtained +;; using a reducer from a failing compile. define dso_local void @_ZL4ncatPcjz(i8* %0, i32 %1, ...) unnamed_addr align 32 !dbg !22 { .critedge3: @@ -25,14 +27,9 @@ br label %2 } -; Function Attrs: nounwind -declare void @llvm.va_start(i8*) #1 - -; Function Attrs: nounwind readnone speculatable willreturn -declare void @llvm.dbg.value(metadata, metadata, metadata) #2 +declare void @llvm.va_start(i8*) -attributes #1 = { nounwind } -attributes #2 = { nounwind readnone speculatable willreturn } +declare void @llvm.dbg.value(metadata, metadata, metadata) !llvm.dbg.cu = !{!0} !llvm.module.flags = !{!20, !21} Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-1.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-1.ll @@ -0,0 +1,96 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +9, DW_OP_stack_value +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; CHECK-NEXT: DW_AT_name ("i") + +; Source to generate the IR below: +; void f1(); +; int f2(int); +; extern bool b; +; extern int x; +; void test() { +; // Value is either 7 or 9 so DW_AT_const_value cannot be used and 3 loc +; // list entries have to be generated. +; int i = 7; +; f1(); +; if (b) { +; i += 2; +; f2(i); +; } +; } +; $ clang++ -S -emit-llvm -g -O2 loclist_1.cc +; + +@b = external dso_local local_unnamed_addr global i8, align 1 + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 7, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !14 + %0 = load i8, i8* @b, align 1, !dbg !15, !tbaa !17, !range !21 + %tobool.not = icmp eq i8 %0, 0, !dbg !15 + br i1 %tobool.not, label %if.end, label %if.then, !dbg !22 + +if.then: ; preds = %entry + call void @llvm.dbg.value(metadata i32 9, metadata !11, metadata !DIExpression()), !dbg !13 + %call = tail call i32 @_Z2f2i(i32 9), !dbg !23 + br label %if.end, !dbg !25 + +if.end: ; preds = %if.then, %entry + ret void, !dbg !26 +} + +declare !dbg !27 dso_local void @_Z2f1v() local_unnamed_addr + +declare !dbg !28 dso_local i32 @_Z2f2i(i32) local_unnamed_addr + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "loclist_1.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 14, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocation(line: 15, column: 5, scope: !7) +!15 = !DILocation(line: 16, column: 9, scope: !16) +!16 = distinct !DILexicalBlock(scope: !7, file: !1, line: 16, column: 9) +!17 = !{!18, !18, i64 0} +!18 = !{!"bool", !19, i64 0} +!19 = !{!"omnipotent char", !20, i64 0} +!20 = !{!"Simple C++ TBAA"} +!21 = !{i8 0, i8 2} +!22 = !DILocation(line: 16, column: 9, scope: !7) +!23 = !DILocation(line: 18, column: 7, scope: !24) +!24 = distinct !DILexicalBlock(scope: !16, file: !1, line: 16, column: 12) +!25 = !DILocation(line: 19, column: 5, scope: !24) +!26 = !DILocation(line: 20, column: 1, scope: !7) +!27 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!28 = !DISubprogram(name: "f2", linkageName: "_Z2f2i", scope: !1, file: !1, line: 2, type: !29, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!29 = !DISubroutineType(types: !30) +!30 = !{!12, !12} Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-2.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-2.ll @@ -0,0 +1,100 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s --check-prefix=CHECK --check-prefix=SECTIONS +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s --check-prefix=CHECK --check-prefix=SECTIONS + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; SECTIONS-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +9, DW_OP_stack_value +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; CHECK-NEXT: DW_AT_name ("i") + +; Source to generate the IR below: +; void f1(); +; int f2(int); +; extern bool b; +; extern int x; +; void test() { +; // i's value is 7 for the first call in in the if block. With basic +; // block sections, this would split the range across sections and would +; // result in an extra entry than without sections. +; int i = 7; +; f1(); +; if (b) { +; f2(i); +; i += 2; +; f2(i); +; } +; } +; $ clang++ -S -emit-llvm -g -O2 loclist_2.cc +; + +@b = external dso_local local_unnamed_addr global i8, align 1 + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 7, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !14 + %0 = load i8, i8* @b, align 1, !dbg !15, !tbaa !17, !range !21 + %tobool.not = icmp eq i8 %0, 0, !dbg !15 + br i1 %tobool.not, label %if.end, label %if.then, !dbg !22 + +if.then: ; preds = %entry + %call = tail call i32 @_Z2f2i(i32 7), !dbg !23 + call void @llvm.dbg.value(metadata i32 9, metadata !11, metadata !DIExpression()), !dbg !13 + %call1 = tail call i32 @_Z2f2i(i32 9), !dbg !25 + br label %if.end, !dbg !26 + +if.end: ; preds = %if.then, %entry + ret void, !dbg !27 +} + +declare !dbg !28 dso_local void @_Z2f1v() local_unnamed_addr + +declare !dbg !29 dso_local i32 @_Z2f2i(i32) local_unnamed_addr + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "loclist_2.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 14, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocation(line: 15, column: 5, scope: !7) +!15 = !DILocation(line: 16, column: 9, scope: !16) +!16 = distinct !DILexicalBlock(scope: !7, file: !1, line: 16, column: 9) +!17 = !{!18, !18, i64 0} +!18 = !{!"bool", !19, i64 0} +!19 = !{!"omnipotent char", !20, i64 0} +!20 = !{!"Simple C++ TBAA"} +!21 = !{i8 0, i8 2} +!22 = !DILocation(line: 16, column: 9, scope: !7) +!23 = !DILocation(line: 17, column: 7, scope: !24) +!24 = distinct !DILexicalBlock(scope: !16, file: !1, line: 16, column: 12) +!25 = !DILocation(line: 19, column: 7, scope: !24) +!26 = !DILocation(line: 20, column: 5, scope: !24) +!27 = !DILocation(line: 21, column: 1, scope: !7) +!28 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!29 = !DISubprogram(name: "f2", linkageName: "_Z2f2i", scope: !1, file: !1, line: 2, type: !30, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!30 = !DISubroutineType(types: !31) +!31 = !{!12, !12} Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-3.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-3.ll @@ -0,0 +1,78 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_reg3 +; CHECK-NEXT: DW_AT_name ("i") + +; Source to generate the IR below: +; void f1(); +; int f2(); +; extern int x; +; void test() { +; int tmp = f2(); +; // non-constant value with a single location description +; // Shouldn't change with BB-sections +; int i = tmp; +; f1(); +; x = i; +; } +; $ clang++ -S -emit-llvm -g -O2 loclist_2.cc + + +@x = external dso_local local_unnamed_addr global i32, align 4 + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + %call = tail call i32 @_Z2f2v(), !dbg !14 + call void @llvm.dbg.value(metadata i32 %call, metadata !11, metadata !DIExpression()), !dbg !15 + call void @llvm.dbg.value(metadata i32 %call, metadata !13, metadata !DIExpression()), !dbg !15 + tail call void @_Z2f1v(), !dbg !16 + store i32 %call, i32* @x, align 4, !dbg !17, !tbaa !18 + ret void, !dbg !22 +} + +declare !dbg !23 dso_local i32 @_Z2f2v() local_unnamed_addr + +declare !dbg !26 dso_local void @_Z2f1v() local_unnamed_addr + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "loclist_3.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 4, type: !8, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11, !13} +!11 = !DILocalVariable(name: "tmp", scope: !7, file: !1, line: 5, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 8, type: !12) +!14 = !DILocation(line: 5, column: 13, scope: !7) +!15 = !DILocation(line: 0, scope: !7) +!16 = !DILocation(line: 9, column: 3, scope: !7) +!17 = !DILocation(line: 10, column: 5, scope: !7) +!18 = !{!19, !19, i64 0} +!19 = !{!"int", !20, i64 0} +!20 = !{!"omnipotent char", !21, i64 0} +!21 = !{!"Simple C++ TBAA"} +!22 = !DILocation(line: 11, column: 1, scope: !7) +!23 = !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 2, type: !24, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!24 = !DISubroutineType(types: !25) +!25 = !{!12} +!26 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-4.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-4.ll @@ -0,0 +1,70 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value) +; CHECK-NEXT: DW_AT_name ("i") + +; Source to generate the IR below: +; void f1(); +; int f2(); +; void test() { +; // constant value through partial scope, no BB boundary +; // Shouldn't change with BB-sections +; int i = 7; +; f1(); +; i = f2(); +; f1(); +; } +; +; $ clang++ -S -emit-llvm -g -O2 loclist_4.cc + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 7, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !14 + %call = tail call i32 @_Z2f2v(), !dbg !15 + call void @llvm.dbg.value(metadata i32 %call, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !16 + ret void, !dbg !17 +} + +declare !dbg !18 dso_local void @_Z2f1v() local_unnamed_addr + +declare !dbg !19 dso_local i32 @_Z2f2v() local_unnamed_addr + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "loclist_4.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 3, type: !8, scopeLine: 3, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 6, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocation(line: 7, column: 3, scope: !7) +!15 = !DILocation(line: 8, column: 7, scope: !7) +!16 = !DILocation(line: 9, column: 3, scope: !7) +!17 = !DILocation(line: 10, column: 1, scope: !7) +!18 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!19 = !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 2, type: !20, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!20 = !DISubroutineType(types: !21) +!21 = !{!12} Index: llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-5.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/basic-block-sections-debug-loclist-5.ll @@ -0,0 +1,102 @@ +; RUN: llc %s --dwarf-version=4 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=4 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s --check-prefix=CHECK --check-prefix=SECTIONS +; RUN: llc %s --dwarf-version=5 --basic-block-sections=none -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s +; RUN: llc %s --dwarf-version=5 --basic-block-sections=all -filetype=obj -o %t +; RUN: llvm-dwarfdump %t | FileCheck %s --check-prefix=CHECK --check-prefix=SECTIONS + +; CHECK: DW_TAG_variable +; CHECK-NEXT: DW_AT_location +; CHECK-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; SECTIONS-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; SECTIONS-NEXT: [0x{{[0-9a-f]+}}, 0x{{[0-9a-f]+}}): DW_OP_consts +7, DW_OP_stack_value +; CHECK-NEXT: DW_AT_name ("i") + +; In the test below, i's constant value of 7 is only valud partially as is redefined at +; the end. This forces the use of a loclist with basic block sections. Without basic +; block sections, a single entry location list would be used to mark the entire scope +; in which value of i is 7. + +; Source to generate the IR below: + +; void f1(); +; int f2(); +; extern bool b; +; extern int x; +; void test() { +; int i = 7; +; f1(); +; if (b) +; f1(); +; i = f2(); +; f1(); +; } +; +; $ clang++ -S -emit-llvm -g -O2 loclist_4.cc + + +@b = external dso_local local_unnamed_addr global i8, align 1 + +define dso_local void @_Z4testv() local_unnamed_addr !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 7, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !14 + %0 = load i8, i8* @b, align 1, !dbg !15, !tbaa !17, !range !21 + %tobool.not = icmp eq i8 %0, 0, !dbg !15 + br i1 %tobool.not, label %if.end, label %if.then, !dbg !22 + +if.then: ; preds = %entry + tail call void @_Z2f1v(), !dbg !23 + br label %if.end, !dbg !23 + +if.end: ; preds = %if.then, %entry + %call = tail call i32 @_Z2f2v(), !dbg !24 + call void @llvm.dbg.value(metadata i32 %call, metadata !11, metadata !DIExpression()), !dbg !13 + tail call void @_Z2f1v(), !dbg !25 + ret void, !dbg !26 +} + +declare !dbg !27 dso_local void @_Z2f1v() local_unnamed_addr + +declare !dbg !28 dso_local i32 @_Z2f2v() local_unnamed_addr + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "loclist_5.cc", directory: "/code") +!2 = !{} +!3 = !{i32 7, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 593cb4655097552ac6d81ce18a2851ae0feb8d3c)"} +!7 = distinct !DISubprogram(name: "test", linkageName: "_Z4testv", scope: !1, file: !1, line: 5, type: !8, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !{!11} +!11 = !DILocalVariable(name: "i", scope: !7, file: !1, line: 9, type: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !DILocation(line: 0, scope: !7) +!14 = !DILocation(line: 10, column: 3, scope: !7) +!15 = !DILocation(line: 11, column: 7, scope: !16) +!16 = distinct !DILexicalBlock(scope: !7, file: !1, line: 11, column: 7) +!17 = !{!18, !18, i64 0} +!18 = !{!"bool", !19, i64 0} +!19 = !{!"omnipotent char", !20, i64 0} +!20 = !{!"Simple C++ TBAA"} +!21 = !{i8 0, i8 2} +!22 = !DILocation(line: 11, column: 7, scope: !7) +!23 = !DILocation(line: 12, column: 5, scope: !16) +!24 = !DILocation(line: 13, column: 7, scope: !7) +!25 = !DILocation(line: 14, column: 3, scope: !7) +!26 = !DILocation(line: 15, column: 1, scope: !7) +!27 = !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 1, type: !8, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!28 = !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 2, type: !29, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!29 = !DISubroutineType(types: !30) +!30 = !{!12} Index: llvm/test/DebugInfo/X86/basic-block-sections_1.ll =================================================================== --- llvm/test/DebugInfo/X86/basic-block-sections_1.ll +++ llvm/test/DebugInfo/X86/basic-block-sections_1.ll @@ -29,12 +29,10 @@ ; BB-SECTIONS-ASM: .LBB_END0_{{[0-9]+}}: ; BB-SECTIONS-ASM: .size _Z3fooi.__part.1, .LBB_END0_{{[0-9]+}}-_Z3fooi.__part.1 ; BB-SECTIONS-ASM: _Z3fooi.__part.2: -; BB-SECTIONS-ASM: .Ltmp{{[0-9]+}}: -; BB-SECTIONS-ASM-NEXT: .LBB_END0_{{[0-9]+}}: +; BB-SECTIONS-ASM: .LBB_END0_{{[0-9]+}}: ; BB-SECTIONS-ASM: .size _Z3fooi.__part.2, .LBB_END0_{{[0-9]+}}-_Z3fooi.__part.2 ; BB-SECTIONS-ASM: _Z3fooi.__part.3: -; BB-SECTIONS-ASM: .Ltmp{{[0-9]+}}: -; BB-SECTIONS-ASM-NEXT: .LBB_END0_{{[0-9]+}}: +; BB-SECTIONS-ASM: .LBB_END0_{{[0-9]+}}: ; BB-SECTIONS-ASM: .size _Z3fooi.__part.3, .LBB_END0_{{[0-9]+}}-_Z3fooi.__part.3 ; BB-SECTIONS-ASM: .Lfunc_end0: ; BB-SECTIONS-ASM: .Ldebug_ranges0: