[llvm] 25d0f3c - [Assignment Tracking] Fix fragment index error in getDerefOffsetInBytes

via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 10 05:55:11 PST 2023


Author: OCHyams
Date: 2023-02-10T13:49:05Z
New Revision: 25d0f3c4d0d9f01755b008b5af92448ba593adf9

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

LOG: [Assignment Tracking] Fix fragment index error in getDerefOffsetInBytes

Without this patch `getDerefOffsetInBytes` incorrectly always returns
`std::nullopt` for expressions with fragments due to an off-by-one error with
fragment element indices.

Reviewed By: StephenTozer

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

Added: 
    

Modified: 
    llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
    llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
    llvm/test/DebugInfo/assignment-tracking/X86/mem-loc-frag-fill.ll
    llvm/test/DebugInfo/assignment-tracking/X86/nested-loop-frags.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index 7098824dbe4b9..d3c9d141b5d87 100644
--- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
+++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
@@ -234,13 +234,13 @@ getDerefOffsetInBytes(const DIExpression *DIExpr) {
   int64_t Offset = 0;
   const unsigned NumElements = DIExpr->getNumElements();
   const auto Elements = DIExpr->getElements();
-  unsigned NextElement = 0;
+  unsigned ExpectedDerefIdx = 0;
   // Extract the offset.
   if (NumElements > 2 && Elements[0] == dwarf::DW_OP_plus_uconst) {
     Offset = Elements[1];
-    NextElement = 2;
+    ExpectedDerefIdx = 2;
   } else if (NumElements > 3 && Elements[0] == dwarf::DW_OP_constu) {
-    NextElement = 3;
+    ExpectedDerefIdx = 3;
     if (Elements[2] == dwarf::DW_OP_plus)
       Offset = Elements[1];
     else if (Elements[2] == dwarf::DW_OP_minus)
@@ -250,19 +250,21 @@ getDerefOffsetInBytes(const DIExpression *DIExpr) {
   }
 
   // If that's all there is it means there's no deref.
-  if (NextElement >= NumElements)
+  if (ExpectedDerefIdx >= NumElements)
     return std::nullopt;
 
   // Check the next element is DW_OP_deref - otherwise this is too complex or
   // isn't a deref expression.
-  if (Elements[NextElement] != dwarf::DW_OP_deref)
+  if (Elements[ExpectedDerefIdx] != dwarf::DW_OP_deref)
     return std::nullopt;
 
   // Check the final operation is either the DW_OP_deref or is a fragment.
-  if (NumElements == NextElement + 1)
+  if (NumElements == ExpectedDerefIdx + 1)
     return Offset; // Ends with deref.
-  else if (NumElements == NextElement + 3 &&
-           Elements[NextElement] == dwarf::DW_OP_LLVM_fragment)
+  unsigned ExpectedFragFirstIdx = ExpectedDerefIdx + 1;
+  unsigned ExpectedFragFinalIdx = ExpectedFragFirstIdx + 2;
+  if (NumElements == ExpectedFragFinalIdx + 1 &&
+      Elements[ExpectedFragFirstIdx] == dwarf::DW_OP_LLVM_fragment)
     return Offset; // Ends with deref + fragment.
 
   // Don't bother trying to interpret anything more complex.

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll b/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
index f01d04aeb20b7..c0fa9ee13c51b 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
@@ -49,6 +49,10 @@
 ; INSTRREF: %2:gr64 = nsw ADD64ri8 %1, 2, implicit-def dead $eflags, debug-instr-number 1
 ; INSTRREF-NEXT: DBG_INSTR_REF ![[VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location
 
+;; Bits [0, 64) are still stack homed. FIXME, this particular reinstatement is
+;; unnecessary.
+; CHECK-NEXT: DBG_VALUE %stack.0.X, $noreg, ![[VAR]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 64)
+
 source_filename = "test.cpp"
 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"

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/mem-loc-frag-fill.ll b/llvm/test/DebugInfo/assignment-tracking/X86/mem-loc-frag-fill.ll
index 899dfc8932b58..aa5f1ee1540ec 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/mem-loc-frag-fill.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/mem-loc-frag-fill.ll
@@ -52,6 +52,16 @@ entry:
   call void @llvm.dbg.assign(metadata i32 2, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32), metadata !31, metadata ptr %c, metadata !DIExpression()), !dbg !19
 ; CHECK-NEXT: DBG_VALUE %stack.0.nums, $noreg, ![[nums]], !DIExpression(DW_OP_plus_uconst, 8, DW_OP_deref, DW_OP_LLVM_fragment, 64, 32)
   tail call void @_Z4stepv(), !dbg !32
+;; Next dbg.assign added by hand to test that the bits [64, 32) have been
+;; correctly tracked as in memory - we know this has worked if
+;; mem-loc-frag-fill reinstates the memory location after this kill-location
+;; for bits [80, 96).
+  call void @llvm.dbg.assign(metadata i32 poison, metadata !12, metadata !DIExpression(DW_OP_LLVM_fragment, 80, 16), metadata !44, metadata ptr poison, metadata !DIExpression()), !dbg !19
+; CHECK: CALL64pcrel32 @_Z4stepv
+; CHECK-NEXT: ADJCALLSTACKUP64
+; CHECK-NEXT: DBG_VALUE $noreg, $noreg, ![[nums]], !DIExpression(DW_OP_LLVM_fragment, 80, 16)
+; CHECK-NEXT: DBG_VALUE %stack.0.nums, $noreg, ![[nums]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 80)
+  tail call void @_Z4stepv(), !dbg !32
   call void @_Z3escP4Nums(ptr noundef nonnull %nums), !dbg !33
   ret i32 0, !dbg !35
 }
@@ -105,4 +115,5 @@ declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata,
 !41 = !DISubroutineType(types: !42)
 !42 = !{null, !43}
 !43 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
+!44 = distinct !DIAssignID()
 !1000 = !{i32 7, !"debug-info-assignment-tracking", i1 true}

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/nested-loop-frags.ll b/llvm/test/DebugInfo/assignment-tracking/X86/nested-loop-frags.ll
index 989abb363c501..eedb0c6704370 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/nested-loop-frags.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/nested-loop-frags.ll
@@ -230,7 +230,7 @@ do.cond4:                                         ; preds = %do.cond
 
 do.end6:                                          ; preds = %do.cond4
   call void @llvm.dbg.assign(metadata i32 3, metadata !21, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata !63, metadata ptr %a.addr, metadata !DIExpression()), !dbg !27; VAR:a
-  call void @llvm.dbg.assign(metadata i32 0, metadata !21, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !70, metadata ptr %a.addr, metadata !DIExpression()), !dbg !27; VAR:a
+  call void @llvm.dbg.assign(metadata i32 0, metadata !21, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !70, metadata ptr %a.addr, metadata !DIExpression(DW_OP_plus_uconst, 32)), !dbg !27; VAR:a
   ;call void @llvm.dbg.assign(metadata i32 3, metadata !21, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !81, metadata ptr %a.addr, metadata !DIExpression()), !dbg !27; VAR:a
   call void @llvm.dbg.assign(metadata i32 4, metadata !22, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata !65, metadata ptr %b.addr, metadata !DIExpression()), !dbg !27 ; VAR:b
   call void @llvm.dbg.assign(metadata i32 0, metadata !22, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !71, metadata ptr %b.addr, metadata !DIExpression()), !dbg !27 ; VAR:b
@@ -240,8 +240,8 @@ do.end6:                                          ; preds = %do.cond4
   ;call void @llvm.dbg.assign(metadata i32 11, metadata !79, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata !81, metadata ptr %f.addr, metadata !DIExpression()), !dbg !27 ; VAR:f
   ret i32 0, !dbg !53
 ; CHECK-LABEL: bb.7.do.end6:
+; CHECK-NEXT:    DBG_VALUE %stack.0.a.addr, $noreg, ![[a]], !DIExpression(DW_OP_plus_uconst, 32, DW_OP_deref, DW_OP_LLVM_fragment, 32, 32)
 ; CHECK-NEXT:    DBG_VALUE %stack.0.a.addr, $noreg, ![[a]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 0, 32)
-; CHECK-NEXT:    DBG_VALUE %stack.0.a.addr, $noreg, ![[a]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 32, 32)
 ; CHECK-NEXT:    DBG_VALUE 4, $noreg, ![[b]], !DIExpression(DW_OP_LLVM_fragment, 0, 32)
 ; CHECK-NEXT:    DBG_VALUE %stack.1.b.addr, $noreg, ![[b]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 32, 32)
 ; xCHECK-NEXT:    XXX ? DBG_VALUE %stack.3.d.addr, $noreg, ![[d]], !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 32, 32)


        


More information about the llvm-commits mailing list