[llvm] 6db6ab4 - Revert "[Assignment Tracking] Fix fragment error for some DSE-shortened stores"

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 19 02:04:28 PDT 2023


Author: OCHyams
Date: 2023-04-19T10:03:33+01:00
New Revision: 6db6ab4815a44bfcaabfcdd84a0ff458394f6f52

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

LOG: Revert "[Assignment Tracking] Fix fragment error for some DSE-shortened stores"

This reverts commit fca3e8e024f0015604d21e6f76f3e199345679c5.

Buildbot: https://lab.llvm.org/buildbot/#/builders/121/builds/29766

Added: 
    

Modified: 
    llvm/include/llvm/IR/DebugInfo.h
    llvm/include/llvm/IR/DebugInfoMetadata.h
    llvm/include/llvm/IR/IntrinsicInst.h
    llvm/lib/IR/DebugInfo.cpp
    llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
    llvm/lib/Transforms/Scalar/SROA.cpp
    llvm/test/DebugInfo/Generic/assignment-tracking/dse/dse-after-memcpyopt-merge.ll

Removed: 
    llvm/test/DebugInfo/Generic/assignment-tracking/dse/shorten-offset.ll


################################################################################
diff  --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index 26a7cfbbb3502..e717407e686c5 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -224,20 +224,6 @@ void RAUW(DIAssignID *Old, DIAssignID *New);
 /// Remove all Assignment Tracking related intrinsics and metadata from \p F.
 void deleteAll(Function *F);
 
-/// Calculate the fragment of the variable in \p DAI covered
-/// from (Dest + SliceOffsetInBits) to
-///   to (Dest + SliceOffsetInBits + SliceSizeInBits)
-///
-/// Return false if it can't be calculated for any reason.
-/// Result is set to nullopt if the intersect equals the variable fragment (or
-/// variable size) in DAI.
-///
-/// Result contains a zero-sized fragment if there's no intersect.
-bool calculateFragmentIntersect(
-    const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
-    uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DAI,
-    std::optional<DIExpression::FragmentInfo> &Result);
-
 /// Helper struct for trackAssignments, below. We don't use the similar
 /// DebugVariable class because trackAssignments doesn't (yet?) understand
 /// partial variables (fragment info) as input and want to make that clear and

diff  --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 21d2904d4c8c0..ebf011c487dd8 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2796,16 +2796,6 @@ class DIExpression : public MDNode {
     /// Return the index of the bit after the end of the fragment, e.g. for
     /// fragment offset=16 and size=32 return their sum, 48.
     uint64_t endInBits() const { return OffsetInBits + SizeInBits; }
-
-    /// Returns a zero-sized fragment if A and B don't intersect.
-    static DIExpression::FragmentInfo intersect(DIExpression::FragmentInfo A,
-                                                DIExpression::FragmentInfo B) {
-      uint64_t StartInBits = std::max(A.OffsetInBits, B.OffsetInBits);
-      uint64_t EndInBits = std::min(A.endInBits(), B.endInBits());
-      if (EndInBits <= StartInBits)
-        return {0, 0};
-      return DIExpression::FragmentInfo(EndInBits - StartInBits, StartInBits);
-    }
   };
 
   /// Retrieve the details of this fragment expression.

diff  --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index 9b349c8846480..548d88ebff1cf 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -376,19 +376,6 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
     return getExpression()->getFragmentInfo();
   }
 
-  /// Get the FragmentInfo for the variable if it exists, otherwise return a
-  /// FragmentInfo that covers the entire variable if the variable size is
-  /// known, otherwise return a zero-sized fragment.
-  DIExpression::FragmentInfo getFragmentOrEntireVariable() const {
-    DIExpression::FragmentInfo VariableSlice(0, 0);
-    // Get the fragment or variable size, or zero.
-    if (auto Sz = getFragmentSizeInBits())
-      VariableSlice.SizeInBits = *Sz;
-    if (auto Frag = getExpression()->getFragmentInfo())
-      VariableSlice.OffsetInBits = Frag->OffsetInBits;
-    return VariableSlice;
-  }
-
   /// \name Casting methods
   /// @{
   static bool classof(const IntrinsicInst *I) {

diff  --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index d3c965bb6862b..3206b23f67de5 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -19,7 +19,6 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DIBuilder.h"
@@ -1794,140 +1793,6 @@ void at::deleteAll(Function *F) {
     DAI->eraseFromParent();
 }
 
-bool at::calculateFragmentIntersect(
-    const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
-    uint64_t SliceSizeInBits, const DbgAssignIntrinsic *DAI,
-    std::optional<DIExpression::FragmentInfo> &Result) {
-  // There are multiple offsets at play in this function, so let's break it
-  // down. Starting with how variables may be stored in allocas:
-  //
-  //   1 Simplest case: variable is alloca sized and starts at offset 0.
-  //   2 Variable is larger than the alloca: the alloca holds just a part of it.
-  //   3 Variable is smaller than the alloca: the alloca may hold multiple
-  //   variables.
-  //
-  // Imagine we have a store to the entire alloca. In case (3) the store
-  // affects bits outside of the bounds of each variable. In case (2), where
-  // the alloca holds the Xth bit to the Yth bit of a variable, the
-  // zero-offset store doesn't represent an assignment at offset zero to the
-  // variable. It is an assignment to offset X.
-  //
-  // # Example 1
-  // Obviously, not all stores are alloca-sized and have zero offset. Imagine
-  // the lower 32 bits of this store are dead and are going to be DSEd:
-  //
-  //    store i64 %v, ptr %dest, !DIAssignID !1
-  //    dbg.assign(..., !DIExpression(fragment, 128, 32), !1, %dest,
-  //               !DIExpression(DW_OP_plus_uconst, 4))
-  //
-  // Goal: Given our dead bits at offset:0 size:32 for the store, determine the
-  // part of the variable, which fits in the fragment expressed by the
-  // dbg.assign, that has been killed, if any.
-  //
-  //     calculateFragmentIntersect(..., SliceOffsetInBits=0,
-  //                 SliceSizeInBits=32, Dest=%dest, DAI=dbg.assign)
-  //
-  // Drawing the store (s) in memory followed by the shortened version ($),
-  // then the dbg.assign (d), with the fragment information on a seperate scale
-  // underneath:
-  //
-  // Memory
-  // offset
-  //   from
-  //   dest 0      63
-  //        |      |
-  //       s[######] - Original stores 64 bits to Dest.
-  //       $----[##] - DSE says the lower 32 bits are dead, to be removed.
-  //       d    [##] - DAI's address-modifying expression adds 4 bytes to dest.
-  // Variable   |  |
-  // Fragment   128|
-  //  Offsets      159
-  //
-  // The answer is achieved in a few steps:
-  // 1. Add the fragment offset to the store offset:
-  //      SliceOffsetInBits:0 + VarFrag.OffsetInBits:128 = 128
-  //
-  // 2. Subtract the address-modifying expression offset plus 
diff erence
-  //    between d.address and dest:
-  //      128 - (expression_offset:32 + (d.address - dest):0) = 96
-  //
-  // 3. That offset along with the store size (32) represents the bits of the
-  //    variable that'd be affected by the store. Call it SliceOfVariable.
-  //    Intersect that with DAI's fragment info:
-  //      SliceOfVariable ∩ DAI_fragment = none
-  //
-  // In this case: none of the dead bits of the store affect DAI.
-  //
-  // # Example 2
-  // Similar example with the same goal. This time the upper 16 bits
-  // of the store are going to be DSE'd.
-  //
-  //    store i64 %v, ptr %dest, !DIAssignID !1
-  //    dbg.assign(..., !DIExpression(fragment, 128, 32), !1, %dest,
-  //               !DIExpression(DW_OP_plus_uconst, 4))
-  //
-  //     calculateFragmentIntersect(..., SliceOffsetInBits=48,
-  //                 SliceSizeInBits=16, Dest=%dest, DAI=dbg.assign)
-  //
-  // Memory
-  // offset
-  //   from
-  //   dest 0      63
-  //        |      |
-  //       s[######] - Original stores 64 bits to Dest.
-  //       $[####]-- - DSE says the upper 16 bits are dead, to be removed.
-  //       d    [##] - DAI's address-modifying expression adds 4 bytes to dest.
-  // Variable   |  |
-  // Fragment   128|
-  //  Offsets      159
-  //
-  // Using the same steps in the first example:
-  // 1. SliceOffsetInBits:48 + VarFrag.OffsetInBits:128 = 176
-  // 2. 176 - (expression_offset:32 + (d.address - dest):0) = 144
-  // 3. SliceOfVariable offset = 144, size = 16:
-  //      SliceOfVariable ∩ DAI_fragment = (offset: 144, size: 16)
-  // SliceOfVariable tells us the bits of the variable described by DAI that are
-  // affected by the DSE.
-  if (DAI->isKillAddress())
-    return false;
-
-  DIExpression::FragmentInfo VarFrag = DAI->getFragmentOrEntireVariable();
-  if (VarFrag.SizeInBits == 0)
-    return false; // Variable size is unknown.
-
-  // Calculate the 
diff erence between Dest and the dbg.assign address +
-  // address-modifying expression.
-  int64_t PointerOffsetInBits;
-  {
-    auto DestOffsetInBytes = llvm::isPointerOffset(Dest, DAI->getAddress(), DL);
-    if (!DestOffsetInBytes)
-      return false; // Can't calculate 
diff erence in addresses.
-
-    int64_t ExprOffsetInBytes;
-    if (!DAI->getAddressExpression()->extractIfOffset(ExprOffsetInBytes))
-      return false;
-
-    int64_t PointerOffsetInBytes = *DestOffsetInBytes + ExprOffsetInBytes;
-    PointerOffsetInBits = PointerOffsetInBytes * 8;
-  }
-
-  // Adjust the slice offset so that we go from describing the a slice
-  // of memory to a slice of the variable.
-  int64_t NewOffsetInBits =
-      SliceOffsetInBits + VarFrag.OffsetInBits - PointerOffsetInBits;
-  if (NewOffsetInBits < 0)
-    return false; // Fragment offsets can only be positive.
-  DIExpression::FragmentInfo SliceOfVariable(SliceSizeInBits, NewOffsetInBits);
-  // Intersect the variable slice with DAI's fragment to trim it down to size.
-  DIExpression::FragmentInfo TrimmedSliceOfVariable =
-      DIExpression::FragmentInfo::intersect(SliceOfVariable, VarFrag);
-  if (TrimmedSliceOfVariable == VarFrag)
-    Result = std::nullopt;
-  else
-    Result = TrimmedSliceOfVariable;
-  return true;
-}
-
 /// Collect constant properies (base, size, offset) of \p StoreDest.
 /// Return std::nullopt if any properties are not constants.
 static std::optional<AssignmentInfo>

diff  --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index d0c249f736006..56ea24193bda8 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -482,75 +482,41 @@ memoryIsNotModifiedBetween(Instruction *FirstI, Instruction *SecondI,
   return true;
 }
 
-static void shortenAssignment(Instruction *Inst, Value *OriginalDest,
-                              uint64_t OldOffsetInBits, uint64_t OldSizeInBits,
-                              uint64_t NewSizeInBits, bool IsOverwriteEnd) {
-  const DataLayout &DL = Inst->getModule()->getDataLayout();
-  uint64_t DeadSliceSizeInBits = OldSizeInBits - NewSizeInBits;
-  uint64_t DeadSliceOffsetInBits =
+static void shortenAssignment(Instruction *Inst, uint64_t OldOffsetInBits,
+                              uint64_t OldSizeInBits, uint64_t NewSizeInBits,
+                              bool IsOverwriteEnd) {
+  DIExpression::FragmentInfo DeadFragment;
+  DeadFragment.SizeInBits = OldSizeInBits - NewSizeInBits;
+  DeadFragment.OffsetInBits =
       OldOffsetInBits + (IsOverwriteEnd ? NewSizeInBits : 0);
-  auto SetDeadFragExpr = [](DbgAssignIntrinsic *DAI,
-                            DIExpression::FragmentInfo DeadFragment) {
-    // createFragmentExpression expects an offset relative to the existing
-    // fragment offset if there is one.
-    uint64_t RelativeOffset = DeadFragment.OffsetInBits -
-                              DAI->getExpression()
-                                  ->getFragmentInfo()
-                                  .value_or(DIExpression::FragmentInfo(0, 0))
-                                  .OffsetInBits;
-    if (auto NewExpr = DIExpression::createFragmentExpression(
-            DAI->getExpression(), RelativeOffset, DeadFragment.SizeInBits)) {
-      DAI->setExpression(*NewExpr);
-      return;
-    }
-    // Failed to create a fragment expression for this so discard the value,
-    // making this a kill location.
-    auto *Expr = *DIExpression::createFragmentExpression(
-        DIExpression::get(DAI->getContext(), std::nullopt),
+
+  auto CreateDeadFragExpr = [Inst, DeadFragment]() {
+    // FIXME: This should be using the DIExpression in the Alloca's dbg.assign
+    // for the variable, since that could also contain a fragment?
+    return *DIExpression::createFragmentExpression(
+        DIExpression::get(Inst->getContext(), std::nullopt),
         DeadFragment.OffsetInBits, DeadFragment.SizeInBits);
-    DAI->setExpression(Expr);
-    DAI->setKillLocation();
   };
 
   // A DIAssignID to use so that the inserted dbg.assign intrinsics do not
   // link to any instructions. Created in the loop below (once).
   DIAssignID *LinkToNothing = nullptr;
-  LLVMContext &Ctx = Inst->getContext();
-  auto GetDeadLink = [&Ctx, &LinkToNothing]() {
-    if (!LinkToNothing)
-      LinkToNothing = DIAssignID::getDistinct(Ctx);
-    return LinkToNothing;
-  };
 
   // Insert an unlinked dbg.assign intrinsic for the dead fragment after each
-  // overlapping dbg.assign intrinsic. The loop invalidates the iterators
-  // returned by getAssignmentMarkers so save a copy of the markers to iterate
-  // over.
-  auto LinkedRange = at::getAssignmentMarkers(Inst);
-  SmallVector<DbgAssignIntrinsic *> Linked(LinkedRange.begin(),
-                                           LinkedRange.end());
-  for (auto *DAI : Linked) {
-    std::optional<DIExpression::FragmentInfo> NewFragment;
-    if (!at::calculateFragmentIntersect(DL, OriginalDest, DeadSliceOffsetInBits,
-                                        DeadSliceSizeInBits, DAI,
-                                        NewFragment) ||
-        !NewFragment) {
-      // We couldn't calculate the intersecting fragment for some reason. Be
-      // cautious and unlink the whole assignment from the store.
-      DAI->setKillAddress();
-      DAI->setAssignId(GetDeadLink());
-      continue;
+  // overlapping dbg.assign intrinsic.
+  for (auto *DAI : at::getAssignmentMarkers(Inst)) {
+    if (auto FragInfo = DAI->getExpression()->getFragmentInfo()) {
+      if (!DIExpression::fragmentsOverlap(*FragInfo, DeadFragment))
+        continue;
     }
-    // No intersect.
-    if (NewFragment->SizeInBits == 0)
-      continue;
 
     // Fragments overlap: insert a new dbg.assign for this dead part.
     auto *NewAssign = cast<DbgAssignIntrinsic>(DAI->clone());
     NewAssign->insertAfter(DAI);
-    NewAssign->setAssignId(GetDeadLink());
-    if (NewFragment)
-      SetDeadFragExpr(NewAssign, *NewFragment);
+    if (!LinkToNothing)
+      LinkToNothing = DIAssignID::getDistinct(Inst->getContext());
+    NewAssign->setAssignId(LinkToNothing);
+    NewAssign->setExpression(CreateDeadFragExpr());
     NewAssign->setKillAddress();
   }
 }
@@ -627,8 +593,8 @@ static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
   DeadIntrinsic->setLength(TrimmedLength);
   DeadIntrinsic->setDestAlignment(PrefAlign);
 
-  Value *OrigDest = DeadIntrinsic->getRawDest();
   if (!IsOverwriteEnd) {
+    Value *OrigDest = DeadIntrinsic->getRawDest();
     Type *Int8PtrTy =
         Type::getInt8PtrTy(DeadIntrinsic->getContext(),
                            OrigDest->getType()->getPointerAddressSpace());
@@ -647,7 +613,7 @@ static bool tryToShorten(Instruction *DeadI, int64_t &DeadStart,
   }
 
   // Update attached dbg.assign intrinsics. Assume 8-bit byte.
-  shortenAssignment(DeadI, OrigDest, DeadStart * 8, DeadSize * 8, NewSize * 8,
+  shortenAssignment(DeadI, DeadStart * 8, DeadSize * 8, NewSize * 8,
                     IsOverwriteEnd);
 
   // Finally update start and size of dead access.

diff  --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index db518a4c101eb..d5615c902ad15 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -130,7 +130,6 @@ namespace {
 /// UseFrag - Use Target as the new fragment.
 /// UseNoFrag - The new slice already covers the whole variable.
 /// Skip - The new alloca slice doesn't include this variable.
-/// FIXME: Can we use calculateFragmentIntersect instead?
 enum FragCalcResult { UseFrag, UseNoFrag, Skip };
 static FragCalcResult
 calculateFragment(DILocalVariable *Variable,

diff  --git a/llvm/test/DebugInfo/Generic/assignment-tracking/dse/dse-after-memcpyopt-merge.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/dse/dse-after-memcpyopt-merge.ll
index f1704f4bcc98b..0d6f6fd910595 100644
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/dse/dse-after-memcpyopt-merge.ll
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/dse/dse-after-memcpyopt-merge.ll
@@ -1,4 +1,4 @@
-; RUN: opt %s -S -passes=dse -o - | FileCheck %s --implicit-check-not="call void @llvm.dbg"
+; RUN: opt %s -S -passes=dse -o - | FileCheck %s
 
 ;; Observed in the wild, but test is created by running memcpyopt on
 ;; assignment-tracking/memcpyopt/merge-stores.ll then manually inserting
@@ -7,17 +7,19 @@
 ;; A memory intrinsic (or vector instruction) might have multiple dbg.assigns
 ;; linked to it if it has been created as a result of merging scalar stores,
 ;; such as in this example. DSE is going to shorten the memset because there's
-;; a later store that overwrites part of it. Unlink the dbg.assigns that
-;; describe the overlapping fragments.
+;; a later store that overwrites part of it. Insert a linked dbg.assign after
+;; each overlapping fragment to undef the dead part's memory location without
+;; needing to work out how to split the fragments exactly.
 
 ;; Check that there's an unlinked dbg.assign inserted after each overlapping
 ;; fragment of the shortened store.
 ;;
-; CHECK: llvm.dbg.assign({{.*}}, metadata ptr %g, metadata !DIExpression())
-; CHECK: llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32), metadata ![[ID:[0-9]+]], metadata ptr %arrayidx.i, metadata !DIExpression())
-; CHECK: llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata ![[ID]], metadata ptr %arrayidx3.i, metadata !DIExpression())
-; CHECK: llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata ![[UniqueID1:[0-9]+]], metadata ptr undef, metadata !DIExpression())
-; CHECK: llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[#]], metadata !DIExpression(DW_OP_LLVM_fragment, 96, 32), metadata ![[UniqueID2:[0-9]+]], metadata ptr undef, metadata !DIExpression())
+; CHECK:      call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[VAR:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata ![[ID:[0-9]+]], metadata ptr %arrayidx5.i, metadata !DIExpression())
+; CHECK-NEXT: call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[VAR]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata ![[UniqueID1:[0-9]+]], metadata ptr undef, metadata !DIExpression())
+
+; CHECK:      call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[VAR]], metadata !DIExpression(DW_OP_LLVM_fragment, 96, 32), metadata ![[ID]], metadata ptr %arrayidx7.i, metadata !DIExpression())
+; CHECK-NEXT: call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata ![[VAR]], metadata !DIExpression(DW_OP_LLVM_fragment, 96, 32), metadata ![[UniqueID2:[0-9]+]], metadata ptr undef, metadata !DIExpression())
+
 ; CHECK: call void @llvm.memset{{.*}}, !DIAssignID ![[ID]]
 
 ; CHECK-DAG: ![[ID]] = distinct !DIAssignID()
@@ -32,7 +34,10 @@ define dso_local void @_Z1fv() local_unnamed_addr !dbg !7 {
 entry:
   %g = alloca %struct.v, align 4, !DIAssignID !23
   call void @llvm.dbg.assign(metadata i1 undef, metadata !11, metadata !DIExpression(), metadata !23, metadata ptr %g, metadata !DIExpression()), !dbg !24
-   %arrayidx.i = getelementptr inbounds %struct.v, ptr %g, i64 0, i32 0, i64 2, !dbg !37
+  call void @llvm.lifetime.start.p0i8(i64 16, ptr nonnull %g), !dbg !25
+  call void @llvm.dbg.assign(metadata ptr %g, metadata !26, metadata !DIExpression(), metadata !35, metadata ptr undef, metadata !DIExpression()), !dbg !32
+  call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata !29, metadata !DIExpression(), metadata !36, metadata ptr undef, metadata !DIExpression()), !dbg !32
+  %arrayidx.i = getelementptr inbounds %struct.v, ptr %g, i64 0, i32 0, i64 2, !dbg !37
   call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 32), metadata !39, metadata ptr %arrayidx.i, metadata !DIExpression()), !dbg !24
   %arrayidx3.i = getelementptr inbounds %struct.v, ptr %g, i64 0, i32 0, i64 1, !dbg !40
   call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 32, 32), metadata !39, metadata ptr %arrayidx3.i, metadata !DIExpression()), !dbg !24
@@ -45,14 +50,19 @@ entry:
   ;; -- Start modification
   %arrayidx7 = getelementptr inbounds %struct.v, ptr %g, i64 0, i32 0, i64 3, !dbg !24
   store float 0.000000e+00, ptr %arrayidx7, align 4, !dbg !24, !DIAssignID !49
+  call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 96, 32), metadata !49, metadata ptr %arrayidx7, metadata !DIExpression()), !dbg !24
   %arrayidx = getelementptr inbounds %struct.v, ptr %g, i64 0, i32 0, i64 0, !dbg !24
   store float 0.000000e+00, ptr %arrayidx, align 4, !dbg !24, !DIAssignID !50
+  call void @llvm.dbg.assign(metadata float 0.000000e+00, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 0, 32), metadata !50, metadata ptr %arrayidx, metadata !DIExpression()), !dbg !24
   ;; -- End modification
   call void @_Z3escP1v(ptr nonnull %g), !dbg !43
+  call void @llvm.lifetime.end.p0i8(i64 16, ptr nonnull %0), !dbg !45
   ret void, !dbg !45
 }
 
+declare void @llvm.lifetime.start.p0i8(i64 immarg, ptr nocapture)
 declare !dbg !64 dso_local void @_Z3escP1v(ptr) local_unnamed_addr
+declare void @llvm.lifetime.end.p0i8(i64 immarg, ptr nocapture)
 declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
 declare void @llvm.memset.p0i8.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
 

diff  --git a/llvm/test/DebugInfo/Generic/assignment-tracking/dse/shorten-offset.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/dse/shorten-offset.ll
deleted file mode 100644
index b6dc56acf7636..0000000000000
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/dse/shorten-offset.ll
+++ /dev/null
@@ -1,134 +0,0 @@
-; RUN: opt %s -S -passes=dse -o - | FileCheck %s --implicit-check-not="call void @llvm.dbg"
-
-;; Based on the test shorten.ll with some adjustments.
-;;
-;; $ cat test.cpp
-;; void esc(char*);
-;; void shortenEnd() {
-;;   char local[80];                      //        bits    frag
-;;   __builtin_memset(local + 8,  0, 24); // local:  64-160 ( 64, 96)
-;;   __builtin_memset(local + 16, 8, 40); // local: 128-160 (128, 32)
-;;   esc(local);
-;; }
-;; void shortenStart() {
-;;   char local2[40];                 //          bits   frag
-;;   __builtin_memset(local2, 0, 40); // local2:  0-160  (0, 160)
-;;   __builtin_memset(local2, 8, 16); // local2:  0-128  (0, 128)
-;;   esc(local2);
-;; }
-
-;; The variables and intrinsics have been adjusted with by hand to test
-;; what happens when the variable doesn't fill the whole alloca, and
-;; when offsets are encoded with both the address component of the dbg.assign
-;; and the address modifying DIExpression.
-
-;; DeadStoreElimination will shorten the first store in shortenEnd from [64,
-;; 192) bits to [64, 128) bits. Variable 'local' has been adjusted to be 160
-;; bits large. Check that we get an unlinked dbg.assign covering the deleted
-;; bits that overlap the dbg.assign's fagment: [128, 160) (offset=128 size=32).
-
-; CHECK: @_Z10shortenEndv
-; CHECK:      call void @llvm.dbg.assign({{.*}}, metadata ptr %local, metadata !DIExpression())
-; CHECK:      call void @llvm.memset{{.*}}, !DIAssignID ![[ID:[0-9]+]]
-; CHECK-NEXT: call void @llvm.dbg.assign(metadata i8 0, metadata ![[VAR:[0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 96), metadata ![[ID:[0-9]+]], metadata ptr %offset_4_bytes, metadata !DIExpression(DW_OP_plus_uconst, 4))
-; CHECK-NEXT: call void @llvm.dbg.assign(metadata i8 0, metadata ![[VAR]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32), metadata ![[UniqueID1:[0-9]+]], metadata ptr undef, metadata !DIExpression({{.*}}))
-
-;; DSE will shorten the first store in shortenStart from [0, 160) bits to [128,
-;; 160) bits. Variable 'local2' has been adjusted to be 160 bits.  Check we get
-;; an unlinked dbg.assign covering the deleted bits that overlap the
-;; dbg.assign's fragment (no fragment in this case, i.e. the whole variable):
-;; [0, 128) (offset=0, size=128).
-
-; CHECK: @_Z12shortenStartv
-; CHECK:      call void @llvm.dbg.assign({{.*}}, metadata ptr %local2, metadata !DIExpression())
-; CHECK:      call void @llvm.memset{{.*}}, !DIAssignID ![[ID2:[0-9]+]]
-; CHECK-NEXT: call void @llvm.dbg.assign(metadata i8 0, metadata ![[VAR2:[0-9]+]], metadata !DIExpression(), metadata ![[ID2]], metadata ptr %local2, metadata !DIExpression())
-; CHECK-NEXT: call void @llvm.dbg.assign(metadata i8 0, metadata ![[VAR2]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128), metadata ![[UniqueID2:[0-9]+]], metadata ptr undef, metadata !DIExpression())
-
-; CHECK-DAG: ![[ID]] = distinct !DIAssignID()
-; CHECK-DAG: ![[UniqueID1]] = distinct !DIAssignID()
-; CHECK-DAG: ![[UniqueID2]] = distinct !DIAssignID()
-
-define dso_local void @_Z10shortenEndv() local_unnamed_addr #0 !dbg !7 {
-entry:
-  %local = alloca [80 x i8], align 16, !DIAssignID !16
-  call void @llvm.dbg.assign(metadata i1 undef, metadata !11, metadata !DIExpression(), metadata !16, metadata ptr %local, metadata !DIExpression()), !dbg !17
-  %arraydecay = getelementptr inbounds [80 x i8], ptr %local, i64 0, i64 0, !dbg !19
-  %offset_4_bytes = getelementptr inbounds [80 x i8], ptr %local, i64 0, i64 4, !dbg !21
-  %offset_8_bytes = getelementptr inbounds [80 x i8], ptr %local, i64 0, i64 8, !dbg !21
-  call void @llvm.memset.p0i8.i64(ptr noundef nonnull align 16 dereferenceable(24) %offset_8_bytes, i8 0, i64 72, i1 false), !dbg !19, !DIAssignID !20
-  call void @llvm.dbg.assign(metadata i8 0, metadata !11, metadata !DIExpression(DW_OP_LLVM_fragment, 64, 96), metadata !20, metadata ptr %offset_4_bytes, metadata !DIExpression(DW_OP_plus_uconst, 4)), !dbg !17
-  %offset_16_bytes = getelementptr inbounds [80 x i8], ptr %local, i64 0, i64 4, !dbg !21
-  call void @llvm.memset.p0i8.i64(ptr noundef nonnull align 16 dereferenceable(40) %offset_16_bytes, i8 8, i64 64, i1 false), !dbg !22, !DIAssignID !23
-  call void @_Z3escPi(ptr noundef nonnull %arraydecay), !dbg !24
-  ret void, !dbg !25
-}
-
-declare void @llvm.memset.p0i8.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
-declare !dbg !26 dso_local void @_Z3escPi(ptr noundef) local_unnamed_addr
-
-define dso_local void @_Z12shortenStartv() local_unnamed_addr #0 !dbg !31 {
-entry:
-  %local2 = alloca [40 x i8], align 16, !DIAssignID !37
-  call void @llvm.dbg.assign(metadata i1 undef, metadata !33, metadata !DIExpression(), metadata !37, metadata ptr %local2, metadata !DIExpression()), !dbg !38
-  %arraydecay = getelementptr inbounds [40 x i8], ptr %local2, i64 0, i64 0, !dbg !40
-  call void @llvm.memset.p0i8.i64(ptr noundef nonnull align 16 dereferenceable(40) %local2, i8 0, i64 36, i1 false), !dbg !40, !DIAssignID !41
-  call void @llvm.dbg.assign(metadata i8 0, metadata !33, metadata !DIExpression(), metadata !41, metadata ptr %local2, metadata !DIExpression()), !dbg !38
-  call void @llvm.memset.p0i8.i64(ptr noundef nonnull align 16 dereferenceable(16) %local2, i8 8, i64 16, i1 false), !dbg !42, !DIAssignID !43
-  call void @_Z3escPi(ptr noundef nonnull %arraydecay), !dbg !44
-  ret void, !dbg !45
-}
-
-declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!2, !3, !4, !5, !1000}
-!llvm.ident = !{!6}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
-!1 = !DIFile(filename: "test.cpp", directory: "/")
-!2 = !{i32 7, !"Dwarf Version", i32 5}
-!3 = !{i32 2, !"Debug Info Version", i32 3}
-!4 = !{i32 1, !"wchar_size", i32 4}
-!5 = !{i32 7, !"uwtable", i32 1}
-!6 = !{!"clang version 14.0.0"}
-!7 = distinct !DISubprogram(name: "shortenEnd", linkageName: "_Z10shortenEndv", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
-!8 = !DISubroutineType(types: !9)
-!9 = !{null}
-!10 = !{!11}
-!11 = !DILocalVariable(name: "local", scope: !7, file: !1, line: 3, type: !12)
-!12 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 160, elements: !14)
-!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!14 = !{!15}
-!15 = !DISubrange(count: 5)
-!16 = distinct !DIAssignID()
-!17 = !DILocation(line: 0, scope: !7)
-!18 = !DILocation(line: 3, column: 3, scope: !7)
-!19 = !DILocation(line: 4, column: 3, scope: !7)
-!20 = distinct !DIAssignID()
-!21 = !DILocation(line: 5, column: 26, scope: !7)
-!22 = !DILocation(line: 5, column: 3, scope: !7)
-!23 = distinct !DIAssignID()
-!24 = !DILocation(line: 6, column: 3, scope: !7)
-!25 = !DILocation(line: 7, column: 1, scope: !7)
-!26 = !DISubprogram(name: "esc", linkageName: "_Z3escPi", scope: !1, file: !1, line: 1, type: !27, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !30)
-!27 = !DISubroutineType(types: !28)
-!28 = !{null, !29}
-!29 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
-!30 = !{}
-!31 = distinct !DISubprogram(name: "shortenStart", linkageName: "_Z12shortenStartv", scope: !1, file: !1, line: 8, type: !8, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !32)
-!32 = !{!33}
-!33 = !DILocalVariable(name: "local2", scope: !31, file: !1, line: 9, type: !34)
-!34 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 160, elements: !35)
-!35 = !{!36}
-!36 = !DISubrange(count: 5)
-!37 = distinct !DIAssignID()
-!38 = !DILocation(line: 0, scope: !31)
-!39 = !DILocation(line: 9, column: 3, scope: !31)
-!40 = !DILocation(line: 10, column: 3, scope: !31)
-!41 = distinct !DIAssignID()
-!42 = !DILocation(line: 11, column: 3, scope: !31)
-!43 = distinct !DIAssignID()
-!44 = !DILocation(line: 12, column: 3, scope: !31)
-!45 = !DILocation(line: 13, column: 1, scope: !31)
-!1000 = !{i32 7, !"debug-info-assignment-tracking", i1 true}


        


More information about the llvm-commits mailing list