[llvm] r331182 - [SelectionDAG] Improve selection of DBG_VALUE using a PHI node result

Bjorn Pettersson via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 30 07:37:39 PDT 2018


Author: bjope
Date: Mon Apr 30 07:37:39 2018
New Revision: 331182

URL: http://llvm.org/viewvc/llvm-project?rev=331182&view=rev
Log:
[SelectionDAG] Improve selection of DBG_VALUE using a PHI node result

Summary:
When building the selection DAG at ISel all PHI nodes are
selected and lowered to Machine Instruction PHI nodes before
we start to create any SDNodes. So there are no SDNodes for
values produced by the PHI nodes.

In the past when selecting a dbg.value intrinsic that uses
the value produced by a PHI node we have been handling such
dbg.value intrinsics as "dangling debug info". I.e. we have
not created a SDDbgValue node directly, because there is
no existing SDNode for the PHI result, instead we deferred
the creationg of a SDDbgValue until we found the first use
of the PHI result.

The old solution had a couple of flaws. The position of the
selected DBG_VALUE instruction would end up quite late in a
basic block, and for example not directly after the PHI node
as in the LLVM IR input. And in case there were no use at all
in the basic block the dbg.value could be dropped completely.

This patch introduces a new VREG kind of SDDbgValue nodes.
It is similar to a SDNODE kind of node, but it refers directly
to a virtual register and not a SDNode. When we do selection
for a dbg.value that is using the result of a PHI node we
can do a lookup of the virtual register directly (as it already
is determined for the PHI node) and create a SDDbgValue node
immediately instead of delaying the selection until we find a
use.

This should fix a problem with losing debug info at ISel
as seen in PR37234 (https://bugs.llvm.org/show_bug.cgi?id=37234).
It does not resolve PR37234 completely, because the debug info
is dropped later on in the BranchFolder (see D46184).

Reviewers: #debug-info, aprantl

Reviewed By: #debug-info, aprantl

Subscribers: rnk, gbedwell, aprantl, JDevlieghere, llvm-commits

Differential Revision: https://reviews.llvm.org/D46129

Added:
    llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll
    llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
    llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/trunk/test/DebugInfo/COFF/pieces.ll

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=331182&r1=331181&r2=331182&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Mon Apr 30 07:37:39 2018
@@ -1242,6 +1242,11 @@ public:
                                     unsigned FI, const DebugLoc &DL,
                                     unsigned O);
 
+  /// Creates a VReg SDDbgValue node.
+  SDDbgValue *getVRegDbgValue(DIVariable *Var, DIExpression *Expr,
+                              unsigned VReg, bool IsIndirect,
+                              const DebugLoc &DL, unsigned O);
+
   /// Transfer debug values from one node to another, while optionally
   /// generating fragment expressions for split-up values. If \p InvalidateDbg
   /// is set, debug values are invalidated after they are transferred.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp?rev=331182&r1=331181&r2=331182&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/InstrEmitter.cpp Mon Apr 30 07:37:39 2018
@@ -720,6 +720,8 @@ InstrEmitter::EmitDbgValue(SDDbgValue *S
     else
       AddOperand(MIB, Op, (*MIB).getNumOperands(), &II, VRBaseMap,
                  /*IsDebug=*/true, /*IsClone=*/false, /*IsCloned=*/false);
+  } else if (SD->getKind() == SDDbgValue::VREG) {
+    MIB.addReg(SD->getVReg(), RegState::Debug);
   } else if (SD->getKind() == SDDbgValue::CONST) {
     const Value *V = SD->getConst();
     if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h?rev=331182&r1=331181&r2=331182&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h Mon Apr 30 07:37:39 2018
@@ -32,7 +32,8 @@ public:
   enum DbgValueKind {
     SDNODE = 0,             ///< Value is the result of an expression.
     CONST = 1,              ///< Value is a constant.
-    FRAMEIX = 2             ///< Value is contents of a stack location.
+    FRAMEIX = 2,            ///< Value is contents of a stack location.
+    VREG = 3                ///< Value is a virtual register.
   };
 private:
   union {
@@ -42,6 +43,7 @@ private:
     } s;
     const Value *Const;     ///< Valid for constants.
     unsigned FrameIx;       ///< Valid for stack objects.
+    unsigned VReg;          ///< Valid for registers.
   } u;
   DIVariable *Var;
   DIExpression *Expr;
@@ -77,6 +79,14 @@ public:
     u.FrameIx = FI;
   }
 
+  /// Constructor for virtual registers.
+  SDDbgValue(DIVariable *Var, DIExpression *Expr, unsigned VReg, bool indir,
+             DebugLoc dl, unsigned O)
+      : Var(Var), Expr(Expr), DL(std::move(dl)), Order(O), IsIndirect(indir) {
+    kind = VREG;
+    u.VReg = VReg;
+  }
+
   /// Returns the kind.
   DbgValueKind getKind() const { return kind; }
 
@@ -98,6 +108,9 @@ public:
   /// Returns the FrameIx for a stack object
   unsigned getFrameIx() const { assert (kind==FRAMEIX); return u.FrameIx; }
 
+  /// Returns the Virtual Register for a VReg
+  unsigned getVReg() const { assert (kind==VREG); return u.VReg; }
+
   /// Returns whether this is an indirect value.
   bool isIndirect() const { return IsIndirect; }
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=331182&r1=331181&r2=331182&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Mon Apr 30 07:37:39 2018
@@ -7310,6 +7310,17 @@ SDDbgValue *SelectionDAG::getFrameIndexD
   return new (DbgInfo->getAlloc()) SDDbgValue(Var, Expr, FI, DL, O);
 }
 
+/// VReg
+SDDbgValue *SelectionDAG::getVRegDbgValue(DIVariable *Var,
+                                          DIExpression *Expr,
+                                          unsigned VReg, bool IsIndirect,
+                                          const DebugLoc &DL, unsigned O) {
+  assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
+         "Expected inlined-at fields to agree");
+  return new (DbgInfo->getAlloc()) SDDbgValue(Var, Expr, VReg, IsIndirect, DL,
+                                              O);
+}
+
 void SelectionDAG::transferDbgValues(SDValue From, SDValue To,
                                      unsigned OffsetInBits, unsigned SizeInBits,
                                      bool InvalidateDbg) {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=331182&r1=331181&r2=331182&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Apr 30 07:37:39 2018
@@ -5254,6 +5254,19 @@ SelectionDAGBuilder::visitIntrinsicCall(
       return nullptr;
     }
 
+    // PHI nodes have already been selected, so we should know which VReg that
+    // is assigns to already.
+    if (isa<PHINode>(V)) {
+      auto It = FuncInfo.ValueMap.find(V);
+      if (It != FuncInfo.ValueMap.end()) {
+        unsigned Reg = It->second;
+        SDV = DAG.getVRegDbgValue(Variable, Expression, Reg, false, dl,
+                                  SDNodeOrder);
+        DAG.AddDbgValue(SDV, nullptr, false);
+        return nullptr;
+      }
+    }
+
     // TODO: When we get here we will either drop the dbg.value completely, or
     // we try to move it forward by letting it dangle for awhile. So we should
     // probably add an extra DbgValue to the DAG here, with a reference to

Modified: llvm/trunk/test/DebugInfo/COFF/pieces.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/pieces.ll?rev=331182&r1=331181&r2=331182&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/pieces.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/pieces.ll Mon Apr 30 07:37:39 2018
@@ -42,19 +42,20 @@
 ; ASM:         xorl    %esi, %esi
 ; ASM:         .p2align        4, 0x90
 ; ASM: .LBB0_3:                                # %for.body
-; ASM: [[ox_start:\.Ltmp[0-9]+]]:
+; ASM: [[oy_ox_start:\.Ltmp[0-9]+]]:
 ; ASM:        #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 0 32] $edi
+; ASM:        #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 32 32] $esi
 ; ASM:        .cv_loc 0 1 13 11               # t.c:13:11
 ; ASM:        movl    %edi, %ecx
 ; ASM:        callq   g
 ; ASM:        movl    %eax, %edi
-; ASM: [[oy_start:\.Ltmp[0-9]+]]:
+; ASM: [[ox_start:\.Ltmp[0-9]+]]:
 ; ASM:         #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 0 32] $edi
-; ASM:         #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 32 32] $esi
 ; ASM:         .cv_loc 0 1 14 11               # t.c:14:11
 ; ASM:         movl    %esi, %ecx
 ; ASM:         callq   g
 ; ASM:         movl    %eax, %esi
+; ASM: [[oy_start:\.Ltmp[0-9]+]]:
 ; ASM:         #DEBUG_VALUE: loop_csr:o <- [DW_OP_LLVM_fragment 32 32] $esi
 ; ASM:         cmpl    n(%rip), %eax
 ; ASM:         jl      .LBB0_3
@@ -101,6 +102,8 @@
 ; ASM:        .asciz  "loop_csr"              # Function name
 ; ASM:        .short  4414                    # Record kind: S_LOCAL
 ; ASM:        .asciz  "o"
+; ASM:        .cv_def_range    [[oy_ox_start]] [[ox_start]], "C\021\030\000\000\000\000\000\000\000"
+; ASM:        .cv_def_range    [[oy_ox_start]] [[oy_start]], "C\021\027\000\000\000\004\000\000\000"
 ; ASM:        .cv_def_range    [[ox_start]] .Lfunc_end0, "C\021\030\000\000\000\000\000\000\000"
 ; ASM:        .cv_def_range    [[oy_start]] [[oy_end]], "C\021\027\000\000\000\004\000\000\000"
 

Added: llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll?rev=331182&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-1.ll Mon Apr 30 07:37:39 2018
@@ -0,0 +1,178 @@
+; RUN: llc -start-after=codegenprepare -stop-before expand-isel-pseudos -o - %s | FileCheck %s
+
+; This test case was generated from the following debug.c program,
+; using: clang debug.c -g -O1 -S -o dbg_value_phi_isel1.ll -emit-llvm
+; --------------------------------------
+; int end = 10;
+;
+; int main() {
+;   int x = 9;
+;   int y = 13;
+;   for (int u = 0; u < end; ++u) {
+;     x += y;
+;     y = y * 3;
+;   }
+;
+;   volatile int arr[80];
+;   for (int q = 0; q < 64; ++q) {
+;     arr[q] = q + 3;
+;   }
+;
+;   return x;
+; }
+; --------------------------------------
+;
+
+; ModuleID = 'debug.c'
+source_filename = "debug.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at end = dso_local local_unnamed_addr global i32 10, align 4, !dbg !0
+
+; Function Attrs: nounwind uwtable
+define dso_local i32 @main() local_unnamed_addr #0 !dbg !11 {
+; CHECK-LABEL: name:            main
+entry:
+  %arr = alloca [80 x i32], align 16
+  call void @llvm.dbg.value(metadata i32 9, metadata !15, metadata !DIExpression()), !dbg !26
+  call void @llvm.dbg.value(metadata i32 13, metadata !16, metadata !DIExpression()), !dbg !27
+  call void @llvm.dbg.value(metadata i32 0, metadata !17, metadata !DIExpression()), !dbg !28
+  %0 = load i32, i32* @end, align 4, !dbg !29, !tbaa !31
+  %cmp20 = icmp sgt i32 %0, 0, !dbg !35
+  br i1 %cmp20, label %for.body.lr.ph, label %for.cond.cleanup, !dbg !36
+
+for.body.lr.ph:                                   ; preds = %entry
+  %1 = load i32, i32* @end, align 4, !tbaa !31
+  br label %for.body, !dbg !36
+
+for.cond.cleanup:                                 ; preds = %for.body, %entry
+; CHECK-LABEL: bb.{{.*}}.for.cond.cleanup:
+; CHECK:      [[REG1:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: DBG_VALUE debug-use [[REG1]]
+  %x.0.lcssa = phi i32 [ 9, %entry ], [ %add, %for.body ]
+  call void @llvm.dbg.value(metadata i32 %x.0.lcssa, metadata !15, metadata !DIExpression()), !dbg !26
+  %2 = bitcast [80 x i32]* %arr to i8*, !dbg !37
+  call void @llvm.lifetime.start.p0i8(i64 320, i8* nonnull %2) #3, !dbg !37
+  call void @llvm.dbg.declare(metadata [80 x i32]* %arr, metadata !19, metadata !DIExpression()), !dbg !38
+  call void @llvm.dbg.value(metadata i32 0, metadata !24, metadata !DIExpression()), !dbg !39
+  br label %for.body4, !dbg !40
+
+for.body:                                         ; preds = %for.body.lr.ph, %for.body
+; CHECK-LABEL: bb.{{.*}}.for.body:
+; CHECK:      [[REG2:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: [[REG3:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: [[REG4:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: DBG_VALUE debug-use [[REG2]]
+; CHECK-NEXT: DBG_VALUE debug-use [[REG3]]
+; CHECK-NEXT: DBG_VALUE debug-use [[REG4]]
+  %u.023 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+  %y.022 = phi i32 [ 13, %for.body.lr.ph ], [ %mul, %for.body ]
+  %x.021 = phi i32 [ 9, %for.body.lr.ph ], [ %add, %for.body ]
+  call void @llvm.dbg.value(metadata i32 %u.023, metadata !17, metadata !DIExpression()), !dbg !28
+  call void @llvm.dbg.value(metadata i32 %y.022, metadata !16, metadata !DIExpression()), !dbg !27
+  call void @llvm.dbg.value(metadata i32 %x.021, metadata !15, metadata !DIExpression()), !dbg !26
+  %add = add nuw nsw i32 %y.022, %x.021, !dbg !41
+  %mul = mul nsw i32 %y.022, 3, !dbg !43
+  %inc = add nuw nsw i32 %u.023, 1, !dbg !44
+  call void @llvm.dbg.value(metadata i32 %inc, metadata !17, metadata !DIExpression()), !dbg !28
+  call void @llvm.dbg.value(metadata i32 %mul, metadata !16, metadata !DIExpression()), !dbg !27
+  call void @llvm.dbg.value(metadata i32 %add, metadata !15, metadata !DIExpression()), !dbg !26
+  %cmp = icmp slt i32 %inc, %1, !dbg !35
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !36, !llvm.loop !45
+
+for.cond.cleanup3:                                ; preds = %for.body4
+  call void @llvm.lifetime.end.p0i8(i64 320, i8* nonnull %2) #3, !dbg !47
+  ret i32 %x.0.lcssa, !dbg !48
+
+for.body4:                                        ; preds = %for.body4, %for.cond.cleanup
+  %indvars.iv = phi i64 [ 0, %for.cond.cleanup ], [ %indvars.iv.next, %for.body4 ]
+  call void @llvm.dbg.value(metadata i64 %indvars.iv, metadata !24, metadata !DIExpression()), !dbg !39
+  %arrayidx = getelementptr inbounds [80 x i32], [80 x i32]* %arr, i64 0, i64 %indvars.iv, !dbg !49
+  %3 = trunc i64 %indvars.iv to i32, !dbg !52
+  %4 = add i32 %3, 3, !dbg !52
+  store volatile i32 %4, i32* %arrayidx, align 4, !dbg !52, !tbaa !31
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !53
+  call void @llvm.dbg.value(metadata i32 undef, metadata !24, metadata !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value)), !dbg !39
+  %exitcond = icmp eq i64 %indvars.iv.next, 64, !dbg !54
+  br i1 %exitcond, label %for.cond.cleanup3, label %for.body4, !dbg !40, !llvm.loop !55
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2
+
+attributes #0 = { nounwind uwtable }
+attributes #1 = { argmemonly nounwind }
+attributes #2 = { nounwind readnone speculatable }
+attributes #3 = { nounwind }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "end", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0 (x)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "debug.c", directory: "")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{!"clang version 7.0.0 (x)"}
+!11 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !2, variables: !14)
+!12 = !DISubroutineType(types: !13)
+!13 = !{!6}
+!14 = !{!15, !16, !17, !19, !24}
+!15 = !DILocalVariable(name: "x", scope: !11, file: !3, line: 4, type: !6)
+!16 = !DILocalVariable(name: "y", scope: !11, file: !3, line: 5, type: !6)
+!17 = !DILocalVariable(name: "u", scope: !18, file: !3, line: 6, type: !6)
+!18 = distinct !DILexicalBlock(scope: !11, file: !3, line: 6, column: 3)
+!19 = !DILocalVariable(name: "arr", scope: !11, file: !3, line: 11, type: !20)
+!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !21, size: 2560, elements: !22)
+!21 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !6)
+!22 = !{!23}
+!23 = !DISubrange(count: 80)
+!24 = !DILocalVariable(name: "q", scope: !25, file: !3, line: 12, type: !6)
+!25 = distinct !DILexicalBlock(scope: !11, file: !3, line: 12, column: 3)
+!26 = !DILocation(line: 4, column: 7, scope: !11)
+!27 = !DILocation(line: 5, column: 7, scope: !11)
+!28 = !DILocation(line: 6, column: 12, scope: !18)
+!29 = !DILocation(line: 6, column: 23, scope: !30)
+!30 = distinct !DILexicalBlock(scope: !18, file: !3, line: 6, column: 3)
+!31 = !{!32, !32, i64 0}
+!32 = !{!"int", !33, i64 0}
+!33 = !{!"omnipotent char", !34, i64 0}
+!34 = !{!"Simple C/C++ TBAA"}
+!35 = !DILocation(line: 6, column: 21, scope: !30)
+!36 = !DILocation(line: 6, column: 3, scope: !18)
+!37 = !DILocation(line: 11, column: 3, scope: !11)
+!38 = !DILocation(line: 11, column: 16, scope: !11)
+!39 = !DILocation(line: 12, column: 12, scope: !25)
+!40 = !DILocation(line: 12, column: 3, scope: !25)
+!41 = !DILocation(line: 7, column: 7, scope: !42)
+!42 = distinct !DILexicalBlock(scope: !30, file: !3, line: 6, column: 33)
+!43 = !DILocation(line: 8, column: 11, scope: !42)
+!44 = !DILocation(line: 6, column: 28, scope: !30)
+!45 = distinct !{!45, !36, !46}
+!46 = !DILocation(line: 9, column: 3, scope: !18)
+!47 = !DILocation(line: 17, column: 1, scope: !11)
+!48 = !DILocation(line: 16, column: 3, scope: !11)
+!49 = !DILocation(line: 13, column: 5, scope: !50)
+!50 = distinct !DILexicalBlock(scope: !51, file: !3, line: 12, column: 32)
+!51 = distinct !DILexicalBlock(scope: !25, file: !3, line: 12, column: 3)
+!52 = !DILocation(line: 13, column: 12, scope: !50)
+!53 = !DILocation(line: 12, column: 27, scope: !51)
+!54 = !DILocation(line: 12, column: 21, scope: !51)
+!55 = distinct !{!55, !40, !56}
+!56 = !DILocation(line: 14, column: 3, scope: !25)

Added: llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll?rev=331182&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll (added)
+++ llvm/trunk/test/DebugInfo/X86/sdag-dbgvalue-phi-use-2.ll Mon Apr 30 07:37:39 2018
@@ -0,0 +1,171 @@
+; RUN: llc -start-after=codegenprepare -stop-before expand-isel-pseudos -o - %s | FileCheck %s
+
+; This test case is a modified version of dbg_value_phi_isel1.ll
+; where the llvm.dbg.value nodes in for.body has been moved.
+
+; ModuleID = 'debug.c'
+source_filename = "debug.c"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at end = dso_local local_unnamed_addr global i32 10, align 4, !dbg !0
+
+; Function Attrs: nounwind uwtable
+define dso_local i32 @main() local_unnamed_addr #0 !dbg !11 {
+entry:
+  %arr = alloca [80 x i32], align 16
+  call void @llvm.dbg.value(metadata i32 9, metadata !15, metadata !DIExpression()), !dbg !26
+  call void @llvm.dbg.value(metadata i32 13, metadata !16, metadata !DIExpression()), !dbg !27
+  call void @llvm.dbg.value(metadata i32 0, metadata !17, metadata !DIExpression()), !dbg !28
+  %0 = load i32, i32* @end, align 4, !dbg !29, !tbaa !31
+  %cmp20 = icmp sgt i32 %0, 0, !dbg !35
+  br i1 %cmp20, label %for.body.lr.ph, label %for.cond.cleanup, !dbg !36
+
+for.body.lr.ph:                                   ; preds = %entry
+  %1 = load i32, i32* @end, align 4, !tbaa !31
+  br label %for.body, !dbg !36
+
+for.cond.cleanup:                                 ; preds = %for.body, %entry
+; CHECK-LABEL: bb.{{.*}}.for.cond.cleanup:
+; CHECK:      [[REG1:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: DBG_VALUE debug-use [[REG1]]
+  %x.0.lcssa = phi i32 [ 9, %entry ], [ %add, %for.body ]
+  call void @llvm.dbg.value(metadata i32 %x.0.lcssa, metadata !15, metadata !DIExpression()), !dbg !26
+  %2 = bitcast [80 x i32]* %arr to i8*, !dbg !37
+  call void @llvm.lifetime.start.p0i8(i64 320, i8* nonnull %2) #3, !dbg !37
+  call void @llvm.dbg.declare(metadata [80 x i32]* %arr, metadata !19, metadata !DIExpression()), !dbg !38
+  call void @llvm.dbg.value(metadata i32 0, metadata !24, metadata !DIExpression()), !dbg !39
+  br label %for.body4, !dbg !40
+
+for.body:                                         ; preds = %for.body.lr.ph, %for.body
+; CHECK-LABEL: bb.{{.*}}.for.body:
+; CHECK:      [[REG2:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: [[REG3:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: [[REG4:%[0-9]+]]:gr32 = PHI
+; CHECK-NEXT: DBG_VALUE debug-use [[REG3]], debug-use $noreg, !16
+; CHECK-NEXT: DBG_VALUE 555, debug-use $noreg, !17
+; XXX: Shouldn't the following DBG_VALUE be placed after the add (ADD32rr).
+; CHECK-NEXT: DBG_VALUE debug-use [[REG2]], debug-use $noreg, !17
+; CHECK-NEXT: ADD32rr
+; XXX: Shouldn't the following DBG_VALUE be placed after the mul (LEA etc).
+; CHECK-NEXT: DBG_VALUE 777, debug-use $noreg, !17
+; CHECK:      INC32r
+; XXX: Shouldn't the following DBG_VALUE be placed after the icmp (the non-dead implicit def of $eflags)
+; CHECK:      DBG_VALUE debug-use [[REG4]]
+; CHECK-NEXT: implicit-def $eflags
+  %u.023 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
+  %y.022 = phi i32 [ 13, %for.body.lr.ph ], [ %mul, %for.body ]
+  %x.021 = phi i32 [ 9, %for.body.lr.ph ], [ %add, %for.body ]
+  call void @llvm.dbg.value(metadata i32 %y.022, metadata !16, metadata !DIExpression()), !dbg !27
+  ; This dbg.value has been manually added compared to dbg_value_phi_isel1.ll
+  call void @llvm.dbg.value(metadata i32 555, metadata !17, metadata !DIExpression()), !dbg !28
+  %add = add nuw nsw i32 %y.022, %x.021, !dbg !41
+  ; This dbg.value has been manually moved compared to dbg_value_phi_isel1.ll
+  call void @llvm.dbg.value(metadata i32 %u.023, metadata !17, metadata !DIExpression()), !dbg !28
+  %mul = mul nsw i32 %y.022, 3, !dbg !43
+  ; This dbg.value has been manually added compared to dbg_value_phi_isel1.ll
+  call void @llvm.dbg.value(metadata i32 777, metadata !17, metadata !DIExpression()), !dbg !28
+  %inc = add nuw nsw i32 %u.023, 1, !dbg !44
+  call void @llvm.dbg.value(metadata i32 %inc, metadata !17, metadata !DIExpression()), !dbg !28
+  call void @llvm.dbg.value(metadata i32 %mul, metadata !16, metadata !DIExpression()), !dbg !27
+  call void @llvm.dbg.value(metadata i32 %add, metadata !15, metadata !DIExpression()), !dbg !26
+  %cmp = icmp slt i32 %inc, %1, !dbg !35
+  ; This dbg.value has been manually moved compared to dbg_value_phi_isel1.ll
+  call void @llvm.dbg.value(metadata i32 %x.021, metadata !15, metadata !DIExpression()), !dbg !26
+  br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !36, !llvm.loop !45
+
+for.cond.cleanup3:                                ; preds = %for.body4
+  call void @llvm.lifetime.end.p0i8(i64 320, i8* nonnull %2) #3, !dbg !47
+  ret i32 %x.0.lcssa, !dbg !48
+
+for.body4:                                        ; preds = %for.body4, %for.cond.cleanup
+  %indvars.iv = phi i64 [ 0, %for.cond.cleanup ], [ %indvars.iv.next, %for.body4 ]
+  call void @llvm.dbg.value(metadata i64 %indvars.iv, metadata !24, metadata !DIExpression()), !dbg !39
+  %arrayidx = getelementptr inbounds [80 x i32], [80 x i32]* %arr, i64 0, i64 %indvars.iv, !dbg !49
+  %3 = trunc i64 %indvars.iv to i32, !dbg !52
+  %4 = add i32 %3, 3, !dbg !52
+  store volatile i32 %4, i32* %arrayidx, align 4, !dbg !52, !tbaa !31
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1, !dbg !53
+  call void @llvm.dbg.value(metadata i32 undef, metadata !24, metadata !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value)), !dbg !39
+  %exitcond = icmp eq i64 %indvars.iv.next, 64, !dbg !54
+  br i1 %exitcond, label %for.cond.cleanup3, label %for.body4, !dbg !40, !llvm.loop !55
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: nounwind readnone speculatable
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2
+
+attributes #0 = { nounwind uwtable }
+attributes #1 = { argmemonly nounwind }
+attributes #2 = { nounwind readnone speculatable }
+attributes #3 = { nounwind }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "end", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0 (x)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "debug.c", directory: "")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{!"clang version 7.0.0 (x)"}
+!11 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: true, unit: !2, variables: !14)
+!12 = !DISubroutineType(types: !13)
+!13 = !{!6}
+!14 = !{!15, !16, !17, !19, !24}
+!15 = !DILocalVariable(name: "x", scope: !11, file: !3, line: 4, type: !6)
+!16 = !DILocalVariable(name: "y", scope: !11, file: !3, line: 5, type: !6)
+!17 = !DILocalVariable(name: "u", scope: !18, file: !3, line: 6, type: !6)
+!18 = distinct !DILexicalBlock(scope: !11, file: !3, line: 6, column: 3)
+!19 = !DILocalVariable(name: "arr", scope: !11, file: !3, line: 11, type: !20)
+!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !21, size: 2560, elements: !22)
+!21 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !6)
+!22 = !{!23}
+!23 = !DISubrange(count: 80)
+!24 = !DILocalVariable(name: "q", scope: !25, file: !3, line: 12, type: !6)
+!25 = distinct !DILexicalBlock(scope: !11, file: !3, line: 12, column: 3)
+!26 = !DILocation(line: 4, column: 7, scope: !11)
+!27 = !DILocation(line: 5, column: 7, scope: !11)
+!28 = !DILocation(line: 6, column: 12, scope: !18)
+!29 = !DILocation(line: 6, column: 23, scope: !30)
+!30 = distinct !DILexicalBlock(scope: !18, file: !3, line: 6, column: 3)
+!31 = !{!32, !32, i64 0}
+!32 = !{!"int", !33, i64 0}
+!33 = !{!"omnipotent char", !34, i64 0}
+!34 = !{!"Simple C/C++ TBAA"}
+!35 = !DILocation(line: 6, column: 21, scope: !30)
+!36 = !DILocation(line: 6, column: 3, scope: !18)
+!37 = !DILocation(line: 11, column: 3, scope: !11)
+!38 = !DILocation(line: 11, column: 16, scope: !11)
+!39 = !DILocation(line: 12, column: 12, scope: !25)
+!40 = !DILocation(line: 12, column: 3, scope: !25)
+!41 = !DILocation(line: 7, column: 7, scope: !42)
+!42 = distinct !DILexicalBlock(scope: !30, file: !3, line: 6, column: 33)
+!43 = !DILocation(line: 8, column: 11, scope: !42)
+!44 = !DILocation(line: 6, column: 28, scope: !30)
+!45 = distinct !{!45, !36, !46}
+!46 = !DILocation(line: 9, column: 3, scope: !18)
+!47 = !DILocation(line: 17, column: 1, scope: !11)
+!48 = !DILocation(line: 16, column: 3, scope: !11)
+!49 = !DILocation(line: 13, column: 5, scope: !50)
+!50 = distinct !DILexicalBlock(scope: !51, file: !3, line: 12, column: 32)
+!51 = distinct !DILexicalBlock(scope: !25, file: !3, line: 12, column: 3)
+!52 = !DILocation(line: 13, column: 12, scope: !50)
+!53 = !DILocation(line: 12, column: 27, scope: !51)
+!54 = !DILocation(line: 12, column: 21, scope: !51)
+!55 = distinct !{!55, !40, !56}
+!56 = !DILocation(line: 14, column: 3, scope: !25)




More information about the llvm-commits mailing list