[llvm] ef8992b - Re-apply "[DebugInfo] Emit DW_OP_implicit_value for Floating point constants"

Sourabh Singh Tomar via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 19 13:10:08 PDT 2020


Author: Sourabh Singh Tomar
Date: 2020-08-20T01:39:42+05:30
New Revision: ef8992b9f0189005e0d9e09bd0967301bd7a7cc6

URL: https://github.com/llvm/llvm-project/commit/ef8992b9f0189005e0d9e09bd0967301bd7a7cc6
DIFF: https://github.com/llvm/llvm-project/commit/ef8992b9f0189005e0d9e09bd0967301bd7a7cc6.diff

LOG: Re-apply "[DebugInfo] Emit DW_OP_implicit_value for Floating point constants"

This patch was reverted in 7c182663a857fc87 due to some failures
observed on PCC based machines. Failures were due to Endianness issue and
long double representation issues.

Patch is revised to address Endianness issue. Furthermore, support
for emission of `DW_OP_implicit_value` for `long double` has been removed
(since it was unclean at the moment). Planning to handle this in
a clean way soon!

For more context, please refer to following review link.

Reviewed By: aprantl

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

Added: 
    llvm/test/DebugInfo/X86/implicit_value-double.ll
    llvm/test/DebugInfo/X86/implicit_value-float.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
    llvm/test/DebugInfo/X86/float_const_loclist.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index cee72120accb..0730fff3bcaf 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -2501,8 +2501,21 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
       DwarfExpr.addExpression(std::move(ExprCursor));
       return;
   } else if (Value.isConstantFP()) {
-    APInt RawBytes = Value.getConstantFP()->getValueAPF().bitcastToAPInt();
-    DwarfExpr.addUnsignedConstant(RawBytes);
+    if (AP.getDwarfVersion() >= 4 && AP.getDwarfDebug()->tuneForGDB()) {
+      DwarfExpr.addConstantFP(Value.getConstantFP()->getValueAPF(), AP);
+      return;
+    } else if (Value.getConstantFP()
+                   ->getValueAPF()
+                   .bitcastToAPInt()
+                   .getBitWidth() <= 64 /*bits*/)
+      DwarfExpr.addUnsignedConstant(
+          Value.getConstantFP()->getValueAPF().bitcastToAPInt());
+    else
+      LLVM_DEBUG(
+          dbgs()
+          << "Skipped DwarfExpression creation for ConstantFP of size"
+          << Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth()
+          << " bits\n");
   }
   DwarfExpr.addExpression(std::move(ExprCursor));
 }

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index d4762121d105..4455035d8910 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -17,6 +17,7 @@
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/CodeGen/Register.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
@@ -25,6 +26,8 @@
 
 using namespace llvm;
 
+#define DEBUG_TYPE "dwarfdebug"
+
 void DwarfExpression::emitConstu(uint64_t Value) {
   if (Value < 32)
     emitOp(dwarf::DW_OP_lit0 + Value);
@@ -219,6 +222,31 @@ void DwarfExpression::addUnsignedConstant(const APInt &Value) {
   }
 }
 
+void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
+  assert(isImplicitLocation() || isUnknownLocation());
+  APInt API = APF.bitcastToAPInt();
+  int NumBytes = API.getBitWidth() / 8;
+  if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
+    // FIXME: Add support for `long double`.
+    emitOp(dwarf::DW_OP_implicit_value);
+    emitUnsigned(NumBytes /*Size of the block in bytes*/);
+
+    const uint64_t *Value = API.getRawData();
+    const bool IsLittleEndian = AP.getDataLayout().isLittleEndian();
+    uint64_t Swapped = support::endian::byte_swap(
+        *Value, IsLittleEndian ? support::little : support::big);
+
+    const char *SwappedBytes = reinterpret_cast<const char *>(&Swapped);
+    for (int i = 0; i < NumBytes; ++i)
+      emitData1(SwappedBytes[i]);
+
+    return;
+  }
+  LLVM_DEBUG(
+      dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
+             << API.getBitWidth() << " bits\n");
+}
+
 bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
                                               DIExpressionCursor &ExprCursor,
                                               unsigned MachineReg,

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 757b17511453..78a98a61178f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -299,6 +299,9 @@ class DwarfExpression {
   /// Emit an unsigned constant.
   void addUnsignedConstant(const APInt &Value);
 
+  /// Emit an floating point constant.
+  void addConstantFP(const APFloat &Value, const AsmPrinter &AP);
+
   /// Lock this down to become a memory location description.
   void setMemoryLocationKind() {
     assert(isUnknownLocation());

diff  --git a/llvm/test/DebugInfo/X86/float_const_loclist.ll b/llvm/test/DebugInfo/X86/float_const_loclist.ll
index f9008209e5df..24ee16444836 100644
--- a/llvm/test/DebugInfo/X86/float_const_loclist.ll
+++ b/llvm/test/DebugInfo/X86/float_const_loclist.ll
@@ -20,12 +20,10 @@
 ;
 ; CHECK: .debug_info contents:
 ; CHECK: DW_TAG_variable
-; CHECK-NEXT:  DW_AT_location {{.*}} (
-; CHECK-NEXT:    [0x[[START:.*]], 0x[[END:.*]]): DW_OP_constu 0xc8f5c28f5c28f800, DW_OP_piece 0x8, DW_OP_constu 0x4000, DW_OP_bit_piece 0x10 0x40)
 ; CHECK-NEXT:  DW_AT_name {{.*}}"ld"
 ; CHECK: DW_TAG_variable
 ; CHECK-NEXT:  DW_AT_location {{.*}} (
-; CHECK-NEXT:    [0x[[START]], 0x[[END]]): DW_OP_constu 0x4048f5c3)
+; CHECK-NEXT:    [0x{{.*}}, 0x{{.*}}): DW_OP_constu 0x4048f5c3)
 ; CHECK-NEXT:  DW_AT_name {{.*}}"f"
 
 source_filename = "test.c"

diff  --git a/llvm/test/DebugInfo/X86/implicit_value-double.ll b/llvm/test/DebugInfo/X86/implicit_value-double.ll
new file mode 100644
index 000000000000..3c14c7dfefce
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/implicit_value-double.ll
@@ -0,0 +1,66 @@
+;; This test checks for emission of DW_OP_implicit_value operation
+;; for double type.
+
+; RUN: llc -debugger-tune=gdb -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
+
+; CHECK: .debug_info contents:
+; CHECK: DW_TAG_variable
+; CHECK-NEXT:  DW_AT_location        ({{.*}}
+; CHECK-NEXT:                     [{{.*}}): DW_OP_implicit_value 0x8 0x1f 0x85 0xeb 0x51 0xb8 0x1e 0x09 0x40)
+; CHECK-NEXT:  DW_AT_name    ("d")
+
+;; Generated from: clang -ggdb -O1
+;;int main() {
+;;        double d = 3.14;
+;;        printf("dummy\n");
+;;        d *= d;
+;;        return 0;
+;;}
+
+; ModuleID = 'implicit_value-double.c'
+source_filename = "implicit_value-double.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at str = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
+
+; Function Attrs: nofree nounwind uwtable
+define dso_local i32 @main() local_unnamed_addr #0 !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata double 3.140000e+00, metadata !12, metadata !DIExpression()), !dbg !14
+  %puts = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @str, i64 0, i64 0)), !dbg !15
+  call void @llvm.dbg.value(metadata double undef, metadata !12, metadata !DIExpression()), !dbg !14
+  ret i32 0, !dbg !16
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+; Function Attrs: nofree nounwind
+declare i32 @puts(i8* nocapture readonly) local_unnamed_addr #2
+
+attributes #0 = { nofree nounwind uwtable }
+attributes #1 = { nounwind readnone speculatable willreturn }
+attributes #2 = { nofree nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "implicit_value-double.c", directory: "/home/")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 11.0.0"}
+!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "d", scope: !7, file: !1, line: 2, type: !13)
+!13 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
+!14 = !DILocation(line: 0, scope: !7)
+!15 = !DILocation(line: 3, column: 2, scope: !7)
+!16 = !DILocation(line: 5, column: 2, scope: !7)

diff  --git a/llvm/test/DebugInfo/X86/implicit_value-float.ll b/llvm/test/DebugInfo/X86/implicit_value-float.ll
new file mode 100644
index 000000000000..8c51b4948177
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/implicit_value-float.ll
@@ -0,0 +1,65 @@
+;; This test checks for emission of DW_OP_implicit_value operation
+;; for float type.
+
+; RUN: llc -debugger-tune=gdb -filetype=obj %s -o - | llvm-dwarfdump - | FileCheck %s
+
+; CHECK: .debug_info contents:
+; CHECK: DW_TAG_variable
+; CHECK-NEXT:  DW_AT_location        ({{.*}}
+; CHECK-NEXT:                     [{{.*}}): DW_OP_implicit_value 0x4 0xc3 0xf5 0x48 0x40)
+; CHECK-NEXT:  DW_AT_name    ("f")
+
+;; Generated from: clang -ggdb -O1
+;;int main() {
+;;        float f = 3.14f;
+;;        printf("dummy\n");
+;;        f *= f;
+;;        return 0;
+;;}
+; ModuleID = 'implicit_value-float.c'
+source_filename = "implicit_value-float.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at str = private unnamed_addr constant [6 x i8] c"dummy\00", align 1
+
+; Function Attrs: nofree nounwind uwtable
+define dso_local i32 @main() local_unnamed_addr #0 !dbg !7 {
+entry:
+  call void @llvm.dbg.value(metadata float 0x40091EB860000000, metadata !12, metadata !DIExpression()), !dbg !14
+  %puts = call i32 @puts(i8* nonnull dereferenceable(1) getelementptr inbounds ([6 x i8], [6 x i8]* @str, i64 0, i64 0)), !dbg !15
+  call void @llvm.dbg.value(metadata float undef, metadata !12, metadata !DIExpression()), !dbg !14
+  ret i32 0, !dbg !16
+}
+
+; Function Attrs: nounwind readnone speculatable willreturn
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1
+
+; Function Attrs: nofree nounwind
+declare i32 @puts(i8* nocapture readonly) local_unnamed_addr #2
+
+attributes #0 = { nofree nounwind uwtable }
+attributes #1 = { nounwind readnone speculatable willreturn }
+attributes #2 = { nofree nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "implicit_value-float.c", directory: "/home/")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 11.0.0"}
+!7 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 1, type: !8, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = !{!12}
+!12 = !DILocalVariable(name: "f", scope: !7, file: !1, line: 2, type: !13)
+!13 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
+!14 = !DILocation(line: 0, scope: !7)
+!15 = !DILocation(line: 3, column: 2, scope: !7)
+!16 = !DILocation(line: 5, column: 2, scope: !7)


        


More information about the llvm-commits mailing list