[llvm] Handle llvm.dbg.values in SROA. (PR #94070)

via llvm-commits llvm-commits at lists.llvm.org
Fri May 31 15:38:09 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Shubham Sandeep Rastogi (rastogishubham)

<details>
<summary>Changes</summary>

This patch properly handles llvm.dbg.values in SROA by making sure that any llvm.dbg.values get moved to before a store just like llvm.dbg.declares do, or the llvm.dbg.value is correctly updated with the right alloca after an aggregate alloca is broken up.

This is part of a stack of patches and is preceded by: https://github.com/llvm/llvm-project/pull/94068

---

Patch is 133.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/94070.diff


12 Files Affected:

- (modified) llvm/include/llvm/IR/DebugInfo.h (+2) 
- (modified) llvm/include/llvm/IR/DebugProgramInstruction.h (+5) 
- (modified) llvm/include/llvm/IR/IntrinsicInst.h (+7) 
- (modified) llvm/include/llvm/Transforms/Utils/Local.h (+7) 
- (modified) llvm/lib/IR/DebugInfo.cpp (+17) 
- (modified) llvm/lib/Transforms/Scalar/SROA.cpp (+14) 
- (modified) llvm/lib/Transforms/Utils/Local.cpp (+28) 
- (modified) llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp (+3) 
- (modified) llvm/test/DebugInfo/X86/sroa-after-inlining.ll (+3-1) 
- (added) llvm/test/DebugInfo/sroa-handle-dbg-value.ll (+263) 
- (modified) llvm/test/Transforms/SROA/alignment.ll (+131-131) 
- (modified) llvm/test/Transforms/SROA/vector-promotion.ll (+253-250) 


``````````diff
diff --git a/llvm/include/llvm/IR/DebugInfo.h b/llvm/include/llvm/IR/DebugInfo.h
index 5b80218d6c5cc..73f45c3769be4 100644
--- a/llvm/include/llvm/IR/DebugInfo.h
+++ b/llvm/include/llvm/IR/DebugInfo.h
@@ -43,6 +43,8 @@ class Module;
 TinyPtrVector<DbgDeclareInst *> findDbgDeclares(Value *V);
 /// As above, for DVRDeclares.
 TinyPtrVector<DbgVariableRecord *> findDVRDeclares(Value *V);
+/// As above, for DVRValues.
+TinyPtrVector<DbgVariableRecord *> findDVRValues(Value *V);
 
 /// Finds the llvm.dbg.value intrinsics describing a value.
 void findDbgValues(
diff --git a/llvm/include/llvm/IR/DebugProgramInstruction.h b/llvm/include/llvm/IR/DebugProgramInstruction.h
index ed8081a3cad19..72ff8f20d9006 100644
--- a/llvm/include/llvm/IR/DebugProgramInstruction.h
+++ b/llvm/include/llvm/IR/DebugProgramInstruction.h
@@ -426,6 +426,11 @@ class DbgVariableRecord : public DbgRecord, protected DebugValueUser {
   /// Does this describe the address of a local variable. True for dbg.addr
   /// and dbg.declare, but not dbg.value, which describes its value.
   bool isAddressOfVariable() const { return Type == LocationType::Declare; }
+
+  /// Does this describe the value of a local variable. False for dbg.addr
+  /// and dbg.declare, but not True dbg.value, which describes its value.
+  bool isValueOfVariable() const { return Type == LocationType::Value; }
+
   LocationType getType() const { return Type; }
 
   void setKillLocation();
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index fcd3a1025ac13..7168a17212313 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -341,6 +341,13 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
     return getIntrinsicID() == Intrinsic::dbg_declare;
   }
 
+  /// Does this describe the value of a local variable. True for dbg.value,
+  /// but not dbg.declare, which describes its address, or dbg.assign, which
+  /// describes a combination of the variable's value and address.
+  bool isValueOfVariable() const {
+    return getIntrinsicID() == Intrinsic::dbg_value;
+  }
+
   void setKillLocation() {
     // TODO: When/if we remove duplicate values from DIArgLists, we don't need
     // this set anymore.
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 6937ec8dfd21c..d9ec9913eeb58 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -259,6 +259,13 @@ CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
 ///  Dbg Intrinsic utilities
 ///
 
+/// Moves an llvm.dbg.value intrinsic before a store to an alloca'd value
+/// that has an associated llvm.dbg.value intrinsic.
+void MoveDebugValueToStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
+                              DIBuilder &Builder);
+void MoveDebugValueToStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI,
+                              DIBuilder &Builder);
+
 /// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
 void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 4c3f37ceaaa46..dc3dad91db8f4 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -80,6 +80,23 @@ TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) {
   return Declares;
 }
 
+TinyPtrVector<DbgVariableRecord *> llvm::findDVRValues(Value *V) {
+  // This function is hot. Check whether the value has any metadata to avoid a
+  // DenseMap lookup.
+  if (!V->isUsedByMetadata())
+    return {};
+  auto *L = LocalAsMetadata::getIfExists(V);
+  if (!L)
+    return {};
+
+  TinyPtrVector<DbgVariableRecord *> Values;
+  for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())
+    if (DVR->getType() == DbgVariableRecord::LocationType::Value)
+      Values.push_back(DVR);
+
+  return Values;
+}
+
 template <typename IntrinsicT, bool DbgAssignAndValuesOnly>
 static void
 findDbgIntrinsics(SmallVectorImpl<IntrinsicT *> &Result, Value *V,
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 756daf5bb41fa..7322af9d023bb 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -5045,10 +5045,20 @@ static void insertNewDbgInst(DIBuilder &DIB, DbgVariableRecord *Orig,
                                                    BeforeInst->getIterator());
     return;
   }
+
+  if (Orig->isDbgValue()) {
+    DbgVariableRecord *DVR = DbgVariableRecord::createDbgVariableRecord(
+        NewAddr, Orig->getVariable(), NewFragmentExpr, Orig->getDebugLoc());
+    BeforeInst->getParent()->insertDbgRecordBefore(DVR,
+                                                   BeforeInst->getIterator());
+    return;
+  }
+
   if (!NewAddr->hasMetadata(LLVMContext::MD_DIAssignID)) {
     NewAddr->setMetadata(LLVMContext::MD_DIAssignID,
                          DIAssignID::getDistinct(NewAddr->getContext()));
   }
+
   DbgVariableRecord *NewAssign = DbgVariableRecord::createLinkedDVRAssign(
       NewAddr, Orig->getValue(), Orig->getVariable(), NewFragmentExpr, NewAddr,
       Orig->getAddressExpression(), Orig->getDebugLoc());
@@ -5221,6 +5231,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
       };
       for_each(findDbgDeclares(Fragment.Alloca), RemoveOne);
       for_each(findDVRDeclares(Fragment.Alloca), RemoveOne);
+      for_each(findDVRValues(Fragment.Alloca), RemoveOne);
 
       insertNewDbgInst(DIB, DbgVariable, Fragment.Alloca, FragmentExpr, &AI);
     }
@@ -5230,6 +5241,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
   // and the individual partitions.
   for_each(findDbgDeclares(&AI), MigrateOne);
   for_each(findDVRDeclares(&AI), MigrateOne);
+  for_each(findDVRValues(&AI), MigrateOne);
   for_each(at::getAssignmentMarkers(&AI), MigrateOne);
   for_each(at::getDVRAssignmentMarkers(&AI), MigrateOne);
 
@@ -5357,6 +5369,8 @@ bool SROA::deleteDeadInstructions(
         OldDII->eraseFromParent();
       for (DbgVariableRecord *OldDII : findDVRDeclares(AI))
         OldDII->eraseFromParent();
+      for (DbgVariableRecord *OldDII : findDVRValues(AI))
+        OldDII->eraseFromParent();
     }
 
     at::deleteAssignmentMarkers(I);
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index ce0f4c7668a40..f90ee060ba3e3 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1731,6 +1731,21 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
                                     SI->getIterator());
 }
 
+/// Moves an llvm.dbg.value intrinsic before a store to an alloca'd value
+/// that has an associated llvm.dbg.value intrinsic.
+void llvm::MoveDebugValueToStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI,
+                                    DIBuilder &Builder) {
+  auto *DIVar = DII->getVariable();
+  assert(DIVar && "Missing variable");
+  auto *DIExpr = DII->getExpression();
+  Value *DV = SI->getValueOperand();
+
+  DebugLoc NewLoc = getDebugValueLoc(DII);
+
+  insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
+                                    SI->getIterator());
+}
+
 /// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
 /// that has an associated llvm.dbg.declare intrinsic.
 void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
@@ -1805,6 +1820,19 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
   SI->getParent()->insertDbgRecordBefore(NewDVR, SI->getIterator());
 }
 
+void llvm::MoveDebugValueToStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
+                                    DIBuilder &Builder) {
+  auto *DIVar = DVR->getVariable();
+  assert(DIVar && "Missing variable");
+  auto *DIExpr = DVR->getExpression();
+  Value *DV = SI->getValueOperand();
+
+  DebugLoc NewLoc = getDebugValueLoc(DVR);
+
+  insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
+                                    SI->getIterator());
+}
+
 /// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
 /// llvm.dbg.declare intrinsic.
 void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 40d0f6b75d69b..47a3066b5d818 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -582,6 +582,9 @@ rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI,
         DbgItem->eraseFromParent();
       } else if (DbgItem->getExpression()->startsWithDeref()) {
         DbgItem->eraseFromParent();
+      } else if (DbgItem->isValueOfVariable()) {
+        MoveDebugValueToStoreLoc(DbgItem, Info.OnlyStore, DIB);
+        DbgItem->eraseFromParent();
       }
     }
   };
diff --git a/llvm/test/DebugInfo/X86/sroa-after-inlining.ll b/llvm/test/DebugInfo/X86/sroa-after-inlining.ll
index d8f2c9a3ade0d..1cd78c7fd85a5 100644
--- a/llvm/test/DebugInfo/X86/sroa-after-inlining.ll
+++ b/llvm/test/DebugInfo/X86/sroa-after-inlining.ll
@@ -35,9 +35,11 @@
 ; CHECK: _Z3barv
 ; CHECK: %[[RESULT:.*]] = call i32 @_Z3foov
 ; CHECK: llvm.dbg.value(metadata i32 %[[RESULT]], metadata [[METADATA_IDX1:![0-9]+]]
+; CHECK: llvm.dbg.value(metadata i32 %[[RESULT]], metadata [[METADATA_IDX2:![0-9]+]]
 ; CHECK: ret
 ; CHECK: DICompileUnit
-; CHECK: [[METADATA_IDX1]] = !DILocalVariable(name: "result"
+; CHECK: [[METADATA_IDX2]] = !DILocalVariable(name: "result"
+; CHECK: [[METADATA_IDX1]] = !DILocalVariable(name: "this"
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
diff --git a/llvm/test/DebugInfo/sroa-handle-dbg-value.ll b/llvm/test/DebugInfo/sroa-handle-dbg-value.ll
new file mode 100644
index 0000000000000..0a2f25409c341
--- /dev/null
+++ b/llvm/test/DebugInfo/sroa-handle-dbg-value.ll
@@ -0,0 +1,263 @@
+; This test was obtained from swift source code and then automatically reducing it via Delta.
+; The swift source code was from the test test/DebugInfo/debug_scope_distinct.swift.
+
+; RUN: opt %s -S -p=sroa -o - | FileCheck %s
+; CHECK: [[SROA_5_SROA_21:%.*]] = alloca [7 x i8], align 8
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_21]], metadata [[META59:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 72, 56)), !dbg [[DBG72:![0-9]+]]
+; CHECK-NEXT: [[SROA_5_SROA_14:%.*]] = alloca [7 x i8], align 8
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_14]], metadata [[META68:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 72, 56)), !dbg [[DBG72]]
+; CHECK-NEXT: [[SROA_5_SROA_7:%.*]] = alloca [7 x i8], align 8
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_7]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 72, 56)), !dbg [[DBG74:![0-9]+]]
+; CHECK-NEXT: [[SROA_5_SROA_0:%.*]] = alloca [7 x i8], align 8
+
+; CHECK: tail call void @llvm.dbg.value(metadata ptr [[REG2:%[0-9]+]], metadata [[META54:![0-9]+]], metadata !DIExpression(DW_OP_deref)), !dbg [[DBG78:![0-9]+]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[REG2:%[0-9]+]], metadata [[META56:![0-9]+]], metadata !DIExpression(DW_OP_deref)), !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i64 0, metadata [[META57:![0-9]+]], metadata !DIExpression()), !dbg [[DBG78]]
+
+; CHECK: [[SROA_418_SROA_COPYLOAD:%.*]] = load i8, ptr [[SROA_418_0_U1_IDX:%.*]], align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_418_SROA_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG72]]
+
+; CHECK: [[SROA_5_SROA_322_COPYLOAD:%.*]] = load ptr, ptr [[SROA_5_322_SROA_5_U1_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_322_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 64)), !dbg [[DBG72]]
+
+; CHECK: [[SROA_5_SROA_423_COPYLOAD:%.*]] = load i8, ptr [[SROA_5_423_SROA_5_U1_IDX_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_423_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg [[DBG72]]
+
+; CHECK: [[SROA_10_0_COPYLOAD:%.*]] = load ptr, ptr [[U11:%.*]], align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_10_0_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG72]]
+
+; CHECK: [[SROA_411_0_COPYLOAD:%.*]] = load i8, ptr [[SROA_411_U11_IDX:%.*]], align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_411_0_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG72]]
+
+; CHECK: [[SROA_5_SROA_315_COPYLOAD:%.*]] = load ptr, ptr [[SROA_5_SROA_311_U1_IDX_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_315_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 64)), !dbg [[DBG72]]
+
+; CHECK: [[SROA_5_SROA_416_COPYLOAD:%.*]] = load i8, ptr [[SROA_5_SROA_411_U11_IDX_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_416_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg [[DBG72]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_322_COPYLOAD]], metadata [[META79:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG92:![0-9]+]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_423_COPYLOAD]], metadata [[META79]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG92]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_315_COPYLOAD]], metadata [[META88:![0-9]+]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG92]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_416_COPYLOAD]], metadata [[META88]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG92]]
+
+; CHECK: [[SROA_3_0_COPYLOAD:%.*]] = load ptr, ptr [[U2:%.*]], align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_3_0_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_44_0_COPYLOAD:%.*]] = load i8, ptr [[SROA_44_U2_IDX:%.*]] align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_44_0_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_5_SROA_38_COPYLOAD:%.*]] = load ptr, ptr [[SROA_5_SROA_38_U2_IDX_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_38_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 64)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_5_SROA_49_COPYLOAD:%.*]] = load i8, ptr [[SROA_5_SROA_49_U2_IDX_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_49_COPYLOAD]], metadata [[META59]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr [[U26:%.*]], align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_0_0_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_4_0_COPYLOAD:%.*]] = load i8, ptr [[SROA_4_0_IDX:%.*]], align 8, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_4_0_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_5_SROA_3_COPYLOAD:%.*]] = load ptr, ptr [[SROA_5_SROA_3_SROA_5_U26_IDX_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_3_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 64)), !dbg [[DBG74]]
+
+; CHECK: [[SROA_5_SROA_4_COPYLOAD:%.*]] = load i8, ptr [[SROA_5_SROA_4_SROA_5_U26_IDX:%.*]], align 1, !dbg [[DBG78]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_4_COPYLOAD]], metadata [[META68]], metadata !DIExpression(DW_OP_LLVM_fragment, 192, 8)), !dbg [[DBG74]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_38_COPYLOAD]], metadata [[META79]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG94:![0-9]+]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_49_COPYLOAD]], metadata [[META79]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG94]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata ptr [[SROA_5_SROA_3_COPYLOAD]], metadata [[META88]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 64)), !dbg [[DBG94]]
+; CHECK-NEXT: tail call void @llvm.dbg.value(metadata i8 [[SROA_5_SROA_4_COPYLOAD]], metadata [[META88]], metadata !DIExpression(DW_OP_LLVM_fragment, 64, 8)), !dbg [[DBG94]]
+
+%T4main1TV13TangentVectorV = type <{ %T4main1UV13TangentVectorV, [7 x i8], %T4main1UV13TangentVectorV }>
+%T4main1UV13TangentVectorV = type <{ %T1M1SVySfG, [7 x i8], %T4main1VV13TangentVectorV }>
+%T1M1SVySfG = type <{ ptr, %Ts4Int8V }>
+%Ts4Int8V = type <{ i8 }>
+%T4main1VV13TangentVectorV = type <{ %T1M1SVySfG }>
+define hidden swiftcc void @"$s4main1TV13TangentVectorV1poiyA2E_AEtFZ"(ptr noalias nocapture sret(%T4main1TV13TangentVectorV) %0, ptr noalias nocapture dereferenceable(57) %1, ptr noalias nocapture dereferenceable(57) %2) #0 !dbg !44 {
+entry:
+  %3 = alloca %T4main1VV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %3, metadata !59, metadata !DIExpression()), !dbg !72
+  %4 = alloca %T4main1UV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %4, metadata !82, metadata !DIExpression()), !dbg !88
+  %5 = alloca %T4main1VV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %5, metadata !68, metadata !DIExpression()), !dbg !72
+  %6 = alloca %T4main1UV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %6, metadata !84, metadata !DIExpression()), !dbg !88
+  %7 = alloca %T4main1VV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %7, metadata !59, metadata !DIExpression()), !dbg !89
+  %8 = alloca %T4main1UV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %8, metadata !82, metadata !DIExpression()), !dbg !92
+  %9 = alloca %T4main1VV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %9, metadata !68, metadata !DIExpression()), !dbg !89
+  %10 = alloca %T4main1UV13TangentVectorV, align 8
+  tail call void @llvm.dbg.value(metadata ptr %10, metadata !84, metadata !DIExpression()), !dbg !92
+  call void @llvm.lifetime.start.p0(i64 9, ptr %3)
+  call void @llvm.lifetime.start.p0(i64 25, ptr %4)
+  call void @llvm.lifetime.start.p0(i64 9, ptr %5)
+  call void @llvm.lifetime.start.p0(i64 25, ptr %6), !dbg !93
+  call void @llvm.lifetime.start.p0(i64 9, ptr %7)
+  call void @llvm.lifetime.start.p0(i64 25, ptr %8)
+  call void @llvm.lifetime.start.p0(i64 9, ptr %9)
+  call void @llvm.lifetime.start.p0(i64 25, ptr %10)
+  tail call void @llvm.dbg.value(metadata ptr %1, metadata !54, metadata !DIExpression(DW_OP_deref)), !dbg !95
+  tail call void @llvm.dbg.value(metadata ptr %2, metadata !56, metadata !DIExpression(DW_OP_deref)), !dbg !95
+  tail call void @llvm.dbg.value(metadata i64 0, metadata !57, metadata !DIExpression()), !dbg !95
+  %.u1 = getelementptr inbounds %T4main1TV13TangentVectorV, ptr %1, i32 0, i32 0
+  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %4, ptr align 8 %.u1, i64 25, i1 false), !dbg !95
+  %.u11 = getelementptr inbounds %T4main1TV13TangentVectorV, ptr %2, i32 0, i32 0
+  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %6, ptr align 8 %.u11, i64 25, i1 false), !dbg !95
+  %.s = getelementptr inbounds %T4main1UV13TangentVectorV, ptr %4, i32 0, i32 0
+  %.s.c = getelementptr inbounds %T1M1SVySfG, ptr %.s, i32 0, i32 0
+  %11 = load ptr, ptr %.s.c, align 8
+  %.s.b = getelementptr inbounds %...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/94070


More information about the llvm-commits mailing list