diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp --- a/llvm/lib/CodeGen/LiveDebugVariables.cpp +++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -119,17 +119,33 @@ DIExpression::replaceArg(Expression, OpIdx, DuplicatingIdx); } } - // A debug value referencing 64+ unique machine locations is very likely - // to be the result of a bug earlier in the pipeline. If by some means this - // limit is validly reached, then we can add a byte to the size of - // LocNoCount. - assert(LocNoVec.size() < 64 && - "debug value containing 64+ unique machine locations is not " - "supported by Live Debug Variables"); - LocNoCount = LocNoVec.size(); - if (LocNoCount > 0) { - LocNos.reset(new unsigned[LocNoCount]()); - std::copy(LocNoVec.begin(), LocNoVec.end(), loc_nos_begin()); + // FIXME: Debug values referencing 64+ unique machine locations are rare and + // currently unsupported for performance reasons. If we can verify that + // performance is acceptable for such debug values, we can increase the + // bit-width of LocNoCount to 14 to enable up to 16384 unique machine + // locations. We will also need to verify that this does not cause issues + // with LiveDebugVariables' use of IntervalMap. + if (LocNoVec.size() < 64) { + LocNoCount = LocNoVec.size(); + if (LocNoCount > 0) { + LocNos = std::make_unique(LocNoCount); + std::copy(LocNoVec.begin(), LocNoVec.end(), loc_nos_begin()); + } + } else { + LLVM_DEBUG(dbgs() << "Found debug value with 64+ unique machine " + "locations, dropping...\n"); + LocNoCount = 1; + // Turn this into an undef debug value list; right now, the simplest form + // of this is an expression with one arg, and an undef debug operand. + Expression = + DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0, + dwarf::DW_OP_stack_value}); + if (auto FragmentInfoOpt = Expr.getFragmentInfo()) + Expression = *DIExpression::createFragmentExpression( + Expression, FragmentInfoOpt->OffsetInBits, + FragmentInfoOpt->SizeInBits); + LocNos = std::make_unique(LocNoCount); + LocNos[0] = UndefLocNo; } } diff --git a/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll b/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll @@ -0,0 +1,178 @@ +; RUN: llc --stop-after=virtregrewriter -o - %s | FileCheck %s + +; Check that any debug value with 64+ unique machine location operands is set +; undef by LiveDebugVariables. + +; CHECK: ![[VAR_L:[0-9]+]] = !DILocalVariable(name: "l" + +; CHECK-NOT: DBG_VALUE +; CHECK: DBG_VALUE_LIST ![[VAR_L]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $noreg +; CHECK-NOT: DBG_VALUE + +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" + +%class.h.0.1.2.3.4.6.7.8.9.10.11.76.77.141 = type { i8 } + +@.str = external dso_local unnamed_addr constant [1 x i8], align 1 + +define dso_local i32 @_Z4funcv() local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg !5 { +entry: + %call2 = call i32 @_Z1kv() + %call4 = call i32 @_Z1kv() + %call6 = call i32 @_Z1kv() + %call8 = call i32 @_Z1kv() + %call10 = call i32 @_Z1kv() + %call12 = call i32 @_Z1kv() + %call14 = call i32 @_Z1kv() + %call16 = call i32 @_Z1kv() + %call18 = call i32 @_Z1kv() + %call20 = call i32 @_Z1kv() + %call22 = call i32 @_Z1kv() + %call24 = call i32 @_Z1kv() + %call26 = call i32 @_Z1kv() + %call28 = call i32 @_Z1kv() + %call30 = call i32 @_Z1kv() + %call32 = call i32 @_Z1kv() + %call34 = call i32 @_Z1kv() + %call36 = call i32 @_Z1kv() + %call38 = call i32 @_Z1kv() + %call40 = call i32 @_Z1kv() + %call42 = call i32 @_Z1kv() + %call44 = call i32 @_Z1kv() + %call46 = call i32 @_Z1kv() + %call48 = call i32 @_Z1kv() + %call50 = call i32 @_Z1kv() + %call52 = call i32 @_Z1kv() + %call54 = call i32 @_Z1kv() + %call56 = call i32 @_Z1kv() + %call58 = call i32 @_Z1kv() + %call60 = call i32 @_Z1kv() + %call62 = call i32 @_Z1kv() + %call64 = call i32 @_Z1kv() + %call66 = call i32 @_Z1kv() + %call68 = call i32 @_Z1kv() + %call70 = call i32 @_Z1kv() + %call72 = call i32 @_Z1kv() + %call74 = call i32 @_Z1kv() + %call76 = call i32 @_Z1kv() + %call78 = call i32 @_Z1kv() + %call80 = call i32 @_Z1kv() + %call82 = call i32 @_Z1kv() + %call84 = call i32 @_Z1kv() + %call86 = call i32 @_Z1kv() + %call88 = call i32 @_Z1kv() + %call90 = call i32 @_Z1kv() + %call92 = call i32 @_Z1kv() + %call94 = call i32 @_Z1kv() + %call96 = call i32 @_Z1kv() + %call98 = call i32 @_Z1kv() + %call100 = call i32 @_Z1kv() + %call102 = call i32 @_Z1kv() + %call104 = call i32 @_Z1kv() + %call106 = call i32 @_Z1kv() + %call108 = call i32 @_Z1kv() + %call110 = call i32 @_Z1kv() + %call112 = call i32 @_Z1kv() + %call114 = call i32 @_Z1kv() + %call116 = call i32 @_Z1kv() + %call118 = call i32 @_Z1kv() + %call120 = call i32 @_Z1kv() + %call122 = call i32 @_Z1kv() + %call124 = call i32 @_Z1kv() + %call126 = call i32 @_Z1kv() + call void @llvm.dbg.value(metadata !DIArgList(i32 0, i32 %call126, i32 %call124, i32 %call122, i32 %call120, i32 %call118, i32 %call116, i32 %call114, i32 %call112, i32 %call110, i32 %call108, i32 %call106, i32 %call104, i32 %call102, i32 %call100, i32 %call98, i32 %call96, i32 %call94, i32 %call92, i32 %call90, i32 %call88, i32 %call86, i32 %call84, i32 %call82, i32 %call80, i32 %call78, i32 %call76, i32 %call74, i32 %call72, i32 %call70, i32 %call68, i32 %call66, i32 %call64, i32 %call62, i32 %call60, i32 %call58, i32 %call56, i32 %call54, i32 %call52, i32 %call50, i32 %call48, i32 %call46, i32 %call44, i32 %call42, i32 %call40, i32 %call38, i32 %call36, i32 %call34, i32 %call32, i32 %call30, i32 %call28, i32 %call26, i32 %call24, i32 %call22, i32 %call20, i32 %call18, i32 %call16, i32 %call14, i32 %call12, i32 %call10, i32 %call8, i32 %call6, i32 %call4, i32 %call2, i32 0), metadata !10, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 64, DW_OP_plus, DW_OP_LLVM_arg, 63, DW_OP_plus, DW_OP_LLVM_arg, 62, DW_OP_plus, DW_OP_LLVM_arg, 61, DW_OP_plus, DW_OP_LLVM_arg, 60, DW_OP_plus, DW_OP_LLVM_arg, 59, DW_OP_plus, DW_OP_LLVM_arg, 58, DW_OP_plus, DW_OP_LLVM_arg, 57, DW_OP_plus, DW_OP_LLVM_arg, 56, DW_OP_plus, DW_OP_LLVM_arg, 55, DW_OP_plus, DW_OP_LLVM_arg, 54, DW_OP_plus, DW_OP_LLVM_arg, 53, DW_OP_plus, DW_OP_LLVM_arg, 52, DW_OP_plus, DW_OP_LLVM_arg, 51, DW_OP_plus, DW_OP_LLVM_arg, 50, DW_OP_plus, DW_OP_LLVM_arg, 49, DW_OP_plus, DW_OP_LLVM_arg, 48, DW_OP_plus, DW_OP_LLVM_arg, 47, DW_OP_plus, DW_OP_LLVM_arg, 46, DW_OP_plus, DW_OP_LLVM_arg, 45, DW_OP_plus, DW_OP_LLVM_arg, 44, DW_OP_plus, DW_OP_LLVM_arg, 43, DW_OP_plus, DW_OP_LLVM_arg, 42, DW_OP_plus, DW_OP_LLVM_arg, 41, DW_OP_plus, DW_OP_LLVM_arg, 40, DW_OP_plus, DW_OP_LLVM_arg, 39, DW_OP_plus, DW_OP_LLVM_arg, 38, DW_OP_plus, DW_OP_LLVM_arg, 37, DW_OP_plus, DW_OP_LLVM_arg, 36, DW_OP_plus, DW_OP_LLVM_arg, 35, DW_OP_plus, DW_OP_LLVM_arg, 34, DW_OP_plus, DW_OP_LLVM_arg, 33, DW_OP_plus, DW_OP_LLVM_arg, 32, DW_OP_plus, DW_OP_LLVM_arg, 31, DW_OP_plus, DW_OP_LLVM_arg, 30, DW_OP_plus, DW_OP_LLVM_arg, 29, DW_OP_plus, DW_OP_LLVM_arg, 28, DW_OP_plus, DW_OP_LLVM_arg, 27, DW_OP_plus, DW_OP_LLVM_arg, 26, DW_OP_plus, DW_OP_LLVM_arg, 25, DW_OP_plus, DW_OP_LLVM_arg, 24, DW_OP_plus, DW_OP_LLVM_arg, 23, DW_OP_plus, DW_OP_LLVM_arg, 22, DW_OP_plus, DW_OP_LLVM_arg, 21, DW_OP_plus, DW_OP_LLVM_arg, 20, DW_OP_plus, DW_OP_LLVM_arg, 19, DW_OP_plus, DW_OP_LLVM_arg, 18, DW_OP_plus, DW_OP_LLVM_arg, 17, DW_OP_plus, DW_OP_LLVM_arg, 16, DW_OP_plus, DW_OP_LLVM_arg, 15, DW_OP_plus, DW_OP_LLVM_arg, 14, DW_OP_plus, DW_OP_LLVM_arg, 13, DW_OP_plus, DW_OP_LLVM_arg, 12, DW_OP_plus, DW_OP_LLVM_arg, 11, DW_OP_plus, DW_OP_LLVM_arg, 10, DW_OP_plus, DW_OP_LLVM_arg, 9, DW_OP_plus, DW_OP_LLVM_arg, 8, DW_OP_plus, DW_OP_LLVM_arg, 7, DW_OP_plus, DW_OP_LLVM_arg, 6, DW_OP_plus, DW_OP_LLVM_arg, 5, DW_OP_plus, DW_OP_LLVM_arg, 4, DW_OP_plus, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_plus, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)), !dbg !11 + %add3 = add nsw i32 0, %call2 + %add5 = add nsw i32 %add3, %call4 + %add7 = add nsw i32 %add5, %call6 + %add9 = add nsw i32 %add7, %call8 + %add11 = add nsw i32 %add9, %call10 + %add13 = add nsw i32 %add11, %call12 + %add15 = add nsw i32 %add13, %call14 + %add17 = add nsw i32 %add15, %call16 + %add19 = add nsw i32 %add17, %call18 + %add21 = add nsw i32 %add19, %call20 + %add23 = add nsw i32 %add21, %call22 + %add25 = add nsw i32 %add23, %call24 + %add27 = add nsw i32 %add25, %call26 + %add29 = add nsw i32 %add27, %call28 + %add31 = add nsw i32 %add29, %call30 + %add33 = add nsw i32 %add31, %call32 + %add35 = add nsw i32 %add33, %call34 + %add37 = add nsw i32 %add35, %call36 + %add39 = add nsw i32 %add37, %call38 + %add41 = add nsw i32 %add39, %call40 + %add43 = add nsw i32 %add41, %call42 + %add45 = add nsw i32 %add43, %call44 + %add47 = add nsw i32 %add45, %call46 + %add49 = add nsw i32 %add47, %call48 + %add51 = add nsw i32 %add49, %call50 + %add53 = add nsw i32 %add51, %call52 + %add55 = add nsw i32 %add53, %call54 + %add57 = add nsw i32 %add55, %call56 + %add59 = add nsw i32 %add57, %call58 + %add61 = add nsw i32 %add59, %call60 + %add63 = add nsw i32 %add61, %call62 + %add65 = add nsw i32 %add63, %call64 + %add67 = add nsw i32 %add65, %call66 + %add69 = add nsw i32 %add67, %call68 + %add71 = add nsw i32 %add69, %call70 + %add73 = add nsw i32 %add71, %call72 + %add75 = add nsw i32 %add73, %call74 + %add77 = add nsw i32 %add75, %call76 + %add79 = add nsw i32 %add77, %call78 + %add81 = add nsw i32 %add79, %call80 + %add83 = add nsw i32 %add81, %call82 + %add85 = add nsw i32 %add83, %call84 + %add87 = add nsw i32 %add85, %call86 + %add89 = add nsw i32 %add87, %call88 + %add91 = add nsw i32 %add89, %call90 + %add93 = add nsw i32 %add91, %call92 + %add95 = add nsw i32 %add93, %call94 + %add97 = add nsw i32 %add95, %call96 + %add99 = add nsw i32 %add97, %call98 + %add101 = add nsw i32 %add99, %call100 + %add103 = add nsw i32 %add101, %call102 + %add105 = add nsw i32 %add103, %call104 + %add107 = add nsw i32 %add105, %call106 + %add109 = add nsw i32 %add107, %call108 + %add111 = add nsw i32 %add109, %call110 + %add113 = add nsw i32 %add111, %call112 + %add115 = add nsw i32 %add113, %call114 + %add117 = add nsw i32 %add115, %call116 + %add119 = add nsw i32 %add117, %call118 + %add121 = add nsw i32 %add119, %call120 + %add123 = add nsw i32 %add121, %call122 + %add125 = add nsw i32 %add123, %call124 + %add127 = add nsw i32 %add125, %call126 + %add130 = add nsw i32 %add127, 0 + ret i32 %add130 +} + +declare dso_local i32 @_Z1kv() local_unnamed_addr + +declare dso_local i32 @_Z1j1h(%class.h.0.1.2.3.4.6.7.8.9.10.11.76.77.141*) local_unnamed_addr + +declare dso_local void @_ZN1hC1EPKc(%class.h.0.1.2.3.4.6.7.8.9.10.11.76.77.141*, i8*) unnamed_addr + +declare dso_local i32 @__gxx_personality_v0(...) + +declare dso_local void @_ZN1hD1Ev(%class.h.0.1.2.3.4.6.7.8.9.10.11.76.77.141*) unnamed_addr + +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 13.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "test.cpp", directory: "/") +!2 = !{} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 7, !"uwtable", i32 1} +!5 = distinct !DISubprogram(name: "func", linkageName: "_Z4funcv", scope: !1, file: !1, line: 10, type: !6, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !9) +!6 = !DISubroutineType(types: !7) +!7 = !{!8} +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{!10} +!10 = !DILocalVariable(name: "l", scope: !5, file: !1, line: 11, type: !8) +!11 = !DILocation(line: 0, scope: !5)