summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp6
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp38
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h15
-rw-r--r--llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll66
-rw-r--r--llvm/test/DebugInfo/X86/float_const_loclist.ll86
5 files changed, 127 insertions, 84 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 1043d0a1435..296a799d33c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1438,10 +1438,10 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
DwarfExpr.AddMachineRegExpression(Expr, Loc.getReg(),
PieceOffsetInBits);
}
+ } else if (Value.isConstantFP()) {
+ APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
+ DwarfExpr.AddUnsignedConstant(RawBytes);
}
- // else ... ignore constant fp. There is not any good way to
- // to represent them here in dwarf.
- // FIXME: ^
}
void DebugLocEntry::finalize(const AsmPrinter &AP,
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 7b5b831da16..0608e05edd5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -159,29 +159,37 @@ bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
return CurPos > PieceOffsetInBits;
}
+void DwarfExpression::AddStackValue() {
+ if (DwarfVersion >= 4)
+ EmitOp(dwarf::DW_OP_stack_value);
+}
+
void DwarfExpression::AddSignedConstant(int Value) {
EmitOp(dwarf::DW_OP_consts);
EmitSigned(Value);
- // The proper way to describe a constant value is
- // DW_OP_constu <const>, DW_OP_stack_value.
- // Unfortunately, DW_OP_stack_value was not available until DWARF-4,
- // so we will continue to generate DW_OP_constu <const> for DWARF-2
- // and DWARF-3. Technically, this is incorrect since DW_OP_const <const>
- // actually describes a value at a constant addess, not a constant value.
- // However, in the past there was no better way to describe a constant
- // value, so the producers and consumers started to rely on heuristics
- // to disambiguate the value vs. location status of the expression.
- // See PR21176 for more details.
- if (DwarfVersion >= 4)
- EmitOp(dwarf::DW_OP_stack_value);
+ AddStackValue();
}
void DwarfExpression::AddUnsignedConstant(unsigned Value) {
EmitOp(dwarf::DW_OP_constu);
EmitUnsigned(Value);
- // cf. comment in DwarfExpression::AddSignedConstant().
- if (DwarfVersion >= 4)
- EmitOp(dwarf::DW_OP_stack_value);
+ AddStackValue();
+}
+
+void DwarfExpression::AddUnsignedConstant(APInt Value) {
+ unsigned Size = Value.getBitWidth();
+ const uint64_t *Data = Value.getRawData();
+
+ // Chop it up into 64-bit pieces, because that's the maximum that
+ // AddUnsignedConstant takes.
+ unsigned Offset = 0;
+ while (Offset < Size) {
+ AddUnsignedConstant(*Data++);
+ if (Offset == 0 && Size <= 64)
+ break;
+ AddOpPiece(std::min(Size-Offset, 64u), Offset);
+ Offset += 64;
+ }
}
static unsigned getOffsetOrZero(unsigned OffsetInBits,
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 78ec937a6b6..5de9131d5c4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -61,6 +61,19 @@ public:
void AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits = 0);
/// Emit a shift-right dwarf expression.
void AddShr(unsigned ShiftBy);
+ /// Emit a DW_OP_stack_value, if supported.
+ ///
+ /// The proper way to describe a constant value is
+ /// DW_OP_constu <const>, DW_OP_stack_value.
+ /// Unfortunately, DW_OP_stack_value was not available until DWARF-4,
+ /// so we will continue to generate DW_OP_constu <const> for DWARF-2
+ /// and DWARF-3. Technically, this is incorrect since DW_OP_const <const>
+ /// actually describes a value at a constant addess, not a constant value.
+ /// However, in the past there was no better way to describe a constant
+ /// value, so the producers and consumers started to rely on heuristics
+ /// to disambiguate the value vs. location status of the expression.
+ /// See PR21176 for more details.
+ void AddStackValue();
/// Emit an indirect dwarf register operation for the given machine register.
/// \return false if no DWARF register exists for MachineReg.
@@ -87,6 +100,8 @@ public:
void AddSignedConstant(int Value);
/// Emit an unsigned constant.
void AddUnsignedConstant(unsigned Value);
+ /// Emit an unsigned constant.
+ void AddUnsignedConstant(APInt Value);
/// \brief Emit an entire expression on top of a machine register location.
///
diff --git a/llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll b/llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll
deleted file mode 100644
index c26d8aea2d1..00000000000
--- a/llvm/test/DebugInfo/X86/debug-loc-empty-entries.ll
+++ /dev/null
@@ -1,66 +0,0 @@
-; RUN: llc -mtriple=x86_64-apple-macosx <%s | FileCheck %s
-; Test that we don't generate empty .debug_loc entries. Originally, there were
-; two empty .debug_loc entries for 'a' in an otherwise empty .debug_loc list.
-;
-; CHECK: .section __DWARF,__debug_loc,regular,debug
-; CHECK-NEXT: Lsection_debug_loc:
-; CHECK-NEXT: .section __DWARF,__debug_abbrev,regular,debug
-;
-; Test that the variable stuck around.
-; CHECK: .section __DWARF,__debug_info,regular,debug
-; CHECK: DW_TAG_variable
-; CHECK-NOT: DW_AT_location
-
-; Generated using clang -cc1 with the following args:
-;
-; -triple x86_64-apple-macosx -emit-llvm -gdwarf-4 -O1
-;
-; From this testcase:
-;
-;; void fn1() {
-;; float a = 1;
-;; for (;;)
-;; a = 0;
-;; }
-
-; Function Attrs: noreturn nounwind readnone
-define void @_Z3fn1v() #0 !dbg !4 {
-entry:
- tail call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0, metadata !9, metadata !14), !dbg !15
- br label %for.cond, !dbg !16
-
-for.cond: ; preds = %for.cond, %entry
- tail call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !9, metadata !14), !dbg !15
- br label %for.cond, !dbg !17
-}
-
-; Function Attrs: nounwind readnone
-declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
-
-attributes #0 = { noreturn nounwind readnone "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { nounwind readnone }
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!11, !12}
-!llvm.ident = !{!13}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.7.0 (trunk 238517) (llvm/trunk 238524)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, subprograms: !3, globals: !2, imports: !2)
-!1 = !DIFile(filename: "<stdin>", directory: "/Users/dexonsmith/data/llvm/bootstrap/play/delta2/testcase")
-!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "fn1", linkageName: "_Z3fn1v", scope: !5, file: !5, line: 1, type: !6, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, variables: !8)
-!5 = !DIFile(filename: "t.cpp", directory: "/Users/dexonsmith/data/llvm/bootstrap/play/delta2/testcase")
-!6 = !DISubroutineType(types: !7)
-!7 = !{null}
-!8 = !{!9}
-!9 = !DILocalVariable(name: "a", scope: !4, file: !5, line: 2, type: !10)
-!10 = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float)
-!11 = !{i32 2, !"Dwarf Version", i32 4}
-!12 = !{i32 2, !"Debug Info Version", i32 3}
-!13 = !{!"clang version 3.7.0 (trunk 238517) (llvm/trunk 238524)"}
-!14 = !DIExpression()
-!15 = !DILocation(line: 2, scope: !4)
-!16 = !DILocation(line: 3, scope: !4)
-!17 = !DILocation(line: 3, scope: !18)
-!18 = distinct !DILexicalBlock(scope: !19, file: !5, line: 3)
-!19 = distinct !DILexicalBlock(scope: !4, file: !5, line: 3)
diff --git a/llvm/test/DebugInfo/X86/float_const_loclist.ll b/llvm/test/DebugInfo/X86/float_const_loclist.ll
new file mode 100644
index 00000000000..eb531178d21
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/float_const_loclist.ll
@@ -0,0 +1,86 @@
+; RUN: llc %s -stop-after=livedebugvalues -o %t 2>&1 | FileCheck --check-prefix=SANITY %s
+; RUN: llc < %s -filetype=obj | llvm-dwarfdump - | FileCheck %s
+; Test debug_loc support for floating point constants.
+;
+; Created from clang -O1:
+; void barrier();
+; void foo() {
+; float f;
+; long double ld;
+; barrier();
+; f = 3.14;
+; ld = 3.14;
+; barrier();
+; }
+;
+; SANITY: CALL{{.*}} @barrier
+; SANITY: DBG_VALUE x86_fp80 0xK4000C8F5C28F5C28F800
+; SANITY: DBG_VALUE float 0x40091EB860000000
+; SANITY: TAILJMP{{.*}} @barrier
+;
+; CHECK: .debug_info contents:
+; CHECK: DW_TAG_variable
+; CHECK-NEXT: DW_AT_location {{.*}} (0x00000000)
+; CHECK-NEXT: DW_AT_name {{.*}}"ld"
+; CHECK: DW_TAG_variable
+; CHECK-NEXT: DW_AT_location {{.*}} (0x00000031)
+; CHECK-NEXT: DW_AT_name {{.*}}"f"
+;
+; CHECK: .debug_loc contents:
+; CHECK: 0x00000000: Beginning address offset: [[START:.*]]
+; CHECK: Ending address offset: [[END:.*]]
+; CHECK: Location description: 10 80 f0 a3 e1 05 93 08 10 80 80 01 9d 10 40
+; constu ..., piece 8, constu ..., bit-piece 16 64
+; CHECK: 0x00000031: Beginning address offset: [[START]]
+; CHECK: Ending address offset: [[END]]
+; CHECK: Location description: 10 c3 eb a3 82 04
+; constu ...
+source_filename = "test.c"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.11.0"
+
+; Function Attrs: nounwind ssp uwtable
+define void @foo() #0 !dbg !4 {
+entry:
+ tail call void (...) @barrier() #3, !dbg !16
+ tail call void @llvm.dbg.value(metadata float 0x40091EB860000000, i64 0, metadata !8, metadata !17), !dbg !18
+ tail call void @llvm.dbg.value(metadata x86_fp80 0xK4000C8F5C28F5C28F800, i64 0, metadata !10, metadata !17), !dbg !19
+ tail call void (...) @barrier() #3, !dbg !20
+ ret void, !dbg !21
+}
+
+declare void @barrier(...)
+
+; Function Attrs: nounwind readnone
+declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2
+
+attributes #0 = { nounwind ssp uwtable }
+attributes #2 = { nounwind readnone }
+attributes #3 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, subprograms: !3)
+!1 = !DIFile(filename: "test.c", directory: "/Volumes/Data/radar/25448338")
+!2 = !{}
+!3 = !{!4}
+!4 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 4, isOptimized: true, variables: !7)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null}
+!7 = !{!8, !10}
+!8 = !DILocalVariable(name: "f", scope: !4, file: !1, line: 5, type: !9)
+!9 = !DIBasicType(name: "float", size: 32, align: 32, encoding: DW_ATE_float)
+!10 = !DILocalVariable(name: "ld", scope: !4, file: !1, line: 6, type: !11)
+!11 = !DIBasicType(name: "long double", size: 128, align: 128, encoding: DW_ATE_float)
+!12 = !{i32 2, !"Dwarf Version", i32 2}
+!13 = !{i32 2, !"Debug Info Version", i32 3}
+!14 = !{i32 1, !"PIC Level", i32 2}
+!15 = !{!"clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)"}
+!16 = !DILocation(line: 7, column: 3, scope: !4)
+!17 = !DIExpression()
+!18 = !DILocation(line: 5, column: 9, scope: !4)
+!19 = !DILocation(line: 6, column: 15, scope: !4)
+!20 = !DILocation(line: 10, column: 3, scope: !4)
+!21 = !DILocation(line: 11, column: 1, scope: !4)
OpenPOWER on IntegriCloud