summaryrefslogtreecommitdiff
path: root/llvm/PR36417-DebugInfo-discard-invalid-DBG_VALUE-instructions.patch
blob: 1841cf517d114db8423cb3efb42edce4ea764e32 (plain)
    1 From 783006ec19853403b8fe799e4c1b9496cb03504a Mon Sep 17 00:00:00 2001
    2 From: Bjorn Pettersson <bjorn.a.pettersson@ericsson.com>
    3 Date: Tue, 6 Mar 2018 08:47:07 +0000
    4 Subject: [PATCH] [DebugInfo] Discard invalid DBG_VALUE instructions in
    5  LiveDebugVariables
    6 
    7 Summary:
    8 This is a workaround for pr36417
    9 https://bugs.llvm.org/show_bug.cgi?id=36417
   10 
   11 LiveDebugVariables will now verify that the DBG_VALUE instructions
   12 are sane (prior to register allocation) by asking LIS if a virtual
   13 register used in the DBG_VALUE is live (or dead def) in the slot
   14 index before the DBG_VALUE. If it isn't sane the DBG_VALUE is
   15 discarded.
   16 
   17 One pass that was identified as introducing non-sane DBG_VALUE
   18 instructtons, when analysing pr36417, was the DAG->DAG Instruction
   19 Selection. It sometimes inserts DBG_VALUE instructions referring to
   20 a virtual register that is defined later in the same basic block.
   21 So it is a use before def kind of problem. The DBG_VALUE is
   22 typically inserted in the beginning of a basic block when this
   23 happens. The problem can be seen in the test case
   24 test/DebugInfo/X86/dbg-value-inlined-parameter.ll
   25 
   26 Reviewers: aprantl, rnk, probinson
   27 
   28 Reviewed By: aprantl
   29 
   30 Subscribers: vsk, davide, alexcrichton, Ka-Ka, eraman, llvm-commits, JDevlieghere
   31 
   32 Differential Revision: https://reviews.llvm.org/D43956
   33 
   34 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326769 91177308-0d34-0410-b5e6-96231b3b80d8
   35 ---
   36  lib/CodeGen/LiveDebugVariables.cpp                 |  38 +++++-
   37  test/DebugInfo/X86/dbg-value-inlined-parameter.ll  |   6 +-
   38  .../X86/live-debug-vars-discard-invalid.mir        | 141 +++++++++++++++++++++
   39  3 files changed, 181 insertions(+), 4 deletions(-)
   40  create mode 100644 test/DebugInfo/X86/live-debug-vars-discard-invalid.mir
   41 
   42 diff --git a/lib/CodeGen/LiveDebugVariables.cpp b/lib/CodeGen/LiveDebugVariables.cpp
   43 index 09168b6b9309..f3fcd004defd 100644
   44 --- a/lib/CodeGen/LiveDebugVariables.cpp
   45 +++ b/lib/CodeGen/LiveDebugVariables.cpp
   46 @@ -514,6 +514,39 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
   47      return false;
   48    }
   49  
   50 +  // Detect invalid DBG_VALUE instructions, with a debug-use of a virtual
   51 +  // register that hasn't been defined yet. If we do not remove those here, then
   52 +  // the re-insertion of the DBG_VALUE instruction after register allocation
   53 +  // will be incorrect.
   54 +  // TODO: If earlier passes are corrected to generate sane debug information
   55 +  // (and if the machine verifier is improved to catch this), then these checks
   56 +  // could be removed or replaced by asserts.
   57 +  bool Discard = false;
   58 +  if (MI.getOperand(0).isReg() &&
   59 +      TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg())) {
   60 +    const unsigned Reg = MI.getOperand(0).getReg();
   61 +    if (!LIS->hasInterval(Reg)) {
   62 +      // The DBG_VALUE is described by a virtual register that does not have a
   63 +      // live interval. Discard the DBG_VALUE.
   64 +      Discard = true;
   65 +      DEBUG(dbgs() << "Discarding debug info (no LIS interval): "
   66 +            << Idx << " " << MI);
   67 +    } else {
   68 +      // The DBG_VALUE is only valid if either Reg is live out from Idx, or Reg
   69 +      // is defined dead at Idx (where Idx is the slot index for the instruction
   70 +      // preceeding the DBG_VALUE).
   71 +      const LiveInterval &LI = LIS->getInterval(Reg);
   72 +      LiveQueryResult LRQ = LI.Query(Idx);
   73 +      if (!LRQ.valueOutOrDead()) {
   74 +        // We have found a DBG_VALUE with the value in a virtual register that
   75 +        // is not live. Discard the DBG_VALUE.
   76 +        Discard = true;
   77 +        DEBUG(dbgs() << "Discarding debug info (reg not live): "
   78 +              << Idx << " " << MI);
   79 +      }
   80 +    }
   81 +  }
   82 +
   83    // Get or create the UserValue for (variable,offset) here.
   84    bool IsIndirect = MI.getOperand(1).isImm();
   85    if (IsIndirect)
   86 @@ -522,7 +555,10 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
   87    const DIExpression *Expr = MI.getDebugExpression();
   88    UserValue *UV =
   89        getUserValue(Var, Expr, MI.getDebugLoc());
   90 -  UV->addDef(Idx, MI.getOperand(0), IsIndirect);
   91 +  if (!Discard)
   92 +    UV->addDef(Idx, MI.getOperand(0), IsIndirect);
   93 +  else
   94 +    UV->addDef(Idx, MachineOperand::CreateReg(0U, RegState::Debug), false);
   95    return true;
   96  }
   97  
   98 diff --git a/test/DebugInfo/X86/dbg-value-inlined-parameter.ll b/test/DebugInfo/X86/dbg-value-inlined-parameter.ll
   99 index 9954039654bb..e83cf0aa7ffd 100644
  100 --- a/test/DebugInfo/X86/dbg-value-inlined-parameter.ll
  101 +++ b/test/DebugInfo/X86/dbg-value-inlined-parameter.ll
  102 @@ -32,10 +32,10 @@
  103  ;CHECK-NEXT: DW_AT_call_line
  104  
  105  ;CHECK: DW_TAG_formal_parameter
  106 -;FIXME: Linux shouldn't drop this parameter either...
  107  ;CHECK-NOT: DW_TAG
  108 -;DARWIN:   DW_AT_abstract_origin {{.*}} "sp"
  109 -;DARWIN: DW_TAG_formal_parameter
  110 +;FIXME: Shouldn't drop this parameter...
  111 +;XCHECK:   DW_AT_abstract_origin {{.*}} "sp"
  112 +;XCHECK: DW_TAG_formal_parameter
  113  ;CHECK: DW_AT_abstract_origin {{.*}} "nums"
  114  ;CHECK-NOT: DW_TAG_formal_parameter
  115  
  116 diff --git a/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir b/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir
  117 new file mode 100644
  118 index 000000000000..abc21bc6ac90
  119 --- /dev/null
  120 +++ b/test/DebugInfo/X86/live-debug-vars-discard-invalid.mir
  121 @@ -0,0 +1,141 @@
  122 +# RUN: llc -mtriple=x86_64-linux-gnu -start-before greedy -stop-after virtregrewriter -o - %s | FileCheck %s
  123 +
  124 +--- |
  125 +  ; ModuleID = '<stdin>'
  126 +  source_filename = "test/DebugInfo/X86/dbg-value-inlined-parameter.ll"
  127 +  target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
  128 +  target triple = "x86_64-apple-darwin"
  129 +
  130 +  %struct.S1 = type { float*, i32 }
  131 +
  132 +  @p = common global %struct.S1 zeroinitializer, align 8, !dbg !0
  133 +
  134 +  ; Function Attrs: nounwind optsize ssp
  135 +  define void @foobar() !dbg !15 {
  136 +  entry:
  137 +    tail call void @llvm.dbg.value(metadata %struct.S1* @p, metadata !18, metadata !DIExpression()) , !dbg !25
  138 +    ret void, !dbg !32
  139 +  }
  140 +
  141 +  ; Function Attrs: nounwind readnone speculatable
  142 +  declare void @llvm.dbg.value(metadata, metadata, metadata) #2
  143 +
  144 +  !llvm.dbg.cu = !{!2}
  145 +  !llvm.module.flags = !{!14}
  146 +
  147 +  !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
  148 +  !1 = !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 14, type: !6, isLocal: false, isDefinition: true)
  149 +  !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 2.9 (trunk 125693)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !5, imports: !4)
  150 +  !3 = !DIFile(filename: "nm2.c", directory: "/private/tmp")
  151 +  !4 = !{}
  152 +  !5 = !{!0}
  153 +  !6 = !DIDerivedType(tag: DW_TAG_typedef, name: "S1", scope: !2, file: !3, line: 4, baseType: !7)
  154 +  !7 = !DICompositeType(tag: DW_TAG_structure_type, name: "S1", scope: !2, file: !3, line: 1, size: 128, align: 64, elements: !8)
  155 +  !8 = !{!9, !12}
  156 +  !9 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !3, file: !3, line: 2, baseType: !10, size: 64, align: 64)
  157 +  !10 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !2, baseType: !11, size: 64, align: 64)
  158 +  !11 = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float)
  159 +  !12 = !DIDerivedType(tag: DW_TAG_member, name: "nums", scope: !3, file: !3, line: 3, baseType: !13, size: 32, align: 32, offset: 64)
  160 +  !13 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
  161 +  !14 = !{i32 1, !"Debug Info Version", i32 3}
  162 +  !15 = distinct !DISubprogram(name: "foobar", scope: !3, file: !3, line: 15, type: !16, isLocal: false, isDefinition: true, virtualIndex: 6, isOptimized: true, unit: !2)
  163 +  !16 = !DISubroutineType(types: !17)
  164 +  !17 = !{null}
  165 +  !18 = !DILocalVariable(name: "sp", arg: 1, scope: !19, file: !3, line: 7, type: !24)
  166 +  !19 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 8, type: !20, isLocal: false, isDefinition: true, scopeLine: 8, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !2, variables: !22)
  167 +  !20 = !DISubroutineType(types: !21)
  168 +  !21 = !{!13}
  169 +  !22 = !{!18, !23}
  170 +  !23 = !DILocalVariable(name: "nums", arg: 2, scope: !19, file: !3, line: 7, type: !13)
  171 +  !24 = !DIDerivedType(tag: DW_TAG_pointer_type, scope: !2, baseType: !6, size: 64, align: 64)
  172 +  !25 = !DILocation(line: 7, column: 13, scope: !19, inlinedAt: !26)
  173 +  !26 = !DILocation(line: 16, column: 3, scope: !27)
  174 +  !27 = distinct !DILexicalBlock(scope: !15, file: !3, line: 15, column: 15)
  175 +  !32 = !DILocation(line: 17, column: 1, scope: !27)
  176 +
  177 +...
  178 +---
  179 +name:            foobar
  180 +tracksRegLiveness: true
  181 +body:             |
  182 +  bb.0:
  183 +    %1:gr64 = IMPLICIT_DEF
  184 +    %2:gr64 = IMPLICIT_DEF
  185 +
  186 +  bb.1:
  187 +    ; This DBG_VALUE will be discarded (use before def of %0).
  188 +    DBG_VALUE debug-use %0, debug-use %noreg, !18, !DIExpression(), debug-location !25
  189 +    %0:gr64 = IMPLICIT_DEF
  190 +    %0:gr64 = IMPLICIT_DEF
  191 +    %0:gr64 = IMPLICIT_DEF
  192 +    %0:gr64 = IMPLICIT_DEF
  193 +
  194 +  bb.2:
  195 +    ; This DBG_VALUE will be discarded (%1 is defined earlier, but it is not live in, so we do not know where %1 is stored).
  196 +    DBG_VALUE debug-use %1, debug-use %noreg, !18, !DIExpression(), debug-location !25
  197 +    %1:gr64 = IMPLICIT_DEF
  198 +    %1:gr64 = IMPLICIT_DEF
  199 +    %1:gr64 = IMPLICIT_DEF
  200 +    %1:gr64 = IMPLICIT_DEF
  201 +    ; This DBG_VALUE is kept, even if %1 is dead, it was defined in the prev instruction,
  202 +    ; so the value should be available for as long as the register allocated to %1 is live.
  203 +    DBG_VALUE debug-use %1, debug-use %noreg, !18, !DIExpression(), debug-location !25
  204 +
  205 +  bb.3:
  206 +    %1:gr64 = IMPLICIT_DEF
  207 +    DBG_VALUE 0, debug-use %noreg, !23, !DIExpression(), debug-location !25
  208 +    ; This DBG_VALUE is kept, even if %1 is dead, it was defined in the prev non-dbg instruction,
  209 +    ; so the value should be available for as long as the register allocated to %1 is live.
  210 +    DBG_VALUE debug-use %1, debug-use %noreg, !18, !DIExpression(), debug-location !25
  211 +
  212 +  bb.4:
  213 +    ; All DBG_VALUEs here should survive. %2 is livein as it was defined in bb.0, and it has use/def in the BTS64rr instruction.
  214 +    DBG_VALUE debug-use %2, debug-use %noreg, !18, !DIExpression(), debug-location !25
  215 +    %2:gr64 = BTS64rr %2, 0, implicit-def %eflags
  216 +    DBG_VALUE 0, debug-use %noreg, !23, !DIExpression(), debug-location !25
  217 +    DBG_VALUE debug-use %2, debug-use %noreg, !18, !DIExpression(), debug-location !25
  218 +    %2:gr64 = BTS64rr %2, 0, implicit-def %eflags
  219 +    DBG_VALUE debug-use %2, debug-use %noreg, !18, !DIExpression(), debug-location !25
  220 +    %2:gr64 = BTS64rr %2, 0, implicit-def %eflags
  221 +    DBG_VALUE debug-use %2, debug-use %noreg, !18, !DIExpression(), debug-location !25
  222 +
  223 +  bb.5:
  224 +    RET 0, debug-location !32
  225 +...
  226 +
  227 +# CHECK-LABEL: name: foobar
  228 +
  229 +# CHECK-LABEL: bb.1:
  230 +## After solving https://bugs.llvm.org/show_bug.cgi?id=36579 we expect to get a
  231 +##   DBG_VALUE debug-use %noreg
  232 +## here.
  233 +# CHECK-NOT:    DBG_VALUE
  234 +
  235 +# CHECK-LABEL: bb.2:
  236 +## After solving https://bugs.llvm.org/show_bug.cgi?id=36579 we expect to get a
  237 +##   DBG_VALUE debug-use %noreg
  238 +## here.
  239 +# CHECK-NOT:    DBG_VALUE
  240 +# CHECK:        dead renamable %rcx = IMPLICIT_DEF
  241 +# CHECK-NEXT:   dead renamable %rcx = IMPLICIT_DEF
  242 +# CHECK-NEXT:   dead renamable %rcx = IMPLICIT_DEF
  243 +# CHECK-NEXT:   dead renamable %rcx = IMPLICIT_DEF
  244 +# CHECK-NEXT:   DBG_VALUE debug-use %rcx, debug-use %noreg, !18, !DIExpression()
  245 +
  246 +# CHECK-LABEL: bb.3:
  247 +# CHECK:        dead renamable %rcx = IMPLICIT_DEF
  248 +# CHECK-NEXT:   DBG_VALUE 0, debug-use %noreg, !23, !DIExpression()
  249 +# CHECK-NEXT:   DBG_VALUE debug-use %rcx, debug-use %noreg, !18, !DIExpression()
  250 +
  251 +# CHECK-LABEL: bb.4:
  252 +# CHECK:        liveins: %rax
  253 +# CHECK:        DBG_VALUE debug-use %rax, debug-use %noreg, !18, !DIExpression()
  254 +# CHECK-NEXT:   renamable %rax = BTS64rr killed renamable %rax, 0, implicit-def %eflags
  255 +# CHECK-NEXT:   DBG_VALUE 0, debug-use %noreg, !23, !DIExpression()
  256 +# CHECK-NEXT:   DBG_VALUE debug-use %rax, debug-use %noreg, !18, !DIExpression()
  257 +# CHECK-NEXT:   renamable %rax = BTS64rr killed renamable %rax, 0, implicit-def %eflags
  258 +# CHECK-NEXT:   DBG_VALUE debug-use %rax, debug-use %noreg, !18, !DIExpression()
  259 +# CHECK-NEXT:   dead renamable %rax = BTS64rr killed renamable %rax, 0, implicit-def %eflags
  260 +
  261 +# CHECK-LABEL: bb.5:
  262 +# CHECK-NEXT:   RET 0

Generated by cgit