|
| 1 | +# RUN: llc %s -o - -experimental-debug-variable-locations=true \ |
| 2 | +# RUN: -run-pass=livedebugvalues \ |
| 3 | +# RUN: | FileCheck %s --implicit-check-not=DBG_VALUE |
| 4 | +# RUN: llc %s -o - -experimental-debug-variable-locations=true \ |
| 5 | +# RUN: -start-before=livedebugvalues -filetype=obj \ |
| 6 | +# RUN: | llvm-dwarfdump - | FileCheck %s --check-prefix=DWARF |
| 7 | +# |
| 8 | +# LLVM can produce DIExpressions that convert from one value of arbitrary size |
| 9 | +# to another. This is normally fine, however that means the value for a |
| 10 | +# variable tracked in instruction referencing might not be the same size as the |
| 11 | +# variable itself. |
| 12 | +# |
| 13 | +# We typically use vector registers as shorthand for "the lower lane of the |
| 14 | +# vector register", for example if we have a single float we might say |
| 15 | +# |
| 16 | +# DBG_VALUE $xmm0 |
| 17 | +# |
| 18 | +# and that's reflected in DWARF too. However, instruction-referencing tries to |
| 19 | +# solve several size problems (see deref-spills-with-size.mir), and gets |
| 20 | +# confused by this shorthand. It manifests in the test sequence below: we |
| 21 | +# locate a variable in a vector register, spill it, then force a stack variable |
| 22 | +# location to be produced. InstrRefBasedLDV would like to produce a |
| 23 | +# DW_OP_deref_size indicating that 128 bits should be loaded for the 32 bit |
| 24 | +# register, but this would be wrong (and illegal DWARF as the max load size is |
| 25 | +# the pointer size). |
| 26 | +# |
| 27 | +# As a sticking-plaster fix: detect when we're about to emit these illegal |
| 28 | +# DWARF locations, and instead use DW_OP_deref_size. There's a small risk we |
| 29 | +# read too much or too little data, but it's better than emitting illegal DWARF. |
| 30 | + |
| 31 | +# CHECK: ![[VAR:[0-9]+]] = !DILocalVariable(name: "flannel", |
| 32 | + |
| 33 | +## Check that we're not producing DW_OP_deref_size, instead using the isIndirect |
| 34 | +## field of DBG_VALUEs. |
| 35 | + |
| 36 | +# CHECK: DBG_VALUE $xmm0, $noreg, |
| 37 | +# CHECK: DBG_VALUE $rsp, 0, ![[VAR]], !DIExpression(DW_OP_plus_uconst, 8), |
| 38 | + |
| 39 | +## Check that we produce a breg location with no further expression attached. |
| 40 | + |
| 41 | +# DWARF: DW_TAG_variable |
| 42 | +# DWARF-NEXT: DW_AT_location |
| 43 | +# DWARF-NEXT: DW_OP_reg17 XMM0 |
| 44 | +# DWARF-NEXT: DW_OP_breg7 RSP+8) |
| 45 | +# DWARF-NEXT: DW_AT_name ("flannel") |
| 46 | + |
| 47 | +--- | |
| 48 | + ; ModuleID = 'missingvar.ll' |
| 49 | + source_filename = "a" |
| 50 | + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" |
| 51 | + target triple = "x86_64-unknown-linux-gnu" |
| 52 | + |
| 53 | + define linkonce_odr void @_ZNSt5dequeIPN4llvm4LoopESaIS2_EE13_M_insert_auxESt15_Deque_iteratorIS2_RS2_PS2_EmRKS2_() local_unnamed_addr align 2 !dbg !3 { |
| 54 | + entry: |
| 55 | + call void @llvm.dbg.value(metadata i32 0, metadata !8, metadata !DIExpression()), !dbg !7 |
| 56 | + call void @llvm.dbg.value(metadata i32 0, metadata !10, metadata !DIExpression()), !dbg !7 |
| 57 | + ret void |
| 58 | + } |
| 59 | + |
| 60 | + declare void @llvm.dbg.value(metadata, metadata, metadata) |
| 61 | + |
| 62 | + !llvm.module.flags = !{!0, !9} |
| 63 | + !llvm.dbg.cu = !{!1} |
| 64 | + |
| 65 | + !0 = !{i32 2, !"Debug Info Version", i32 3} |
| 66 | + !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 4, emissionKind: FullDebug) |
| 67 | + !2 = !DIFile(filename: "bees.cpp", directory: "") |
| 68 | + !3 = distinct !DISubprogram(name: "nope", scope: !2, file: !2, line: 1, type: !4, spFlags: DISPFlagDefinition, unit: !1) |
| 69 | + !4 = !DISubroutineType(types: !5) |
| 70 | + !5 = !{!6} |
| 71 | + !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) |
| 72 | + !7 = !DILocation(line: 1, scope: !3) |
| 73 | + !8 = !DILocalVariable(name: "flannel", scope: !3, type: !6) |
| 74 | + !9 = !{i32 2, !"Dwarf Version", i32 5} |
| 75 | + !10 = !DILocalVariable(name: "shoes", scope: !3, type: !11) |
| 76 | + !11 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed) |
| 77 | + |
| 78 | + |
| 79 | +... |
| 80 | +--- |
| 81 | +name: _ZNSt5dequeIPN4llvm4LoopESaIS2_EE13_M_insert_auxESt15_Deque_iteratorIS2_RS2_PS2_EmRKS2_ |
| 82 | +alignment: 16 |
| 83 | +tracksRegLiveness: true |
| 84 | +debugInstrRef: true |
| 85 | +liveins: |
| 86 | + - { reg: '$rdi' } |
| 87 | + - { reg: '$rsi' } |
| 88 | + - { reg: '$rdx' } |
| 89 | +frameInfo: |
| 90 | + stackSize: 16 |
| 91 | + offsetAdjustment: -16 |
| 92 | + maxAlignment: 16 |
| 93 | + maxCallFrameSize: 0 |
| 94 | +stack: |
| 95 | + - { id: 6, type: spill-slot, offset: -16, size: 16, alignment: 16 } |
| 96 | +machineFunctionInfo: {} |
| 97 | +body: | |
| 98 | + bb.0.entry: |
| 99 | + liveins: $rdi, $rdx, $rsi, $rbp, $xmm0 |
| 100 | + |
| 101 | +
|
| 102 | + $xmm0 = XORPSrr $xmm0, $xmm0, debug-location !7 |
| 103 | + DBG_VALUE $xmm0, $noreg, !8, !DIExpression(), debug-location !7 |
| 104 | + VMOVUPSmr $rsp, 1, $noreg, 36, $noreg, $xmm0 :: (store (s128) into %stack.6) |
| 105 | + $xmm0 = XORPSrr $xmm0, $xmm0, debug-location !7 |
| 106 | + RET64 0, debug-location !7 |
| 107 | +... |
0 commit comments