Clean up the processing of dbg.value in various places
authorKeno Fischer <kfischer@college.harvard.edu>
Sat, 19 Dec 2015 02:02:44 +0000 (02:02 +0000)
committerKeno Fischer <kfischer@college.harvard.edu>
Sat, 19 Dec 2015 02:02:44 +0000 (02:02 +0000)
Summary:
First up is instcombine, where in the dbg.declare -> dbg.value conversion,
the llvm.dbg.value needs to be called on the actual loaded value, rather
than the address (since the whole point of this transformation is to be
able to get rid of the alloca). Further, now that that's cleaned up, we
can remove a hack in the backend, that would add an implicit OP_deref if
the argument to dbg.value was an alloca. This stems from before the
existence of DIExpression and is no longer necessary since the deref can
be expressed explicitly.

Now, in order to make sure that the tests pass with this change, we need to
correct the printing of DEBUG_VALUE comments to take into account the
expression, which wasn't taken into account before.

Unfortunately, for both these changes, there were a number of incorrect
test cases (mostly the wrong number of DW_OP_derefs, but also a couple
where the test itself was broken more badly). aprantl and I have gone
through and adjusted these test case in order to make them pass with
these fixes and in some cases to make sure they're actually testing
what they are meant to test.

Reviewers: aprantl

Subscribers: dsanders

Differential Revision: http://reviews.llvm.org/D14186

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256077 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/Transforms/Utils/Local.cpp
test/CodeGen/ARM/debug-info-blocks.ll
test/DebugInfo/AArch64/coalescing.ll
test/DebugInfo/Mips/dsr-fixed-objects.ll
test/DebugInfo/X86/array.ll
test/DebugInfo/X86/dbg-value-const-byref.ll
test/DebugInfo/X86/debug-loc-asan.ll
test/DebugInfo/X86/op_deref.ll
test/DebugInfo/X86/reference-argument.ll
test/DebugInfo/X86/vla.ll
test/Transforms/Util/simplify-dbg-declare-load.ll [new file with mode: 0644]

index f1f3547750b4ca5836abd6684f1e029c91e9cda0..9132b8e15237473ed0e11e05a000cb7479120f8f 100644 (file)
@@ -775,6 +775,28 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
   int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0;
 
   bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
   int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0;
 
+  for (unsigned i = 0; i < Expr->getNumElements(); ++i) {
+    if (Deref) {
+      // We currently don't support extra Offsets or derefs after the first
+      // one. Bail out early instead of emitting an incorrect comment
+      OS << " [complex expression]";
+      AP.OutStreamer->emitRawComment(OS.str());
+      return true;
+    }
+    uint64_t Op = Expr->getElement(i);
+    if (Op == dwarf::DW_OP_deref) {
+      Deref = true;
+      continue;
+    }
+    uint64_t ExtraOffset = Expr->getElement(i++);
+    if (Op == dwarf::DW_OP_plus)
+      Offset += ExtraOffset;
+    else {
+      assert(Op == dwarf::DW_OP_minus);
+      Offset -= ExtraOffset;
+    }
+  }
+
   // Register or immediate value. Register 0 means undef.
   if (MI->getOperand(0).isFPImm()) {
     APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
   // Register or immediate value. Register 0 means undef.
   if (MI->getOperand(0).isFPImm()) {
     APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
index 885997e2d0e4b4f7a19eaa754e49a4437a01e1da..544c7e7631d9ef4482168c5395fbe1581d464a53 100644 (file)
@@ -950,14 +950,12 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
     assert(Variable->isValidLocationForIntrinsic(dl) &&
            "Expected inlined-at fields to agree");
     uint64_t Offset = DI->getOffset();
     assert(Variable->isValidLocationForIntrinsic(dl) &&
            "Expected inlined-at fields to agree");
     uint64_t Offset = DI->getOffset();
-    // A dbg.value for an alloca is always indirect.
-    bool IsIndirect = isa<AllocaInst>(V) || Offset != 0;
     SDDbgValue *SDV;
     if (Val.getNode()) {
     SDDbgValue *SDV;
     if (Val.getNode()) {
-      if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, Offset, IsIndirect,
+      if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, Offset, false,
                                     Val)) {
         SDV = DAG.getDbgValue(Variable, Expr, Val.getNode(), Val.getResNo(),
                                     Val)) {
         SDV = DAG.getDbgValue(Variable, Expr, Val.getNode(), Val.getResNo(),
-                              IsIndirect, Offset, dl, DbgSDNodeOrder);
+                              false, Offset, dl, DbgSDNodeOrder);
         DAG.AddDbgValue(SDV, Val.getNode(), false);
       }
     } else
         DAG.AddDbgValue(SDV, Val.getNode(), false);
       }
     } else
@@ -4515,12 +4513,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
         // Check unused arguments map.
         N = UnusedArgNodeMap[V];
       if (N.getNode()) {
         // Check unused arguments map.
         N = UnusedArgNodeMap[V];
       if (N.getNode()) {
-        // A dbg.value for an alloca is always indirect.
-        bool IsIndirect = isa<AllocaInst>(V) || Offset != 0;
         if (!EmitFuncArgumentDbgValue(V, Variable, Expression, dl, Offset,
         if (!EmitFuncArgumentDbgValue(V, Variable, Expression, dl, Offset,
-                                      IsIndirect, N)) {
+                                      false, N)) {
           SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(),
           SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(),
-                                IsIndirect, Offset, dl, SDNodeOrder);
+                                false, Offset, dl, SDNodeOrder);
           DAG.AddDbgValue(SDV, N.getNode(), false);
         }
       } else if (!V->use_empty() ) {
           DAG.AddDbgValue(SDV, N.getNode(), false);
         }
       } else if (!V->use_empty() ) {
index 31039816e14a957d3d41ce6dd7cbb0eb5b3202f8..e75163f323df79e48cb7df676e0c48d96764ec05 100644 (file)
@@ -1071,8 +1071,13 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
   if (LdStHasDebugValue(DIVar, LI))
     return true;
 
   if (LdStHasDebugValue(DIVar, LI))
     return true;
 
-  Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0, DIVar, DIExpr,
-                                  DDI->getDebugLoc(), LI);
+  // We are now tracking the loaded value instead of the address. In the
+  // future if multi-location support is added to the IR, it might be
+  // preferable to keep tracking both the loaded value and the original
+  // address in case the alloca can not be elided.
+  Instruction *DbgValue = Builder.insertDbgValueIntrinsic(
+      LI, 0, DIVar, DIExpr, DDI->getDebugLoc(), (Instruction *)nullptr);
+  DbgValue->insertAfter(LI);
   return true;
 }
 
   return true;
 }
 
@@ -1114,9 +1119,13 @@ bool llvm::LowerDbgDeclare(Function &F) {
           // This is a call by-value or some other instruction that
           // takes a pointer to the variable. Insert a *value*
           // intrinsic that describes the alloca.
           // This is a call by-value or some other instruction that
           // takes a pointer to the variable. Insert a *value*
           // intrinsic that describes the alloca.
+          SmallVector<uint64_t, 1> NewDIExpr;
+          auto *DIExpr = DDI->getExpression();
+          NewDIExpr.push_back(dwarf::DW_OP_deref);
+          NewDIExpr.append(DIExpr->elements_begin(), DIExpr->elements_end());
           DIB.insertDbgValueIntrinsic(AI, 0, DDI->getVariable(),
           DIB.insertDbgValueIntrinsic(AI, 0, DDI->getVariable(),
-                                      DDI->getExpression(), DDI->getDebugLoc(),
-                                      CI);
+                                      DIB.createExpression(NewDIExpr),
+                                      DDI->getDebugLoc(), CI);
         }
       DDI->eraseFromParent();
     }
         }
       DDI->eraseFromParent();
     }
index 2a8898651f0de3de2bc87dfbc858a25cd71d0617..e0bc84963f23f790c415878db704e0c8ddf1dd70 100644 (file)
@@ -1,5 +1,21 @@
-; RUN: llc -O0 < %s | FileCheck %s
-; CHECK: @DEBUG_VALUE: foobar_func_block_invoke_0:mydata <- [%SP+{{[0-9]+}}]
+; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump  - | FileCheck %s
+
+; debug_info content
+; CHECK: DW_AT_name {{.*}} "foobar_func_block_invoke_0"
+; CHECK-NOT: DW_TAG_subprogram
+; CHECK: DW_TAG_variable
+; CHECK-NOT: DW_TAG
+; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset]      ([[MYDATA_LOC:0x[0-9a-f]*]])
+; CHECK-NEXT: DW_AT_name {{.*}} "mydata"
+
+; debug_loc content
+; CHECK: .debug_loc contents:
+; CHECK: [[MYDATA_LOC]]: Beginning address offset: {{.*}}
+; CHECK-NOT: {{0x[0-9a-f]*}}: Beginning address offset
+; CHECK: Location description: {{.*}} 23 04 06 23 18
+; CHECK-NOT: {{0x[0-9a-f]*}}: Beginning address offset
+; CHECK: Location description: {{.*}} 23 04 06 23 18
+
 ; Radar 9331779
 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
 target triple = "thumbv7-apple-ios"
 ; Radar 9331779
 target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
 target triple = "thumbv7-apple-ios"
index 79b40dd27c8b387eea3a09947b131698e86c7ffb..5f69895c7363286c1f6254ff21cd61351d2d6523 100644 (file)
@@ -60,6 +60,6 @@ attributes #3 = { nounwind optsize }
 !13 = !{i32 2, !"Debug Info Version", i32 3}
 !14 = !{!"clang version 3.6.0 (trunk 223149) (llvm/trunk 223115)"}
 !15 = !DILocation(line: 5, column: 3, scope: !4)
 !13 = !{i32 2, !"Debug Info Version", i32 3}
 !14 = !{!"clang version 3.6.0 (trunk 223149) (llvm/trunk 223115)"}
 !15 = !DILocation(line: 5, column: 3, scope: !4)
-!16 = !DIExpression()
+!16 = !DIExpression(DW_OP_deref)
 !17 = !DILocation(line: 4, column: 12, scope: !4)
 !18 = !DILocation(line: 8, column: 1, scope: !4)
 !17 = !DILocation(line: 4, column: 12, scope: !4)
 !18 = !DILocation(line: 8, column: 1, scope: !4)
index 9460f89baaabedc480a6ed7730d33c28cef5b36c..ee98272859a77c706fccfa918e1490ee864db3b3 100644 (file)
@@ -33,18 +33,18 @@ declare void @foo(i32*)
 define i32 @f0(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e) !dbg !4 {
 entry:
   %x = alloca i32, align 4
 define i32 @f0(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e) !dbg !4 {
 entry:
   %x = alloca i32, align 4
-  tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !9, metadata !26), !dbg !27
-  tail call void @llvm.dbg.value(metadata i32 %b, i64 0, metadata !10, metadata !26), !dbg !28
-  tail call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !11, metadata !26), !dbg !29
-  tail call void @llvm.dbg.value(metadata i32 %d, i64 0, metadata !12, metadata !26), !dbg !30
-  tail call void @llvm.dbg.value(metadata i32 %e, i64 0, metadata !13, metadata !26), !dbg !31
+  tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !9,  metadata !DIExpression()), !dbg !27
+  tail call void @llvm.dbg.value(metadata i32 %b, i64 0, metadata !10, metadata !DIExpression()), !dbg !28
+  tail call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !11, metadata !DIExpression()), !dbg !29
+  tail call void @llvm.dbg.value(metadata i32 %d, i64 0, metadata !12, metadata !DIExpression()), !dbg !30
+  tail call void @llvm.dbg.value(metadata i32 %e, i64 0, metadata !13, metadata !DIExpression()), !dbg !31
   %0 = bitcast i32* %x to i8*, !dbg !32
   call void @llvm.lifetime.start(i64 4, i8* %0) #4, !dbg !32
   %add = add nsw i32 %b, %a, !dbg !33
   %add1 = add nsw i32 %add, %c, !dbg !34
   %add2 = add nsw i32 %add1, %d, !dbg !35
   %add3 = add nsw i32 %add2, %e, !dbg !36
   %0 = bitcast i32* %x to i8*, !dbg !32
   call void @llvm.lifetime.start(i64 4, i8* %0) #4, !dbg !32
   %add = add nsw i32 %b, %a, !dbg !33
   %add1 = add nsw i32 %add, %c, !dbg !34
   %add2 = add nsw i32 %add1, %d, !dbg !35
   %add3 = add nsw i32 %add2, %e, !dbg !36
-  tail call void @llvm.dbg.value(metadata i32 %add3, i64 0, metadata !14, metadata !26), !dbg !37
+  tail call void @llvm.dbg.value(metadata i32 %add3, i64 0, metadata !14, metadata !DIExpression()), !dbg !37
   store i32 %add3, i32* %x, align 4, !dbg !37, !tbaa !38
   tail call void @llvm.dbg.value(metadata i32* %x, i64 0, metadata !14, metadata !26), !dbg !37
   call void @foo(i32* nonnull %x) #4, !dbg !42
   store i32 %add3, i32* %x, align 4, !dbg !37, !tbaa !38
   tail call void @llvm.dbg.value(metadata i32* %x, i64 0, metadata !14, metadata !26), !dbg !37
   call void @foo(i32* nonnull %x) #4, !dbg !42
@@ -66,18 +66,18 @@ entry:
 define i32 @f1(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e) !dbg !15 {
 entry:
   %x = alloca i32, align 16
 define i32 @f1(i32 signext %a, i32 signext %b, i32 signext %c, i32 signext %d, i32 signext %e) !dbg !15 {
 entry:
   %x = alloca i32, align 16
-  tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !17, metadata !26), !dbg !46
-  tail call void @llvm.dbg.value(metadata i32 %b, i64 0, metadata !18, metadata !26), !dbg !47
-  tail call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !19, metadata !26), !dbg !48
-  tail call void @llvm.dbg.value(metadata i32 %d, i64 0, metadata !20, metadata !26), !dbg !49
-  tail call void @llvm.dbg.value(metadata i32 %e, i64 0, metadata !21, metadata !26), !dbg !50
+  tail call void @llvm.dbg.value(metadata i32 %a, i64 0, metadata !17, metadata !DIExpression()), !dbg !46
+  tail call void @llvm.dbg.value(metadata i32 %b, i64 0, metadata !18, metadata !DIExpression()), !dbg !47
+  tail call void @llvm.dbg.value(metadata i32 %c, i64 0, metadata !19, metadata !DIExpression()), !dbg !48
+  tail call void @llvm.dbg.value(metadata i32 %d, i64 0, metadata !20, metadata !DIExpression()), !dbg !49
+  tail call void @llvm.dbg.value(metadata i32 %e, i64 0, metadata !21, metadata !DIExpression()), !dbg !50
   %0 = bitcast i32* %x to i8*, !dbg !51
   call void @llvm.lifetime.start(i64 4, i8* %0) #4, !dbg !51
   %add = add nsw i32 %b, %a, !dbg !52
   %add1 = add nsw i32 %add, %c, !dbg !53
   %add2 = add nsw i32 %add1, %d, !dbg !54
   %add3 = add nsw i32 %add2, %e, !dbg !55
   %0 = bitcast i32* %x to i8*, !dbg !51
   call void @llvm.lifetime.start(i64 4, i8* %0) #4, !dbg !51
   %add = add nsw i32 %b, %a, !dbg !52
   %add1 = add nsw i32 %add, %c, !dbg !53
   %add2 = add nsw i32 %add1, %d, !dbg !54
   %add3 = add nsw i32 %add2, %e, !dbg !55
-  tail call void @llvm.dbg.value(metadata i32 %add3, i64 0, metadata !22, metadata !26), !dbg !56
+  tail call void @llvm.dbg.value(metadata i32 %add3, i64 0, metadata !22, metadata !DIExpression()), !dbg !56
   store i32 %add3, i32* %x, align 16, !dbg !56, !tbaa !38
   tail call void @llvm.dbg.value(metadata i32* %x, i64 0, metadata !22, metadata !26), !dbg !56
   call void @foo(i32* nonnull %x) #4, !dbg !57
   store i32 %add3, i32* %x, align 16, !dbg !56, !tbaa !38
   tail call void @llvm.dbg.value(metadata i32* %x, i64 0, metadata !22, metadata !26), !dbg !56
   call void @foo(i32* nonnull %x) #4, !dbg !57
@@ -119,7 +119,7 @@ declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
 !23 = !{i32 2, !"Dwarf Version", i32 4}
 !24 = !{i32 2, !"Debug Info Version", i32 3}
 !25 = !{!"clang version 3.8.0 (trunk 251783) (llvm/trunk 251781)"}
 !23 = !{i32 2, !"Dwarf Version", i32 4}
 !24 = !{i32 2, !"Debug Info Version", i32 3}
 !25 = !{!"clang version 3.8.0 (trunk 251783) (llvm/trunk 251781)"}
-!26 = !DIExpression()
+!26 = !DIExpression(DW_OP_deref)
 !27 = !DILocation(line: 4, column: 12, scope: !4)
 !28 = !DILocation(line: 4, column: 19, scope: !4)
 !29 = !DILocation(line: 4, column: 26, scope: !4)
 !27 = !DILocation(line: 4, column: 12, scope: !4)
 !28 = !DILocation(line: 4, column: 19, scope: !4)
 !29 = !DILocation(line: 4, column: 26, scope: !4)
index 2d2a8fb86639a6e8bb1f46f407fa8de189dd05d0..4ffe0a710b85a49f2105c575406b591137825220 100644 (file)
@@ -37,13 +37,13 @@ define i32 @main(i32 %argc, i8** nocapture readnone %argv) #0 !dbg !12 {
   %array = alloca [4 x i32], align 16
   tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !19, metadata !DIExpression()), !dbg !35
   tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !20, metadata !DIExpression()), !dbg !35
   %array = alloca [4 x i32], align 16
   tail call void @llvm.dbg.value(metadata i32 %argc, i64 0, metadata !19, metadata !DIExpression()), !dbg !35
   tail call void @llvm.dbg.value(metadata i8** %argv, i64 0, metadata !20, metadata !DIExpression()), !dbg !35
-  tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression()), !dbg !36
+  tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression(DW_OP_deref)), !dbg !36
   %1 = bitcast [4 x i32]* %array to i8*, !dbg !36
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([4 x i32]* @main.array to i8*), i64 16, i32 16, i1 false), !dbg !36
   %1 = bitcast [4 x i32]* %array to i8*, !dbg !36
   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* bitcast ([4 x i32]* @main.array to i8*), i64 16, i32 16, i1 false), !dbg !36
-  tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression()), !dbg !36
+  tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression(DW_OP_deref)), !dbg !36
   %2 = getelementptr inbounds [4 x i32], [4 x i32]* %array, i64 0, i64 0, !dbg !37
   call void @f(i32* %2), !dbg !37
   %2 = getelementptr inbounds [4 x i32], [4 x i32]* %array, i64 0, i64 0, !dbg !37
   call void @f(i32* %2), !dbg !37
-  tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression()), !dbg !36
+  tail call void @llvm.dbg.value(metadata [4 x i32]* %array, i64 0, metadata !21, metadata !DIExpression(DW_OP_deref)), !dbg !36
   %3 = load i32, i32* %2, align 16, !dbg !38, !tbaa !30
   ret i32 %3, !dbg !38
 }
   %3 = load i32, i32* %2, align 16, !dbg !38, !tbaa !30
   ret i32 %3, !dbg !38
 }
index e231da876b41c9909b6ac975145b44fa17bdc2f9..2b4c1dc1a9374c48cc46de9905b781927920728c 100644 (file)
@@ -56,7 +56,7 @@ entry:
   %call1 = call i32 (...) @f1() #3, !dbg !19
   call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !10, metadata !DIExpression()), !dbg !19
   store i32 %call1, i32* %i, align 4, !dbg !19, !tbaa !20
   %call1 = call i32 (...) @f1() #3, !dbg !19
   call void @llvm.dbg.value(metadata i32 %call1, i64 0, metadata !10, metadata !DIExpression()), !dbg !19
   store i32 %call1, i32* %i, align 4, !dbg !19, !tbaa !20
-  call void @llvm.dbg.value(metadata i32* %i, i64 0, metadata !10, metadata !DIExpression()), !dbg !24
+  call void @llvm.dbg.value(metadata i32* %i, i64 0, metadata !10, metadata !DIExpression(DW_OP_deref)), !dbg !24
   call void @f2(i32* %i) #3, !dbg !24
   ret i32 0, !dbg !25
 }
   call void @f2(i32* %i) #3, !dbg !24
   ret i32 0, !dbg !25
 }
index d1131379f56677993782e96756151240e246dcf1..2e0135574496621f5829eda1b6bd033244b979bf 100644 (file)
@@ -7,15 +7,14 @@
 ; int bar(int y) {
 ;   return y + 2;
 ; }
 ; int bar(int y) {
 ;   return y + 2;
 ; }
-; with "clang++ -S -emit-llvm -fsanitize=address -O0 -g test.cc"
+; with "clang++ -S -emit-llvm -mllvm -asan-skip-promotable-allocas=0 -fsanitize=address -O0 -g test.cc"
 
 
-; First, argument variable "y" resides in %rdi:
-; CHECK: DEBUG_VALUE: bar:y <- %RDI
-
-; Then its address is stored in a location on a stack:
+; The address of the (potentially now malloc'ed) alloca ends up
+; in RDI, after which it is spilled to the stack. We record the
+; spill OFFSET on the stack for checking the debug info below.
+; CHECK: #DEBUG_VALUE: bar:y <- [%RDI+0]
 ; CHECK: movq %rdi, [[OFFSET:[0-9]+]](%rsp)
 ; CHECK-NEXT: [[START_LABEL:.Ltmp[0-9]+]]
 ; CHECK: movq %rdi, [[OFFSET:[0-9]+]](%rsp)
 ; CHECK-NEXT: [[START_LABEL:.Ltmp[0-9]+]]
-; CHECK-NEXT: DEBUG_VALUE: bar:y <- [%RSP+[[OFFSET]]]
 ; This location should be valid until the end of the function.
 
 ; CHECK: .Ldebug_loc{{[0-9]+}}:
 ; This location should be valid until the end of the function.
 
 ; CHECK: .Ldebug_loc{{[0-9]+}}:
index 621d3f5f7f1b66a99a919f90de24d41cd885fc80..535c7390a54c1a5c1b0442ac8ee67acf5b1017a7 100644 (file)
 ; right now, so we check the asm output:
 ; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK
 ; vla should have a register-indirect address at one point.
 ; right now, so we check the asm output:
 ; RUN: llc -O0 -mtriple=x86_64-apple-darwin %s -o - -filetype=asm | FileCheck %s -check-prefix=ASM-CHECK
 ; vla should have a register-indirect address at one point.
-; ASM-CHECK: DEBUG_VALUE: vla <- %RCX
+; ASM-CHECK: DEBUG_VALUE: vla <- [%RCX+0]
 ; ASM-CHECK: DW_OP_breg2
 
 ; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s --check-prefix=PRETTY-PRINT
 ; ASM-CHECK: DW_OP_breg2
 
 ; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s --check-prefix=PRETTY-PRINT
-; PRETTY-PRINT: DIExpression(DW_OP_deref, DW_OP_deref)
+; PRETTY-PRINT: DIExpression(DW_OP_deref)
 
 define void @testVLAwithSize(i32 %s) nounwind uwtable ssp !dbg !5 {
 entry:
 
 define void @testVLAwithSize(i32 %s) nounwind uwtable ssp !dbg !5 {
 entry:
@@ -108,4 +108,4 @@ declare void @llvm.stackrestore(i8*) nounwind
 !27 = !DILocation(line: 8, column: 1, scope: !13)
 !28 = !DIFile(filename: "bar.c", directory: "/Users/echristo/tmp")
 !29 = !{i32 1, !"Debug Info Version", i32 3}
 !27 = !DILocation(line: 8, column: 1, scope: !13)
 !28 = !DIFile(filename: "bar.c", directory: "/Users/echristo/tmp")
 !29 = !{i32 1, !"Debug Info Version", i32 3}
-!30 = !DIExpression(DW_OP_deref, DW_OP_deref)
+!30 = !DIExpression(DW_OP_deref)
index 0df6ff3edab19af13d1b319b1f87f73eb09714eb..9433b8785311d16eefa27f01dcafa39b01de82ad 100644 (file)
@@ -22,6 +22,7 @@ target triple = "x86_64-apple-macosx10.9.0"
 
 declare void @_Z3barR4SVal(%class.SVal* %v)
 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
 
 declare void @_Z3barR4SVal(%class.SVal* %v)
 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
 declare i32 @main()
 ; Function Attrs: nounwind ssp uwtable
 define linkonce_odr void @_ZN1A3fooE4SVal(%class.A* %this, %class.SVal* %v) nounwind ssp uwtable align 2 !dbg !35 {
 declare i32 @main()
 ; Function Attrs: nounwind ssp uwtable
 define linkonce_odr void @_ZN1A3fooE4SVal(%class.A* %this, %class.SVal* %v) nounwind ssp uwtable align 2 !dbg !35 {
@@ -29,7 +30,7 @@ entry:
   %this.addr = alloca %class.A*, align 8
   store %class.A* %this, %class.A** %this.addr, align 8
   call void @llvm.dbg.declare(metadata %class.A** %this.addr, metadata !59, metadata !DIExpression()), !dbg !61
   %this.addr = alloca %class.A*, align 8
   store %class.A* %this, %class.A** %this.addr, align 8
   call void @llvm.dbg.declare(metadata %class.A** %this.addr, metadata !59, metadata !DIExpression()), !dbg !61
-  call void @llvm.dbg.declare(metadata %class.SVal* %v, metadata !62, metadata !DIExpression(DW_OP_deref)), !dbg !61
+  call void @llvm.dbg.value(metadata %class.SVal* %v, i64 0, metadata !62, metadata !DIExpression(DW_OP_deref)), !dbg !61
   %this1 = load %class.A*, %class.A** %this.addr
   call void @_Z3barR4SVal(%class.SVal* %v), !dbg !61
   ret void, !dbg !61
   %this1 = load %class.A*, %class.A** %this.addr
   call void @_Z3barR4SVal(%class.SVal* %v), !dbg !61
   ret void, !dbg !61
index f3f4d9910027ebb7b5f006c016e021e30ec808c0..5a25f021894ea9d2b9286c456781cda9c52109a2 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=asm %s -o - | FileCheck %s
 ; Ensure that we generate an indirect location for the variable length array a.
 ; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=asm %s -o - | FileCheck %s
 ; Ensure that we generate an indirect location for the variable length array a.
-; CHECK: ##DEBUG_VALUE: vla:a <- %RDX
+; CHECK: ##DEBUG_VALUE: vla:a <- [%RDX+0]
 ; CHECK: DW_OP_breg1
 ; rdar://problem/13658587
 ;
 ; CHECK: DW_OP_breg1
 ; rdar://problem/13658587
 ;
diff --git a/test/Transforms/Util/simplify-dbg-declare-load.ll b/test/Transforms/Util/simplify-dbg-declare-load.ll
new file mode 100644 (file)
index 0000000..0357a5e
--- /dev/null
@@ -0,0 +1,52 @@
+; RUN: opt -instcombine -S < %s | FileCheck %s
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+%foo = type { i64, i32, i32 }
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #0
+
+; Function Attrs: sspreq
+define void @julia_fastshortest_6256() #1 {
+top:
+  %cp = alloca %foo, align 8
+  call void @llvm.dbg.declare(metadata %foo* %cp, metadata !1, metadata !16), !dbg !17
+  br i1 undef, label %idxend, label %fail
+
+fail:                                             ; preds = %top
+  unreachable
+
+idxend:                                           ; preds = %top
+; CHECK-NOT call void @llvm.dbg.value(metadata %foo* %cp, i64 0, metadata !1, metadata !16), !dbg !17
+  %0 = load volatile %foo, %foo* %cp, align 8
+; CHECK: call void @llvm.dbg.value(metadata %foo %0, i64 0, metadata !1, metadata !16), !dbg !17
+  store volatile %foo %0, %foo* undef, align 8
+  ret void
+}
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { sspreq }
+
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{}
+
+!0 = !{i32 1, !"Debug Info Version", i32 3}
+!1 = !DILocalVariable(name: "cp", scope: !2, file: !3, line: 106, type: !12)
+!2 = distinct !DISubprogram(name: "fastshortest", linkageName: "julia_fastshortest_6256", scope: null, file: !3, type: !4, isLocal: false, isDefinition: true, isOptimized: true, variables: !11)
+!3 = !DIFile(filename: "grisu/fastshortest.jl", directory: ".")
+!4 = !DISubroutineType(types: !5)
+!5 = !{!6, !7}
+!6 = !DIBasicType(name: "Float64", size: 64, align: 64, encoding: DW_ATE_unsigned)
+!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64, align: 64)
+!8 = !DICompositeType(tag: DW_TAG_structure_type, name: "jl_value_t", file: !9, line: 71, align: 64, elements: !10)
+!9 = !DIFile(filename: "julia.h", directory: "")
+!10 = !{!7}
+!11 = !{}
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "Float", size: 128, align: 64, elements: !13, runtimeLang: DW_LANG_Julia)
+!13 = !{!14, !15, !15}
+!14 = !DIBasicType(name: "UInt64", size: 64, align: 64, encoding: DW_ATE_unsigned)
+!15 = !DIBasicType(name: "Int32", size: 32, align: 32, encoding: DW_ATE_unsigned)
+!16 = !DIExpression()
+!17 = !DILocation(line: 106, scope: !2)