[llvm] 89d19d6 - Reapply: [DebugInfo] Correctly handle salvaged casts and split fragments at ISel

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 18 08:33:11 PST 2019


Author: stozer
Date: 2019-12-18T16:26:42Z
New Revision: 89d19d60adb953dad14c04c7dcaa92d135a7d58f

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

LOG: Reapply: [DebugInfo] Correctly handle salvaged casts and split fragments at ISel

This reverts commit 1f3dd83cc1f2b8f72b9d59e2b4221b12fb7f9a95, reapplying
commit bb1b0bc4e57428ce364d3d6c075ff03cb8973462.

The original commit failed on some builds seemingly due to the use of a
bracketed constructor with an std::array, i.e. `std::array<> arr({...})`.

Added: 
    llvm/test/CodeGen/ARM/fragmented-args-multiple-regs.ll
    llvm/test/DebugInfo/salvage-cast-debug-info.ll

Modified: 
    llvm/include/llvm/IR/DebugInfoMetadata.h
    llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
    llvm/lib/IR/DebugInfoMetadata.cpp
    llvm/lib/Transforms/Utils/Local.cpp
    llvm/test/DebugInfo/X86/dbg-value-dropped-instcombine.ll
    llvm/test/Transforms/EarlyCSE/debug-info-undef.ll
    llvm/test/Transforms/InstCombine/cast-mul-select.ll
    llvm/test/Transforms/InstCombine/pr43893.ll
    llvm/test/Transforms/InstCombine/unavailable-debug.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 214003ad9934..f5582d8f98cb 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2552,6 +2552,11 @@ class DIExpression : public MDNode {
       return 0;
   }
 
+  using ExtOps = std::array<uint64_t, 6>;
+
+  /// Returns the ops for a zero- or sign-extension in a DIExpression.
+  static ExtOps getExtOps(unsigned FromSize, unsigned ToSize, bool Signed);
+
   /// Append a zero- or sign-extension to \p Expr. Converts the expression to a
   /// stack value if it isn't one already.
   static DIExpression *appendExt(const DIExpression *Expr, unsigned FromSize,

diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 27ac489b35b7..735ac67ebfc9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5571,8 +5571,26 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
       = [&](ArrayRef<std::pair<unsigned, unsigned>> SplitRegs) {
       unsigned Offset = 0;
       for (auto RegAndSize : SplitRegs) {
+        // If the expression is already a fragment, the current register
+        // offset+size might extend beyond the fragment. In this case, only
+        // the register bits that are inside the fragment are relevant.
+        int RegFragmentSizeInBits = RegAndSize.second;
+        if (auto ExprFragmentInfo = Expr->getFragmentInfo()) {
+          uint64_t ExprFragmentSizeInBits = ExprFragmentInfo->SizeInBits;
+          // The register is entirely outside the expression fragment,
+          // so is irrelevant for debug info.
+          if (Offset >= ExprFragmentSizeInBits)
+            break;
+          // The register is partially outside the expression fragment, only
+          // the low bits within the fragment are relevant for debug info.
+          if (Offset + RegFragmentSizeInBits > ExprFragmentSizeInBits) {
+            RegFragmentSizeInBits = ExprFragmentSizeInBits - Offset;
+          }
+        }
+
         auto FragmentExpr = DIExpression::createFragmentExpression(
-          Expr, Offset, RegAndSize.second);
+            Expr, Offset, RegFragmentSizeInBits);
+        Offset += RegAndSize.second;
         // If a valid fragment expression cannot be created, the variable's
         // correct value cannot be determined and so it is set as Undef.
         if (!FragmentExpr) {
@@ -5585,7 +5603,6 @@ bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
         FuncInfo.ArgDbgValues.push_back(
           BuildMI(MF, DL, TII->get(TargetOpcode::DBG_VALUE), false,
                   RegAndSize.first, Variable, *FragmentExpr));
-        Offset += RegAndSize.second;
       }
     };
 

diff  --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 9b42a5a0e1b5..ed35a7c55488 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1196,13 +1196,18 @@ bool DIExpression::isConstant() const {
   return true;
 }
 
+DIExpression::ExtOps DIExpression::getExtOps(unsigned FromSize, unsigned ToSize,
+                                             bool Signed) {
+  dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
+  DIExpression::ExtOps Ops{{dwarf::DW_OP_LLVM_convert, FromSize, TK,
+                            dwarf::DW_OP_LLVM_convert, ToSize, TK}};
+  return Ops;
+}
+
 DIExpression *DIExpression::appendExt(const DIExpression *Expr,
                                       unsigned FromSize, unsigned ToSize,
                                       bool Signed) {
-  dwarf::TypeKind TK = Signed ? dwarf::DW_ATE_signed : dwarf::DW_ATE_unsigned;
-  uint64_t Ops[] = {dwarf::DW_OP_LLVM_convert, FromSize, TK,
-                    dwarf::DW_OP_LLVM_convert, ToSize,   TK};
-  return appendToStack(Expr, Ops);
+  return appendToStack(Expr, getExtOps(FromSize, ToSize, Signed));
 }
 
 DIGlobalVariableExpression *

diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index d5690a04f531..b2d511c7c9a9 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1676,9 +1676,8 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
   };
 
   // initializer-list helper for applying operators to the source DIExpression.
-  auto applyOps =
-      [&](std::initializer_list<uint64_t> Opcodes) -> DIExpression * {
-    SmallVector<uint64_t, 8> Ops(Opcodes);
+  auto applyOps = [&](ArrayRef<uint64_t> Opcodes) -> DIExpression * {
+    SmallVector<uint64_t, 8> Ops(Opcodes.begin(), Opcodes.end());
     return doSalvage(Ops);
   };
 
@@ -1686,8 +1685,21 @@ DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
     // No-op casts and zexts are irrelevant for debug info.
     if (CI->isNoopCast(DL) || isa<ZExtInst>(&I))
       return SrcDIExpr;
-    return nullptr;
-  } else if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
+
+    Type *Type = CI->getType();
+    // Casts other than Trunc or SExt to scalar types cannot be salvaged.
+    if (Type->isVectorTy() || (!isa<TruncInst>(&I) && !isa<SExtInst>(&I)))
+      return nullptr;
+
+    Value *FromValue = CI->getOperand(0);
+    unsigned FromTypeBitSize = FromValue->getType()->getScalarSizeInBits();
+    unsigned ToTypeBitSize = Type->getScalarSizeInBits();
+
+    return applyOps(DIExpression::getExtOps(FromTypeBitSize, ToTypeBitSize,
+                                            isa<SExtInst>(&I)));
+  }
+
+  if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
     unsigned BitWidth =
         M.getDataLayout().getIndexSizeInBits(GEP->getPointerAddressSpace());
     // Rewrite a constant GEP into a DIExpression.

diff  --git a/llvm/test/CodeGen/ARM/fragmented-args-multiple-regs.ll b/llvm/test/CodeGen/ARM/fragmented-args-multiple-regs.ll
new file mode 100644
index 000000000000..8c4822dfe158
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/fragmented-args-multiple-regs.ll
@@ -0,0 +1,72 @@
+; RUN: llc < %s -mtriple=armv7-linux-gnueabihf -O1 -stop-after=finalize-isel | FileCheck %s
+
+define dso_local i32 @h(i64 %j) local_unnamed_addr !dbg !8 {
+entry:
+  call void @llvm.dbg.value(metadata i64 %j, metadata !14, metadata !DIExpression()), !dbg !29
+  call void @llvm.dbg.value(metadata i64 %j, metadata !15, metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32)), !dbg !29
+  call void @llvm.dbg.value(metadata i64 %j, metadata !15, metadata !DIExpression(DW_OP_constu, 32, DW_OP_shr, DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_stack_value, DW_OP_LLVM_fragment, 32, 32)), !dbg !29
+  %tobool = icmp ult i64 %j, 4294967296, !dbg !30
+  br i1 %tobool, label %cleanup, label %if.then, !dbg !31
+
+if.then:                                          ; preds = %entry
+  call void @llvm.dbg.value(metadata i64 %j, metadata !15, metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32)), !dbg !29
+  %conv = sitofp i64 %j to double, !dbg !32
+  %add = fadd double %conv, 0x43F0000000000000, !dbg !33
+  call void @llvm.dbg.value(metadata double %add, metadata !25, metadata !DIExpression()), !dbg !34
+  %conv2 = fptosi double %add to i32, !dbg !35
+  br label %cleanup
+
+cleanup:                                          ; preds = %entry, %if.then
+  %retval.0 = phi i32 [ %conv2, %if.then ], [ undef, %entry ]
+  ret i32 %retval.0, !dbg !36
+}
+
+; CHECK-LABEL: bb.0.entry:
+; CHECK: DBG_VALUE [[REG1:%[0-9]+]], $noreg, !14, !DIExpression(DW_OP_LLVM_fragment, 32, 32
+; CHECK: DBG_VALUE [[REG2:%[0-9]+]], $noreg, !14, !DIExpression(DW_OP_LLVM_fragment, 0, 32
+; CHECK: DBG_VALUE [[REG2]], $noreg, !15, !DIExpression({{.+}}DW_OP_LLVM_fragment, 0, 32
+; CHECK: DBG_VALUE $noreg, $noreg, !15, !DIExpression({{.+}}DW_OP_LLVM_fragment, 32, 32
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5, !6}
+!llvm.ident = !{!7}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0 ", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "tif_aux.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{i32 1, !"min_enum_size", i32 4}
+!7 = !{!"clang version 10.0.0 "}
+!8 = distinct !DISubprogram(name: "h", scope: !1, file: !1, line: 10, type: !9, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13)
+!9 = !DISubroutineType(types: !10)
+!10 = !{!11, !12}
+!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!12 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed)
+!13 = !{!14, !15, !25}
+!14 = !DILocalVariable(name: "j", arg: 1, scope: !8, file: !1, line: 10, type: !12)
+!15 = !DILocalVariable(name: "i", scope: !8, file: !1, line: 11, type: !16)
+!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "g", file: !1, line: 8, baseType: !17)
+!17 = distinct !DICompositeType(tag: DW_TAG_union_type, file: !1, line: 5, size: 64, elements: !18)
+!18 = !{!19, !24}
+!19 = !DIDerivedType(tag: DW_TAG_member, name: "e", scope: !17, file: !1, line: 6, baseType: !20, size: 64)
+!20 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "b", file: !1, line: 1, size: 64, elements: !21)
+!21 = !{!22, !23}
+!22 = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: !20, file: !1, line: 2, baseType: !11, size: 32)
+!23 = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: !20, file: !1, line: 2, baseType: !11, size: 32, offset: 32)
+!24 = !DIDerivedType(tag: DW_TAG_member, name: "f", scope: !17, file: !1, line: 7, baseType: !12, size: 64)
+!25 = !DILocalVariable(name: "a", scope: !26, file: !1, line: 14, type: !28)
+!26 = distinct !DILexicalBlock(scope: !27, file: !1, line: 13, column: 14)
+!27 = distinct !DILexicalBlock(scope: !8, file: !1, line: 13, column: 7)
+!28 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
+!29 = !DILocation(line: 0, scope: !8)
+!30 = !DILocation(line: 13, column: 7, scope: !27)
+!31 = !DILocation(line: 13, column: 7, scope: !8)
+!32 = !DILocation(line: 14, column: 16, scope: !26)
+!33 = !DILocation(line: 14, column: 20, scope: !26)
+!34 = !DILocation(line: 0, scope: !26)
+!35 = !DILocation(line: 15, column: 12, scope: !26)
+!36 = !DILocation(line: 17, column: 1, scope: !8)

diff  --git a/llvm/test/DebugInfo/X86/dbg-value-dropped-instcombine.ll b/llvm/test/DebugInfo/X86/dbg-value-dropped-instcombine.ll
index 18e51b6fabd4..46f940e11c63 100644
--- a/llvm/test/DebugInfo/X86/dbg-value-dropped-instcombine.ll
+++ b/llvm/test/DebugInfo/X86/dbg-value-dropped-instcombine.ll
@@ -21,8 +21,8 @@
 ; }
 
 ; CHECK: define dso_local i64 @foo
-; CHECK: @llvm.dbg.value({{.*}}, metadata ![[BEE:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)),
-; CHECK: @llvm.dbg.value(metadata i32 undef, metadata ![[BEE]], metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32)),
+; CHECK: @llvm.dbg.value(metadata i64 {{.*}}, metadata ![[BEE:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32)),
+; CHECK: @llvm.dbg.value(metadata i64 {{.*}}, metadata ![[BEE]], metadata !DIExpression({{.*}}, DW_OP_LLVM_fragment, 32, 32)),
 
 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-unknown"

diff  --git a/llvm/test/DebugInfo/salvage-cast-debug-info.ll b/llvm/test/DebugInfo/salvage-cast-debug-info.ll
new file mode 100644
index 000000000000..f39ac46a66a4
--- /dev/null
+++ b/llvm/test/DebugInfo/salvage-cast-debug-info.ll
@@ -0,0 +1,25 @@
+; RUN: opt %s -debugify -early-cse -S | FileCheck %s
+define i32 @foo(i64 %nose, i32 %more) {
+; CHECK-LABEL: @foo(
+; CHECK: call void @llvm.dbg.value(metadata i64 %nose, metadata [[V1:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned
+; CHECK: call void @llvm.dbg.value(metadata i64 %nose.shift, metadata [[V2:![0-9]+]]
+; CHECK: call void @llvm.dbg.value(metadata i64 %nose.shift, metadata [[V3:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_convert, 64, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned
+
+entry:
+  %nose.trunc = trunc i64 %nose to i32
+  %nose.shift = lshr i64 %nose, 32
+  %nose.trunc.2 = trunc i64 %nose.shift to i32
+  %add = add nsw i32 %more, 1
+  ret i32 %add
+}
+
+!llvm.module.flags = !{!0, !1}
+!llvm.ident = !{!2}
+
+!0 = !{i32 1, !"wchar_size", i32 2}
+!1 = !{i32 7, !"PIC Level", i32 2}
+!2 = !{!"clang version 10.0.0 "}
+
+; CHECK: [[V1]] = !DILocalVariable(
+; CHECK: [[V2]] = !DILocalVariable(
+; CHECK: [[V3]] = !DILocalVariable(

diff  --git a/llvm/test/Transforms/EarlyCSE/debug-info-undef.ll b/llvm/test/Transforms/EarlyCSE/debug-info-undef.ll
index 4615aa264b6d..b0fb8ff75ad3 100644
--- a/llvm/test/Transforms/EarlyCSE/debug-info-undef.ll
+++ b/llvm/test/Transforms/EarlyCSE/debug-info-undef.ll
@@ -10,7 +10,7 @@ entry:
   %0 = load i8, i8* @a, align 1, !dbg !19, !tbaa !20
   %conv = sext i8 %0 to i16, !dbg !19
 
-; CHECK: call void @llvm.dbg.value(metadata i16 undef, metadata !17, metadata !DIExpression()), !dbg !18
+; CHECK: call void @llvm.dbg.value(metadata i8 %0, metadata !17, metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 16, DW_ATE_signed, DW_OP_stack_value)), !dbg !18
 ; CHECK-NEXT:  call i32 (...) @optimize_me_not()
 
   call void @llvm.dbg.value(metadata i16 %conv, metadata !17, metadata !DIExpression()), !dbg !18

diff  --git a/llvm/test/Transforms/InstCombine/cast-mul-select.ll b/llvm/test/Transforms/InstCombine/cast-mul-select.ll
index 5de3314b4727..f82d2fd285fe 100644
--- a/llvm/test/Transforms/InstCombine/cast-mul-select.ll
+++ b/llvm/test/Transforms/InstCombine/cast-mul-select.ll
@@ -13,8 +13,8 @@ define i32 @mul(i32 %x, i32 %y) {
 ; we preserve the debug information in the resulting
 ; instruction.
 ; DBGINFO-LABEL: @mul(
-; DBGINFO-NEXT:    call void @llvm.dbg.value(metadata i8 undef
-; DBGINFO-NEXT:    call void @llvm.dbg.value(metadata i8 undef
+; DBGINFO-NEXT:    call void @llvm.dbg.value(metadata i32 %x
+; DBGINFO-NEXT:    call void @llvm.dbg.value(metadata i32 %y
 ; DBGINFO-NEXT:    [[C:%.*]] = mul i32 {{.*}}
 ; DBGINFO-NEXT:    [[D:%.*]] = and i32 {{.*}}
 ; DBGINFO-NEXT:    call void @llvm.dbg.value(metadata i32 [[C]]

diff  --git a/llvm/test/Transforms/InstCombine/pr43893.ll b/llvm/test/Transforms/InstCombine/pr43893.ll
index 0eb926b19a6e..5eaae20fe741 100644
--- a/llvm/test/Transforms/InstCombine/pr43893.ll
+++ b/llvm/test/Transforms/InstCombine/pr43893.ll
@@ -13,9 +13,10 @@ entry:
 ;CHECK: call void @llvm.dbg.value(metadata i32 -8
 ;CHECK: call void @llvm.dbg.value(metadata i32 undef
   %conv = sext i8 %dec to i32, !dbg !17
-  call void @llvm.dbg.value(metadata i32 %conv, metadata !18, metadata !DIExpression()), !dbg !19
+  %udiv = udiv i32 %conv, 4, !dbg !17
+  call void @llvm.dbg.value(metadata i32 %udiv, metadata !18, metadata !DIExpression()), !dbg !19
   call void @llvm.dbg.value(metadata i32 -8, metadata !20, metadata !DIExpression()), !dbg !19
-  call void @llvm.dbg.value(metadata i32 %conv, metadata !20, metadata !DIExpression()), !dbg !19
+  call void @llvm.dbg.value(metadata i32 %udiv, metadata !20, metadata !DIExpression()), !dbg !19
   store i8 0, i8* @b, align 1, !dbg !21
   %cmp = icmp sgt i32 %conv, 0, !dbg !22
   %conv1 = zext i1 %cmp to i32, !dbg !22

diff  --git a/llvm/test/Transforms/InstCombine/unavailable-debug.ll b/llvm/test/Transforms/InstCombine/unavailable-debug.ll
index 703c1c2898f6..e3f0d7cf22d9 100644
--- a/llvm/test/Transforms/InstCombine/unavailable-debug.ll
+++ b/llvm/test/Transforms/InstCombine/unavailable-debug.ll
@@ -2,7 +2,7 @@
 
 ; Make sure to update the debug value after dead code elimination.
 ; CHECK: %call = call signext i8 @b(i32 6), !dbg !39
-; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 undef, metadata !30, metadata !DIExpression()), !dbg !38
+; CHECK-NEXT: call void @llvm.dbg.value(metadata i8 %call, metadata !30, metadata !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)), !dbg !38
 
 @e = common local_unnamed_addr global i8 0, align 1, !dbg !0
 @c = common local_unnamed_addr global i32 0, align 4, !dbg !6


        


More information about the llvm-commits mailing list