[llvm] [RemoveDIs] Handle DPValues in FastISel (PR #76952)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 4 05:57:34 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Orlando Cazalet-Hyams (OCHyams)

<details>
<summary>Changes</summary>

The change is fairly mechanical:
1. Factor code from `FastISel::selectIntrinsicCall`, which converts debug intrinsics into debug instructions, into functions (NFC).
2. Call those functions for DPValues attached to instructions too.

The test updates look the same as other RemoveDIs changes: re-run the tests with `--try-experimental-debuginfo-iterators`, which checks the output is identical using the new debug info format (if it has been enabled in the cmake configuration).

---

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


74 Files Affected:

- (modified) llvm/include/llvm/CodeGen/FastISel.h (+14) 
- (modified) llvm/lib/CodeGen/SelectionDAG/FastISel.cpp (+188-135) 
- (modified) llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (+4) 
- (modified) llvm/test/CodeGen/AArch64/fast-isel-branch-uncond-debug.ll (+2-1) 
- (modified) llvm/test/CodeGen/AArch64/fast-isel-dbg.ll (+2) 
- (modified) llvm/test/CodeGen/AArch64/fastisel-debugvalue-undef.ll (+1) 
- (modified) llvm/test/CodeGen/ARM/debug-info-blocks.ll (+1) 
- (modified) llvm/test/CodeGen/Generic/csw-debug-assert.ll (+1) 
- (modified) llvm/test/CodeGen/X86/2010-08-04-StackVariable.ll (+1) 
- (modified) llvm/test/CodeGen/X86/DbgValueOtherTargets.test (+3) 
- (modified) llvm/test/CodeGen/X86/fast-isel-dbg-value-alloca.ll (+2) 
- (modified) llvm/test/CodeGen/X86/fold-sext-trunc.ll (+4) 
- (modified) llvm/test/CodeGen/X86/fold-zext-trunc.ll (+4) 
- (modified) llvm/test/CodeGen/X86/label-heapallocsite.ll (+3) 
- (modified) llvm/test/CodeGen/X86/machine-outliner-disubprogram.ll (+1) 
- (modified) llvm/test/CodeGen/X86/pr53243-tail-call-fastisel.ll (+1) 
- (modified) llvm/test/CodeGen/X86/sink-local-value.ll (+1) 
- (modified) llvm/test/DebugInfo/AArch64/cfi-eof-prologue.ll (+1) 
- (modified) llvm/test/DebugInfo/AArch64/frameindices.ll (+1) 
- (modified) llvm/test/DebugInfo/ARM/split-complex.ll (+5-2) 
- (modified) llvm/test/DebugInfo/COFF/class-options-common.ll (+5) 
- (modified) llvm/test/DebugInfo/COFF/cpp-mangling.ll (+4-1) 
- (modified) llvm/test/DebugInfo/COFF/enum-co.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/function-options.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/global_visibility.ll (+1) 
- (modified) llvm/test/DebugInfo/COFF/globals.ll (+8) 
- (modified) llvm/test/DebugInfo/COFF/lambda.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/lines-bb-start.ll (+1) 
- (modified) llvm/test/DebugInfo/COFF/nrvo.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/numeric-leaves.ll (+5) 
- (modified) llvm/test/DebugInfo/COFF/parent-type-scopes.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/purge-typedef-udts.ll (+1) 
- (modified) llvm/test/DebugInfo/COFF/thunk.ll (+6-1) 
- (modified) llvm/test/DebugInfo/COFF/type-quals.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/types-cvarargs.ll (+3) 
- (modified) llvm/test/DebugInfo/COFF/types-integer-old.ll (+1) 
- (modified) llvm/test/DebugInfo/COFF/types-method-ref-qualifiers.ll (+3) 
- (modified) llvm/test/DebugInfo/Generic/2010-10-01-crash.ll (+1) 
- (modified) llvm/test/DebugInfo/Generic/PR20038.ll (+1) 
- (modified) llvm/test/DebugInfo/Generic/dead-argument-order.ll (+1) 
- (modified) llvm/test/DebugInfo/Generic/discriminated-union.ll (+3) 
- (modified) llvm/test/DebugInfo/Generic/disubrange_vla.ll (+7) 
- (modified) llvm/test/DebugInfo/Generic/enum-types.ll (+1) 
- (modified) llvm/test/DebugInfo/Generic/enum.ll (+3) 
- (modified) llvm/test/DebugInfo/Generic/import-inlined-declaration.ll (+2) 
- (modified) llvm/test/DebugInfo/Generic/inlined-vars.ll (+2) 
- (modified) llvm/test/DebugInfo/Generic/recursive_inlining.ll (+1) 
- (modified) llvm/test/DebugInfo/Generic/univariant-discriminated-union.ll (+3) 
- (modified) llvm/test/DebugInfo/Mips/delay-slot.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/aligned_stack_var.ll (+3) 
- (modified) llvm/test/DebugInfo/X86/arguments.ll (+3) 
- (modified) llvm/test/DebugInfo/X86/asan_debug_info.ll (+1-1) 
- (modified) llvm/test/DebugInfo/X86/byvalstruct.ll (+2) 
- (modified) llvm/test/DebugInfo/X86/convert-linked.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/dbg-declare-arg.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll (+5) 
- (modified) llvm/test/DebugInfo/X86/dbg-declare.ll (+5) 
- (modified) llvm/test/DebugInfo/X86/dbg_value_direct.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/debug-info-template-parameter.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/debug_value_list_selectiondag.ll (+6) 
- (modified) llvm/test/DebugInfo/X86/double-declare.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/fi-piece.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/implicit_value-double.ll (+4) 
- (modified) llvm/test/DebugInfo/X86/instr-ref-opt-levels.ll (+11) 
- (modified) llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll (+15) 
- (modified) llvm/test/DebugInfo/X86/missing-abstract-variable.ll (+1-1) 
- (modified) llvm/test/DebugInfo/X86/parameters.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/pieces-1.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/reference-argument.ll (+2) 
- (modified) llvm/test/DebugInfo/X86/spill-indirect-nrvo.ll (+2-4) 
- (modified) llvm/test/DebugInfo/X86/sret.ll (+3-5) 
- (modified) llvm/test/DebugInfo/X86/subreg.ll (+1) 
- (modified) llvm/test/DebugInfo/X86/subregisters.ll (+3) 
- (modified) llvm/test/DebugInfo/X86/vla.ll (+1) 


``````````diff
diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h
index dc2931b40d352c..35d9aeda378287 100644
--- a/llvm/include/llvm/CodeGen/FastISel.h
+++ b/llvm/include/llvm/CodeGen/FastISel.h
@@ -319,6 +319,8 @@ class FastISel {
   /// Reset InsertPt to the given old insert position.
   void leaveLocalValueArea(SavePoint Old);
 
+  void handleDbgInfo(const Instruction *II);
+
 protected:
   explicit FastISel(FunctionLoweringInfo &FuncInfo,
                     const TargetLibraryInfo *LibInfo,
@@ -342,6 +344,18 @@ class FastISel {
   /// specific intrinsic lowering. It returns true if it was successful.
   virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II);
 
+  /// This method is called by target-independent code to do target-specific
+  /// lowering of debug information. It returns false if the debug information
+  /// couldn't be lowered and was instead discarded.
+  virtual bool lowerDbgValue(const Value *V, DIExpression *Expr,
+                             DILocalVariable *Var, const DebugLoc &DL);
+
+  /// This method is called by target-independent code to do target-specific
+  /// lowering of debug information. It returns false if the debug information
+  /// couldn't be lowered and was instead discarded.
+  virtual bool lowerDbgDeclare(const Value *V, DIExpression *Expr,
+                               DILocalVariable *Var, const DebugLoc &DL);
+
   /// This method is called by target-independent code to request that an
   /// instruction with the given type and opcode be emitted.
   virtual unsigned fastEmit_(MVT VT, MVT RetVT, unsigned Opcode);
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index f3d8edb8926b66..abba685f151a08 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1182,6 +1182,184 @@ bool FastISel::selectCall(const User *I) {
   return lowerCall(Call);
 }
 
+void FastISel::handleDbgInfo(const Instruction *II) {
+  if (!II->hasDbgValues())
+    return;
+
+  // Clear any metadata.
+  MIMD = MIMetadata();
+
+  // Reverse order of debug records, because fast-isel walks through backwards.
+  for (DPValue &DPV : llvm::reverse(II->getDbgValueRange())) {
+    flushLocalValueMap();
+    recomputeInsertPt();
+
+    Value *V = nullptr;
+    if (!DPV.hasArgList())
+      V = DPV.getVariableLocationOp(0);
+
+    bool Res = false;
+    if (DPV.getType() == DPValue::LocationType::Value) {
+      Res = lowerDbgValue(V, DPV.getExpression(), DPV.getVariable(),
+                          DPV.getDebugLoc());
+    } else {
+      assert(DPV.getType() == DPValue::LocationType::Declare);
+      if (FuncInfo.PreprocessedDPVDeclares.contains(&DPV))
+        continue;
+      Res = lowerDbgDeclare(V, DPV.getExpression(), DPV.getVariable(),
+                            DPV.getDebugLoc());
+    }
+
+    if (!Res)
+      LLVM_DEBUG(dbgs() << "Dropping debug-info for " << DPV << "\n";);
+  }
+}
+
+bool FastISel::lowerDbgValue(const Value *V, DIExpression *Expr,
+                             DILocalVariable *Var, const DebugLoc &DL) {
+  // This form of DBG_VALUE is target-independent.
+  const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
+  if (!V || isa<UndefValue>(V)) {
+    // DI is either undef or cannot produce a valid DBG_VALUE, so produce an
+    // undef DBG_VALUE to terminate any prior location.
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, false, 0U, Var, Expr);
+    return true;
+  }
+  if (const auto *CI = dyn_cast<ConstantInt>(V)) {
+    // See if there's an expression to constant-fold.
+    if (Expr)
+      std::tie(Expr, CI) = Expr->constantFold(CI);
+    if (CI->getBitWidth() > 64)
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
+          .addCImm(CI)
+          .addImm(0U)
+          .addMetadata(Var)
+          .addMetadata(Expr);
+    else
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
+          .addImm(CI->getZExtValue())
+          .addImm(0U)
+          .addMetadata(Var)
+          .addMetadata(Expr);
+    return true;
+  }
+  if (const auto *CF = dyn_cast<ConstantFP>(V)) {
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II)
+        .addFPImm(CF)
+        .addImm(0U)
+        .addMetadata(Var)
+        .addMetadata(Expr);
+    return true;
+  }
+  if (const auto *Arg = dyn_cast<Argument>(V);
+      Arg && Expr && Expr->isEntryValue()) {
+    // As per the Verifier, this case is only valid for swift async Args.
+    assert(Arg->hasAttribute(Attribute::AttrKind::SwiftAsync));
+
+    Register Reg = getRegForValue(Arg);
+    for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo->liveins())
+      if (Reg == VirtReg || Reg == PhysReg) {
+        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, false /*IsIndirect*/,
+                PhysReg, Var, Expr);
+        return true;
+      }
+
+    LLVM_DEBUG(dbgs() << "Dropping dbg.value: expression is entry_value but "
+                         "couldn't find a physical register\n");
+    return false;
+  }
+  if (auto SI = FuncInfo.StaticAllocaMap.find(dyn_cast<AllocaInst>(V));
+      SI != FuncInfo.StaticAllocaMap.end()) {
+    MachineOperand FrameIndexOp = MachineOperand::CreateFI(SI->second);
+    bool IsIndirect = false;
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, IsIndirect, FrameIndexOp,
+            Var, Expr);
+    return true;
+  }
+  if (Register Reg = lookUpRegForValue(V)) {
+    // FIXME: This does not handle register-indirect values at offset 0.
+    if (!FuncInfo.MF->useDebugInstrRef()) {
+      bool IsIndirect = false;
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, IsIndirect, Reg, Var,
+              Expr);
+      return true;
+    }
+    // If using instruction referencing, produce this as a DBG_INSTR_REF,
+    // to be later patched up by finalizeDebugInstrRefs.
+    SmallVector<MachineOperand, 1> MOs({MachineOperand::CreateReg(
+        /* Reg */ Reg, /* isDef */ false, /* isImp */ false,
+        /* isKill */ false, /* isDead */ false,
+        /* isUndef */ false, /* isEarlyClobber */ false,
+        /* SubReg */ 0, /* isDebug */ true)});
+    SmallVector<uint64_t, 2> Ops({dwarf::DW_OP_LLVM_arg, 0});
+    auto *NewExpr = DIExpression::prependOpcodes(Expr, Ops);
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+            TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, MOs,
+            Var, NewExpr);
+    return true;
+  }
+  return false;
+}
+
+bool FastISel::lowerDbgDeclare(const Value *Address, DIExpression *Expr,
+                               DILocalVariable *Var, const DebugLoc &DL) {
+  if (!Address || isa<UndefValue>(Address)) {
+    LLVM_DEBUG(dbgs() << "Dropping debug info (bad/undef address)\n");
+    return false;
+  }
+
+  std::optional<MachineOperand> Op;
+  if (Register Reg = lookUpRegForValue(Address))
+    Op = MachineOperand::CreateReg(Reg, false);
+
+  // If we have a VLA that has a "use" in a metadata node that's then used
+  // here but it has no other uses, then we have a problem. E.g.,
+  //
+  //   int foo (const int *x) {
+  //     char a[*x];
+  //     return 0;
+  //   }
+  //
+  // If we assign 'a' a vreg and fast isel later on has to use the selection
+  // DAG isel, it will want to copy the value to the vreg. However, there are
+  // no uses, which goes counter to what selection DAG isel expects.
+  if (!Op && !Address->use_empty() && isa<Instruction>(Address) &&
+      (!isa<AllocaInst>(Address) ||
+       !FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(Address))))
+    Op = MachineOperand::CreateReg(FuncInfo.InitializeRegForValue(Address),
+                                   false);
+
+  if (Op) {
+    assert(Var->isValidLocationForIntrinsic(DL) &&
+           "Expected inlined-at fields to agree");
+    if (FuncInfo.MF->useDebugInstrRef() && Op->isReg()) {
+      // If using instruction referencing, produce this as a DBG_INSTR_REF,
+      // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto
+      // the expression, we don't have an "indirect" flag in DBG_INSTR_REF.
+      SmallVector<uint64_t, 3> Ops(
+          {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_deref});
+      auto *NewExpr = DIExpression::prependOpcodes(Expr, Ops);
+      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+              TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, *Op,
+              Var, NewExpr);
+      return true;
+    }
+
+    // A dbg.declare describes the address of a source variable, so lower it
+    // into an indirect DBG_VALUE.
+    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
+            TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ true, *Op, Var,
+            Expr);
+    return true;
+  }
+
+  // We can't yet handle anything else here because it would require
+  // generating code, thus altering codegen because of debug info.
+  LLVM_DEBUG(
+      dbgs() << "Dropping debug info (no materialized reg for address)\n");
+  return false;
+}
+
 bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
   switch (II->getIntrinsicID()) {
   default:
@@ -1211,153 +1389,28 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {
       return true;
 
     const Value *Address = DI->getAddress();
-    if (!Address || isa<UndefValue>(Address)) {
-      LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI
-                        << " (bad/undef address)\n");
-      return true;
-    }
+    if (!lowerDbgDeclare(Address, DI->getExpression(), DI->getVariable(),
+                         MIMD.getDL()))
+      LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI);
 
-    std::optional<MachineOperand> Op;
-    if (Register Reg = lookUpRegForValue(Address))
-      Op = MachineOperand::CreateReg(Reg, false);
-
-    // If we have a VLA that has a "use" in a metadata node that's then used
-    // here but it has no other uses, then we have a problem. E.g.,
-    //
-    //   int foo (const int *x) {
-    //     char a[*x];
-    //     return 0;
-    //   }
-    //
-    // If we assign 'a' a vreg and fast isel later on has to use the selection
-    // DAG isel, it will want to copy the value to the vreg. However, there are
-    // no uses, which goes counter to what selection DAG isel expects.
-    if (!Op && !Address->use_empty() && isa<Instruction>(Address) &&
-        (!isa<AllocaInst>(Address) ||
-         !FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(Address))))
-      Op = MachineOperand::CreateReg(FuncInfo.InitializeRegForValue(Address),
-                                     false);
-
-    if (Op) {
-      assert(DI->getVariable()->isValidLocationForIntrinsic(MIMD.getDL()) &&
-             "Expected inlined-at fields to agree");
-      if (FuncInfo.MF->useDebugInstrRef() && Op->isReg()) {
-        // If using instruction referencing, produce this as a DBG_INSTR_REF,
-        // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto
-        // the expression, we don't have an "indirect" flag in DBG_INSTR_REF.
-        SmallVector<uint64_t, 3> Ops(
-            {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_deref});
-        auto *NewExpr = DIExpression::prependOpcodes(DI->getExpression(), Ops);
-        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(),
-                TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, *Op,
-                DI->getVariable(), NewExpr);
-      } else {
-        // A dbg.declare describes the address of a source variable, so lower it
-        // into an indirect DBG_VALUE.
-        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(),
-                TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ true, *Op,
-                DI->getVariable(), DI->getExpression());
-      }
-    } else {
-      // We can't yet handle anything else here because it would require
-      // generating code, thus altering codegen because of debug info.
-      LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI
-                        << " (no materialized reg for address)\n");
-    }
     return true;
   }
   case Intrinsic::dbg_value: {
     // This form of DBG_VALUE is target-independent.
     const DbgValueInst *DI = cast<DbgValueInst>(II);
-    const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);
     const Value *V = DI->getValue();
     DIExpression *Expr = DI->getExpression();
     DILocalVariable *Var = DI->getVariable();
+    if (DI->hasArgList())
+      // Signal that we don't have a location for this.
+      V = nullptr;
+
     assert(Var->isValidLocationForIntrinsic(MIMD.getDL()) &&
            "Expected inlined-at fields to agree");
-    if (!V || isa<UndefValue>(V) || DI->hasArgList()) {
-      // DI is either undef or cannot produce a valid DBG_VALUE, so produce an
-      // undef DBG_VALUE to terminate any prior location.
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(), II, false, 0U,
-              Var, Expr);
-      return true;
-    }
-    if (const auto *CI = dyn_cast<ConstantInt>(V)) {
-      // See if there's an expression to constant-fold.
-      if (Expr)
-        std::tie(Expr, CI) = Expr->constantFold(CI);
-      if (CI->getBitWidth() > 64)
-        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
-            .addCImm(CI)
-            .addImm(0U)
-            .addMetadata(Var)
-            .addMetadata(Expr);
-      else
-        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
-            .addImm(CI->getZExtValue())
-            .addImm(0U)
-            .addMetadata(Var)
-            .addMetadata(Expr);
-      return true;
-    }
-    if (const auto *CF = dyn_cast<ConstantFP>(V)) {
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II)
-          .addFPImm(CF)
-          .addImm(0U)
-          .addMetadata(Var)
-          .addMetadata(Expr);
-      return true;
-    }
-    if (const auto *Arg = dyn_cast<Argument>(V);
-        Arg && Expr && Expr->isEntryValue()) {
-      // As per the Verifier, this case is only valid for swift async Args.
-      assert(Arg->hasAttribute(Attribute::AttrKind::SwiftAsync));
-
-      Register Reg = getRegForValue(Arg);
-      for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo->liveins())
-        if (Reg == VirtReg || Reg == PhysReg) {
-          BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(), II,
-                  false /*IsIndirect*/, PhysReg, Var, Expr);
-          return true;
-        }
 
-      LLVM_DEBUG(dbgs() << "Dropping dbg.value: expression is entry_value but "
-                           "couldn't find a physical register\n"
-                        << *DI << "\n");
-      return true;
-    }
-    if (auto SI = FuncInfo.StaticAllocaMap.find(dyn_cast<AllocaInst>(V));
-        SI != FuncInfo.StaticAllocaMap.end()) {
-      MachineOperand FrameIndexOp = MachineOperand::CreateFI(SI->second);
-      bool IsIndirect = false;
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(), II, IsIndirect,
-              FrameIndexOp, Var, Expr);
-      return true;
-    }
-    if (Register Reg = lookUpRegForValue(V)) {
-      // FIXME: This does not handle register-indirect values at offset 0.
-      if (!FuncInfo.MF->useDebugInstrRef()) {
-        bool IsIndirect = false;
-        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(), II, IsIndirect,
-                Reg, Var, Expr);
-        return true;
-      }
-      // If using instruction referencing, produce this as a DBG_INSTR_REF,
-      // to be later patched up by finalizeDebugInstrRefs.
-      SmallVector<MachineOperand, 1> MOs({MachineOperand::CreateReg(
-          /* Reg */ Reg, /* isDef */ false, /* isImp */ false,
-          /* isKill */ false, /* isDead */ false,
-          /* isUndef */ false, /* isEarlyClobber */ false,
-          /* SubReg */ 0, /* isDebug */ true)});
-      SmallVector<uint64_t, 2> Ops({dwarf::DW_OP_LLVM_arg, 0});
-      auto *NewExpr = DIExpression::prependOpcodes(Expr, Ops);
-      BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD.getDL(),
-              TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, MOs,
-              Var, NewExpr);
-      return true;
-    }
-    // We don't know how to handle other cases, so we drop.
-    LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
+    if (!lowerDbgValue(V, Expr, Var, MIMD.getDL()))
+      LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
+
     return true;
   }
   case Intrinsic::dbg_label: {
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 3dc6e4bbcf46ba..53d4b0b984c0a4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1614,6 +1614,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
         if (isFoldedOrDeadInstruction(Inst, *FuncInfo) ||
             ElidedArgCopyInstrs.count(Inst)) {
           --NumFastIselRemaining;
+          FastIS->handleDbgInfo(Inst);
           continue;
         }
 
@@ -1625,6 +1626,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
         if (FastIS->selectInstruction(Inst)) {
           --NumFastIselRemaining;
           ++NumFastIselSuccess;
+
+          FastIS->handleDbgInfo(Inst);
           // If fast isel succeeded, skip over all the folded instructions, and
           // then see if there is a load right before the selected instructions.
           // Try to fold the load if so.
@@ -1640,6 +1643,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
             // If we succeeded, don't re-select the load.
             LLVM_DEBUG(dbgs()
                        << "FastISel folded load: " << *BeforeInst << "\n");
+            FastIS->handleDbgInfo(BeforeInst);
             BI = std::next(BasicBlock::const_iterator(BeforeInst));
             --NumFastIselRemaining;
             ++NumFastIselSuccess;
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-branch-uncond-debug.ll b/llvm/test/CodeGen/AArch64/fast-isel-branch-uncond-debug.ll
index 1d213945966a69..e1614d322b93d5 100644
--- a/llvm/test/CodeGen/AArch64/fast-isel-branch-uncond-debug.ll
+++ b/llvm/test/CodeGen/AArch64/fast-isel-branch-uncond-debug.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -mtriple=aarch64 -O1 -opt-bisect-limit=2 -o - %s  2> /dev/null | FileCheck %s
+; RUN: llc --try-experimental-debuginfo-iterators -mtriple=aarch64 -O1 -opt-bisect-limit=2 -o - %s  2> /dev/null | FileCheck %s
 
 define dso_local i32 @a() #0 !dbg !7 {
 entry:
@@ -41,4 +42,4 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) #2
 !18 = distinct !{!18, !19, !20}
 !19 = !DILocation(line: 3, column: 3, scope: !17)
 !20 = !DILocation(line: 4, column: 5, scope: !17)
- 
\ No newline at end of file
+
diff --git a/llvm/test/CodeGen/AArch64/fast-isel-dbg.ll b/llvm/test/CodeGen/AArch64/fast-isel-dbg.ll
index 602d454044d435..0c1a693089cb0d 100644
--- a/llvm/test/CodeGen/AArch64/fast-isel-dbg.ll
+++ b/llvm/test/CodeGen/AArch64/fast-isel-dbg.ll
@@ -1,4 +1,6 @@
 ; RUN: llc -o - %s -fast-isel -stop-before=finalize-isel | FileCheck %s
+; RUN: llc --try-experimental-debuginfo-iterators -o - %s -fast-isel -stop-before=finalize-isel | FileCheck %s
+
 ; Make sure fast-isel produces DBG_VALUE instructions even if no debug printer
 ; is scheduled because of -stop-before.
 target triple="aarch64--"
diff --git a/llvm/test/CodeGen/AArch64/fastisel-debugvalue-undef.ll b/llvm/test/CodeGen/AArch64/fastisel-debugvalue-undef.ll
index cccede6a50459a..c30a01baedaf34 100644
--- a/llvm/test/CodeGen/AArch64/fastisel-debugvalue-undef.ll
+++ b/llvm/test/CodeGen/AArch64/fastisel-debugvalue-undef.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -O0 -fast-isel=1 -o - -print-after="finalize-isel" %s 2>&1 | FileCheck %s
+; RUN: llc --try-experimental-debuginfo-iterators -O0 -fast-isel=1 -o - -print-after="finalize-isel" %s 2>&1 | FileCheck %s
 
 ; Check that we emit a DBG_VALUE for the `@llvm.dbg.value` which has `undef` has first arg.
 
diff --git a/llvm/test/CodeGen/ARM/debug-info-blocks.ll b/llvm/test/CodeGen/ARM/debug-info-blocks.ll
index 1c9ffb1775aa4f..8ef341faed6b73 100644
--- a/llvm/test/CodeGen/ARM/debug-info-blocks.ll
+++ b/llvm/test/CodeGen/ARM/debug-info-blocks.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -filetype=obj -O0 < %s | llvm-dwarfdump -v - | FileCheck %s
+; RUN: llc --try-experimental-debuginfo-iterators -filetype=obj -O0 < %s | llvm-dwarfdump -v - | FileCheck %s
 
 ; debug_info content
 ; CHECK: DW_AT_name {{.*}} "foobar_func_block_invoke_0"
diff --git a/llvm/test/CodeGen/Generic/csw-debug-assert.ll b/llv...
[truncated]

``````````

</details>


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


More information about the llvm-commits mailing list