[llvm] 429c6ec - Revert "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 10 06:35:49 PST 2021


Author: Stephen Tozer
Date: 2021-03-10T14:35:33Z
New Revision: 429c6ecbb302e2beedd8694378ae5be456206209

URL: https://github.com/llvm/llvm-project/commit/429c6ecbb302e2beedd8694378ae5be456206209
DIFF: https://github.com/llvm/llvm-project/commit/429c6ecbb302e2beedd8694378ae5be456206209.diff

LOG: Revert "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"

This reverts commit 0da27ba56c9f5e3f534a65401962301189eac342.

This revision was causing an error on the sanitizer-x86_64-linux-autoconf build.

Added: 
    

Modified: 
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
    llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
    llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
    llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h

Removed: 
    llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir
    llvm/test/DebugInfo/X86/dbg_value_list_emission.mir


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d55747691ec5..dbe7028b1a48 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -918,6 +918,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   OS << V->getName();
   OS << " <- ";
 
+  // The second operand is only an offset if it's an immediate.
+  bool MemLoc = MI->isIndirectDebugValue();
+  auto Offset = StackOffset::getFixed(MemLoc ? MI->getOperand(1).getImm() : 0);
   const DIExpression *Expr = MI->getDebugExpression();
   if (Expr->getNumElements()) {
     OS << '[';
@@ -931,71 +934,56 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   }
 
   // Register or immediate value. Register 0 means undef.
-  for (const MachineOperand &Op : MI->debug_operands()) {
-    if (&Op != MI->debug_operands().begin())
-      OS << ", ";
-    switch (Op.getType()) {
-    case MachineOperand::MO_FPImmediate: {
-      APFloat APF = APFloat(Op.getFPImm()->getValueAPF());
-      if (Op.getFPImm()->getType()->isFloatTy()) {
-        OS << (double)APF.convertToFloat();
-      } else if (Op.getFPImm()->getType()->isDoubleTy()) {
-        OS << APF.convertToDouble();
-      } else {
-        // There is no good way to print long double.  Convert a copy to
-        // double.  Ah well, it's only a comment.
-        bool ignored;
-        APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
-                    &ignored);
-        OS << "(long double) " << APF.convertToDouble();
-      }
-      break;
-    }
-    case MachineOperand::MO_Immediate: {
-      OS << Op.getImm();
-      break;
+  if (MI->getDebugOperand(0).isFPImm()) {
+    APFloat APF = APFloat(MI->getDebugOperand(0).getFPImm()->getValueAPF());
+    if (MI->getDebugOperand(0).getFPImm()->getType()->isFloatTy()) {
+      OS << (double)APF.convertToFloat();
+    } else if (MI->getDebugOperand(0).getFPImm()->getType()->isDoubleTy()) {
+      OS << APF.convertToDouble();
+    } else {
+      // There is no good way to print long double.  Convert a copy to
+      // double.  Ah well, it's only a comment.
+      bool ignored;
+      APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
+                  &ignored);
+      OS << "(long double) " << APF.convertToDouble();
     }
-    case MachineOperand::MO_CImmediate: {
-      Op.getCImm()->getValue().print(OS, false /*isSigned*/);
-      break;
+  } else if (MI->getDebugOperand(0).isImm()) {
+    OS << MI->getDebugOperand(0).getImm();
+  } else if (MI->getDebugOperand(0).isCImm()) {
+    MI->getDebugOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
+  } else if (MI->getDebugOperand(0).isTargetIndex()) {
+    auto Op = MI->getDebugOperand(0);
+    OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
+    // NOTE: Want this comment at start of line, don't emit with AddComment.
+    AP.OutStreamer->emitRawComment(OS.str());
+    return true;
+  } else {
+    Register Reg;
+    if (MI->getDebugOperand(0).isReg()) {
+      Reg = MI->getDebugOperand(0).getReg();
+    } else {
+      assert(MI->getDebugOperand(0).isFI() && "Unknown operand type");
+      const TargetFrameLowering *TFI = AP.MF->getSubtarget().getFrameLowering();
+      Offset += TFI->getFrameIndexReference(
+          *AP.MF, MI->getDebugOperand(0).getIndex(), Reg);
+      MemLoc = true;
     }
-    case MachineOperand::MO_TargetIndex: {
-      OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
+    if (Reg == 0) {
+      // Suppress offset, it is not meaningful here.
+      OS << "undef";
       // NOTE: Want this comment at start of line, don't emit with AddComment.
       AP.OutStreamer->emitRawComment(OS.str());
-      break;
-    }
-    case MachineOperand::MO_Register:
-    case MachineOperand::MO_FrameIndex: {
-      Register Reg;
-      Optional<StackOffset> Offset;
-      if (Op.isReg()) {
-        Reg = Op.getReg();
-      } else {
-        const TargetFrameLowering *TFI =
-            AP.MF->getSubtarget().getFrameLowering();
-        Offset = TFI->getFrameIndexReference(*AP.MF, Op.getIndex(), Reg);
-      }
-      if (!Reg) {
-        // Suppress offset, it is not meaningful here.
-        OS << "undef";
-        break;
-      }
-      // The second operand is only an offset if it's an immediate.
-      if (MI->isIndirectDebugValue())
-        Offset = StackOffset::getFixed(MI->getDebugOffset().getImm());
-      if (Offset)
-        OS << '[';
-      OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
-      if (Offset)
-        OS << '+' << Offset->getFixed() << ']';
-      break;
-    }
-    default:
-      llvm_unreachable("Unknown operand type");
+      return true;
     }
+    if (MemLoc)
+      OS << '[';
+    OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
   }
 
+  if (MemLoc)
+    OS << '+' << Offset.getFixed() << ']';
+
   // NOTE: Want this comment at start of line, don't emit with AddComment.
   AP.OutStreamer->emitRawComment(OS.str());
   return true;

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
index bb24f1414ef1..a30720cc20ff 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
@@ -37,6 +37,22 @@ namespace {
 using EntryIndex = DbgValueHistoryMap::EntryIndex;
 }
 
+// If @MI is a DBG_VALUE with debug value described by a
+// defined register, returns the number of this register.
+// In the other case, returns 0.
+static Register isDescribedByReg(const MachineInstr &MI) {
+  assert(MI.isDebugValue());
+  assert(MI.getNumOperands() == 4);
+  // If the location of variable is an entry value (DW_OP_LLVM_entry_value)
+  // do not consider it as a register location.
+  if (MI.getDebugExpression()->isEntryValue())
+    return 0;
+  // If location of variable is described using a register (directly or
+  // indirectly), this register is always a first operand.
+  return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg()
+                                       : Register();
+}
+
 void InstructionOrdering::initialize(const MachineFunction &MF) {
   // We give meta instructions the same ordinal as the preceding instruction
   // because this class is written for the task of comparing positions of
@@ -317,44 +333,24 @@ static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
 }
 
 /// Create a clobbering entry and end all open debug value entries
-/// for \p Var that are described by \p RegNo using that entry. Inserts into \p
-/// FellowRegisters the set of Registers that were also used to describe \p Var
-/// alongside \p RegNo.
+/// for \p Var that are described by \p RegNo using that entry.
 static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
                               const MachineInstr &ClobberingInstr,
                               DbgValueEntriesMap &LiveEntries,
-                              DbgValueHistoryMap &HistMap,
-                              SmallVectorImpl<Register> &FellowRegisters) {
+                              DbgValueHistoryMap &HistMap) {
   EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
+
   // Close all entries whose values are described by the register.
   SmallVector<EntryIndex, 4> IndicesToErase;
-  // If a given register appears in a live DBG_VALUE_LIST for Var alongside the
-  // clobbered register, and never appears in a live DBG_VALUE* for Var without
-  // the clobbered register, then it is no longer linked to the variable.
-  SmallSet<Register, 4> MaybeRemovedRegisters;
-  SmallSet<Register, 4> KeepRegisters;
   for (auto Index : LiveEntries[Var]) {
     auto &Entry = HistMap.getEntry(Var, Index);
     assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
-    if (Entry.getInstr()->isDebugEntryValue())
-      continue;
-    if (Entry.getInstr()->hasDebugOperandForReg(RegNo)) {
+    if (isDescribedByReg(*Entry.getInstr()) == RegNo) {
       IndicesToErase.push_back(Index);
       Entry.endEntry(ClobberIndex);
-      for (auto &MO : Entry.getInstr()->debug_operands())
-        if (MO.isReg() && MO.getReg() && MO.getReg() != RegNo)
-          MaybeRemovedRegisters.insert(MO.getReg());
-    } else {
-      for (auto &MO : Entry.getInstr()->debug_operands())
-        if (MO.isReg() && MO.getReg())
-          KeepRegisters.insert(MO.getReg());
     }
   }
 
-  for (Register Reg : MaybeRemovedRegisters)
-    if (!KeepRegisters.contains(Reg))
-      FellowRegisters.push_back(Reg);
-
   // Drop all entries that have ended.
   for (auto Index : IndicesToErase)
     LiveEntries[Var].erase(Index);
@@ -382,24 +378,17 @@ static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
         IndicesToErase.push_back(Index);
         Entry.endEntry(NewIndex);
       }
-      if (!DV.isDebugEntryValue())
-        for (const MachineOperand &Op : DV.debug_operands())
-          if (Op.isReg() && Op.getReg())
-            TrackedRegs[Op.getReg()] |= !Overlaps;
+      if (Register Reg = isDescribedByReg(DV))
+        TrackedRegs[Reg] |= !Overlaps;
     }
 
     // If the new debug value is described by a register, add tracking of
     // that register if it is not already tracked.
-    if (!DV.isDebugEntryValue()) {
-      for (const MachineOperand &Op : DV.debug_operands()) {
-        if (Op.isReg() && Op.getReg()) {
-          Register NewReg = Op.getReg();
-          if (!TrackedRegs.count(NewReg))
-            addRegDescribedVar(RegVars, NewReg, Var);
-          LiveEntries[Var].insert(NewIndex);
-          TrackedRegs[NewReg] = true;
-        }
-      }
+    if (Register NewReg = isDescribedByReg(DV)) {
+      if (!TrackedRegs.count(NewReg))
+        addRegDescribedVar(RegVars, NewReg, Var);
+      LiveEntries[Var].insert(NewIndex);
+      TrackedRegs[NewReg] = true;
     }
 
     // Drop tracking of registers that are no longer used.
@@ -422,16 +411,9 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
                                 DbgValueEntriesMap &LiveEntries,
                                 const MachineInstr &ClobberingInstr) {
   // Iterate over all variables described by this register and add this
-  // instruction to their history, clobbering it. All registers that also
-  // describe the clobbered variables (i.e. in variadic debug values) will have
-  // those Variables removed from their DescribedVars.
-  for (const auto &Var : I->second) {
-    SmallVector<Register, 4> FellowRegisters;
-    clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap,
-                      FellowRegisters);
-    for (Register RegNo : FellowRegisters)
-      dropRegDescribedVar(RegVars, RegNo, Var);
-  }
+  // instruction to their history, clobbering it.
+  for (const auto &Var : I->second)
+    clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap);
   RegVars.erase(I);
 }
 

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index b9a9e1cfaee0..68a4bfba42a7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -35,8 +35,7 @@ Optional<DbgVariableLocation>
 DbgVariableLocation::extractFromMachineInstruction(
     const MachineInstr &Instruction) {
   DbgVariableLocation Location;
-  // Variables calculated from multiple locations can't be represented here.
-  if (Instruction.getNumDebugOperands() != 1)
+  if (!Instruction.isDebugValue())
     return None;
   if (!Instruction.getDebugOperand(0).isReg())
     return None;
@@ -47,15 +46,6 @@ DbgVariableLocation::extractFromMachineInstruction(
   int64_t Offset = 0;
   const DIExpression *DIExpr = Instruction.getDebugExpression();
   auto Op = DIExpr->expr_op_begin();
-  // We can handle a DBG_VALUE_LIST iff it has exactly one location operand that
-  // appears exactly once at the start of the expression.
-  if (Instruction.isDebugValueList()) {
-    if (Instruction.getNumDebugOperands() == 1 &&
-        Op->getOp() == dwarf::DW_OP_LLVM_arg)
-      ++Op;
-    else
-      return None;
-  }
   while (Op != DIExpr->expr_op_end()) {
     switch (Op->getOp()) {
     case dwarf::DW_OP_constu: {
@@ -271,8 +261,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
       continue;
 
     auto IsDescribedByReg = [](const MachineInstr *MI) {
-      return any_of(MI->debug_operands(),
-                    [](auto &MO) { return MO.isReg() && MO.getReg(); });
+      return MI->getDebugOperand(0).isReg() && MI->getDebugOperand(0).getReg();
     };
 
     // The first mention of a function argument gets the CurrentFnBegin label,

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 525b839d67a0..36278f2e9e2d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -34,10 +34,10 @@ struct TargetIndexLocation {
   }
 };
 
-/// A single location or constant within a variable location description, with
-/// either a single entry (with an optional DIExpression) used for a DBG_VALUE,
-/// or a list of entries used for a DBG_VALUE_LIST.
-class DbgValueLocEntry {
+/// A single location or constant.
+class DbgValueLoc {
+  /// Any complex address location expression for this DbgValueLoc.
+  const DIExpression *Expression;
 
   /// Type of entry that this represents.
   enum EntryType {
@@ -64,16 +64,24 @@ class DbgValueLocEntry {
   };
 
 public:
-  DbgValueLocEntry(int64_t i) : EntryKind(E_Integer) { Constant.Int = i; }
-  DbgValueLocEntry(const ConstantFP *CFP) : EntryKind(E_ConstantFP) {
+  DbgValueLoc(const DIExpression *Expr, int64_t i)
+      : Expression(Expr), EntryKind(E_Integer) {
+    Constant.Int = i;
+  }
+  DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP)
+      : Expression(Expr), EntryKind(E_ConstantFP) {
     Constant.CFP = CFP;
   }
-  DbgValueLocEntry(const ConstantInt *CIP) : EntryKind(E_ConstantInt) {
+  DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP)
+      : Expression(Expr), EntryKind(E_ConstantInt) {
     Constant.CIP = CIP;
   }
-  DbgValueLocEntry(MachineLocation Loc) : EntryKind(E_Location), Loc(Loc) {}
-  DbgValueLocEntry(TargetIndexLocation Loc)
-      : EntryKind(E_TargetIndexLocation), TIL(Loc) {}
+  DbgValueLoc(const DIExpression *Expr, MachineLocation Loc)
+      : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
+    assert(cast<DIExpression>(Expr)->isValid());
+  }
+  DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc)
+      : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {}
 
   bool isLocation() const { return EntryKind == E_Location; }
   bool isTargetIndexLocation() const {
@@ -87,7 +95,11 @@ class DbgValueLocEntry {
   const ConstantInt *getConstantInt() const { return Constant.CIP; }
   MachineLocation getLoc() const { return Loc; }
   TargetIndexLocation getTargetIndexLocation() const { return TIL; }
-  friend bool operator==(const DbgValueLocEntry &, const DbgValueLocEntry &);
+  bool isFragment() const { return getExpression()->isFragment(); }
+  bool isEntryVal() const { return getExpression()->isEntryValue(); }
+  const DIExpression *getExpression() const { return Expression; }
+  friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
+  friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   LLVM_DUMP_METHOD void dump() const {
     if (isLocation()) {
@@ -99,77 +111,6 @@ class DbgValueLocEntry {
       Constant.CIP->dump();
     else if (isConstantFP())
       Constant.CFP->dump();
-  }
-#endif
-};
-
-/// The location of a single variable, composed of an expression and 0 or more
-/// DbgValueLocEntries.
-class DbgValueLoc {
-  /// Any complex address location expression for this DbgValueLoc.
-  const DIExpression *Expression;
-
-  SmallVector<DbgValueLocEntry, 2> ValueLocEntries;
-
-  bool IsVariadic;
-
-public:
-  DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
-      : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
-        IsVariadic(true) {
-#ifndef NDEBUG
-    // Currently, DBG_VALUE_VAR expressions must use stack_value.
-    assert(Expr && Expr->isValid() &&
-           is_contained(Locs, dwarf::DW_OP_stack_value));
-    for (DbgValueLocEntry &Entry : ValueLocEntries) {
-      assert(!Entry.isConstantFP() && !Entry.isConstantInt() &&
-             "Constant values should only be present in non-variadic "
-             "DBG_VALUEs.");
-    }
-#endif
-  }
-
-  DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
-              bool IsVariadic)
-      : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
-        IsVariadic(IsVariadic) {
-#ifndef NDEBUG
-    assert(cast<DIExpression>(Expr)->isValid() ||
-           !any_of(Locs, [](auto LE) { return LE.isLocation(); }));
-    if (!IsVariadic) {
-      assert(ValueLocEntries.size() == 1);
-    } else {
-      // Currently, DBG_VALUE_VAR expressions must use stack_value.
-      assert(Expr && Expr->isValid() &&
-             is_contained(Expr->getElements(), dwarf::DW_OP_stack_value));
-      for (DbgValueLocEntry &Entry : ValueLocEntries) {
-        assert(!Entry.isConstantFP() && !Entry.isConstantInt() &&
-               "Constant values should only be present in non-variadic "
-               "DBG_VALUEs.");
-      }
-    }
-#endif
-  }
-
-  DbgValueLoc(const DIExpression *Expr, DbgValueLocEntry Loc)
-      : Expression(Expr), ValueLocEntries(1, Loc), IsVariadic(false) {
-    assert(((Expr && Expr->isValid()) || !Loc.isLocation()) &&
-           "DBG_VALUE with a machine location must have a valid expression.");
-  }
-
-  bool isFragment() const { return getExpression()->isFragment(); }
-  bool isEntryVal() const { return getExpression()->isEntryValue(); }
-  bool isVariadic() const { return IsVariadic; }
-  const DIExpression *getExpression() const { return Expression; }
-  const ArrayRef<DbgValueLocEntry> getLocEntries() const {
-    return ValueLocEntries;
-  }
-  friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
-  friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-  LLVM_DUMP_METHOD void dump() const {
-    for (DbgValueLocEntry DV : ValueLocEntries)
-      DV.dump();
     if (Expression)
       Expression->dump();
   }
@@ -239,32 +180,30 @@ class DebugLocEntry {
                 DwarfCompileUnit &TheCU);
 };
 
-/// Compare two DbgValueLocEntries for equality.
-inline bool operator==(const DbgValueLocEntry &A, const DbgValueLocEntry &B) {
+/// Compare two DbgValueLocs for equality.
+inline bool operator==(const DbgValueLoc &A,
+                       const DbgValueLoc &B) {
   if (A.EntryKind != B.EntryKind)
     return false;
 
+  if (A.Expression != B.Expression)
+    return false;
+
   switch (A.EntryKind) {
-  case DbgValueLocEntry::E_Location:
+  case DbgValueLoc::E_Location:
     return A.Loc == B.Loc;
-  case DbgValueLocEntry::E_TargetIndexLocation:
+  case DbgValueLoc::E_TargetIndexLocation:
     return A.TIL == B.TIL;
-  case DbgValueLocEntry::E_Integer:
+  case DbgValueLoc::E_Integer:
     return A.Constant.Int == B.Constant.Int;
-  case DbgValueLocEntry::E_ConstantFP:
+  case DbgValueLoc::E_ConstantFP:
     return A.Constant.CFP == B.Constant.CFP;
-  case DbgValueLocEntry::E_ConstantInt:
+  case DbgValueLoc::E_ConstantInt:
     return A.Constant.CIP == B.Constant.CIP;
   }
   llvm_unreachable("unhandled EntryKind");
 }
 
-/// Compare two DbgValueLocs for equality.
-inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) {
-  return A.ValueLocEntries == B.ValueLocEntries &&
-         A.Expression == B.Expression && A.IsVariadic == B.IsVariadic;
-}
-
 /// Compare two fragments based on their offset.
 inline bool operator<(const DbgValueLoc &A,
                       const DbgValueLoc &B) {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index cba36ab584e9..3d378df287ac 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -728,95 +728,36 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
 
   // Check if variable has a single location description.
   if (auto *DVal = DV.getValueLoc()) {
-    if (!DVal->isVariadic()) {
-      const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
-      if (Entry->isLocation()) {
-        addVariableAddress(DV, *VariableDie, Entry->getLoc());
-      } else if (Entry->isInt()) {
-        auto *Expr = DV.getSingleExpression();
-        if (Expr && Expr->getNumElements()) {
-          DIELoc *Loc = new (DIEValueAllocator) DIELoc;
-          DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
-          // If there is an expression, emit raw unsigned bytes.
-          DwarfExpr.addFragmentOffset(Expr);
-          DwarfExpr.addUnsignedConstant(Entry->getInt());
-          DwarfExpr.addExpression(Expr);
-          addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
-          if (DwarfExpr.TagOffset)
-            addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
-                    dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
-        } else
-          addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
-      } else if (Entry->isConstantFP()) {
-        addConstantFPValue(*VariableDie, Entry->getConstantFP());
-      } else if (Entry->isConstantInt()) {
-        addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
-      } else if (Entry->isTargetIndexLocation()) {
+    if (DVal->isLocation())
+      addVariableAddress(DV, *VariableDie, DVal->getLoc());
+    else if (DVal->isInt()) {
+      auto *Expr = DV.getSingleExpression();
+      if (Expr && Expr->getNumElements()) {
         DIELoc *Loc = new (DIEValueAllocator) DIELoc;
         DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
-        const DIBasicType *BT = dyn_cast<DIBasicType>(
-            static_cast<const Metadata *>(DV.getVariable()->getType()));
-        DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
+        // If there is an expression, emit raw unsigned bytes.
+        DwarfExpr.addFragmentOffset(Expr);
+        DwarfExpr.addUnsignedConstant(DVal->getInt());
+        DwarfExpr.addExpression(Expr);
         addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
-      }
-      return VariableDie;
+        if (DwarfExpr.TagOffset)
+          addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
+                  dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
+
+      } else
+        addConstantValue(*VariableDie, DVal->getInt(), DV.getType());
+    } else if (DVal->isConstantFP()) {
+      addConstantFPValue(*VariableDie, DVal->getConstantFP());
+    } else if (DVal->isConstantInt()) {
+      addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType());
+    } else if (DVal->isTargetIndexLocation()) {
+      DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+      DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+      const DIBasicType *BT = dyn_cast<DIBasicType>(
+          static_cast<const Metadata *>(DV.getVariable()->getType()));
+      DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
+      addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
     }
-    // If any of the location entries are registers with the value 0, then the
-    // location is undefined.
-    if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
-          return Entry.isLocation() && !Entry.getLoc().getReg();
-        }))
-      return VariableDie;
-    const DIExpression *Expr = DV.getSingleExpression();
-    assert(Expr && "Variadic Debug Value must have an Expression.");
-    DIELoc *Loc = new (DIEValueAllocator) DIELoc;
-    DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
-    DwarfExpr.addFragmentOffset(Expr);
-    DIExpressionCursor Cursor(Expr);
-    const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
-
-    // Declare the TargetMachine locally so we don't need to capture `this` in
-    // the lambda.
-    TargetMachine &TM = Asm->TM;
-    auto AddEntry = [&DwarfExpr, &TRI, &TM](const DbgValueLocEntry &Entry,
-                                            DIExpressionCursor &Cursor) {
-      if (Entry.isLocation()) {
-        if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
-                                               Entry.getLoc().getReg()))
-          return false;
-      } else if (Entry.isInt()) {
-        // If there is an expression, emit raw unsigned bytes.
-        DwarfExpr.addUnsignedConstant(Entry.getInt());
-      } else if (Entry.isConstantFP()) {
-        APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
-        DwarfExpr.addUnsignedConstant(RawBytes);
-      } else if (Entry.isConstantInt()) {
-        APInt RawBytes = Entry.getConstantInt()->getValue();
-        DwarfExpr.addUnsignedConstant(RawBytes);
-      } else if (Entry.isTargetIndexLocation()) {
-        TargetIndexLocation Loc = Entry.getTargetIndexLocation();
-        // TODO TargetIndexLocation is a target-independent. Currently only the
-        // WebAssembly-specific encoding is supported.
-        assert(TM.getTargetTriple().isWasm());
-        DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
-      } else {
-        llvm_unreachable("Unsupported Entry type.");
-      }
-      return true;
-    };
-
-    DwarfExpr.addExpression(
-        std::move(Cursor),
-        [&AddEntry, &DVal](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
-          return AddEntry(DVal->getLocEntries()[Idx], Cursor);
-        });
-
-    // Now attach the location information to the DIE.
-    addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
-    if (DwarfExpr.TagOffset)
-      addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
-              *DwarfExpr.TagOffset);
-
     return VariableDie;
   }
 

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 9e20527b2ac3..beed2a5126c4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -235,27 +235,29 @@ const DIType *DbgVariable::getType() const {
 /// Get .debug_loc entry for the instruction range starting at MI.
 static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
   const DIExpression *Expr = MI->getDebugExpression();
-  const bool IsVariadic = MI->isDebugValueList();
-  assert(MI->getNumOperands() >= 3);
-  SmallVector<DbgValueLocEntry, 4> DbgValueLocEntries;
-  for (const MachineOperand &Op : MI->debug_operands()) {
-    if (Op.isReg()) {
-      MachineLocation MLoc(Op.getReg(),
-                           MI->isNonListDebugValue() && MI->isDebugOffsetImm());
-      DbgValueLocEntries.push_back(DbgValueLocEntry(MLoc));
-    } else if (Op.isTargetIndex()) {
-      DbgValueLocEntries.push_back(
-          DbgValueLocEntry(TargetIndexLocation(Op.getIndex(), Op.getOffset())));
-    } else if (Op.isImm())
-      DbgValueLocEntries.push_back(DbgValueLocEntry(Op.getImm()));
-    else if (Op.isFPImm())
-      DbgValueLocEntries.push_back(DbgValueLocEntry(Op.getFPImm()));
-    else if (Op.isCImm())
-      DbgValueLocEntries.push_back(DbgValueLocEntry(Op.getCImm()));
-    else
-      llvm_unreachable("Unexpected debug operand in DBG_VALUE* instruction!");
-  }
-  return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
+  assert(MI->getNumOperands() == 4);
+  if (MI->getDebugOperand(0).isReg()) {
+    const auto &RegOp = MI->getDebugOperand(0);
+    const auto &Op1 = MI->getDebugOffset();
+    // If the second operand is an immediate, this is a
+    // register-indirect address.
+    assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
+    MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
+    return DbgValueLoc(Expr, MLoc);
+  }
+  if (MI->getDebugOperand(0).isTargetIndex()) {
+    const auto &Op = MI->getDebugOperand(0);
+    return DbgValueLoc(Expr,
+                       TargetIndexLocation(Op.getIndex(), Op.getOffset()));
+  }
+  if (MI->getDebugOperand(0).isImm())
+    return DbgValueLoc(Expr, MI->getDebugOperand(0).getImm());
+  if (MI->getDebugOperand(0).isFPImm())
+    return DbgValueLoc(Expr, MI->getDebugOperand(0).getFPImm());
+  if (MI->getDebugOperand(0).isCImm())
+    return DbgValueLoc(Expr, MI->getDebugOperand(0).getCImm());
+
+  llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
 }
 
 void DbgVariable::initializeDbgValue(const MachineInstr *DbgValue) {
@@ -643,7 +645,7 @@ static void finishCallSiteParams(ValT Val, const DIExpression *Expr,
     assert((!CombinedExpr || CombinedExpr->isValid()) &&
            "Combined debug expression is invalid");
 
-    DbgValueLoc DbgLocVal(CombinedExpr, DbgValueLocEntry(Val));
+    DbgValueLoc DbgLocVal(CombinedExpr, Val);
     DbgCallSiteParam CSParm(Param.ParamReg, DbgLocVal);
     Params.push_back(CSParm);
     ++NumCSParams;
@@ -1611,9 +1613,7 @@ static bool validThroughout(LexicalScopes &LScopes,
   // throughout the function. This is a hack, presumably for DWARF v2 and not
   // necessarily correct. It would be much better to use a dbg.declare instead
   // if we know the constant is live throughout the scope.
-  if (MBB->pred_empty() &&
-      all_of(DbgValue->debug_operands(),
-             [](const MachineOperand &Op) { return Op.isImm(); }))
+  if (DbgValue->getDebugOperand(0).isImm() && MBB->pred_empty())
     return true;
 
   // Test if the location terminates before the end of the scope.
@@ -2486,95 +2486,51 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
   auto *DIExpr = Value.getExpression();
   DIExpressionCursor ExprCursor(DIExpr);
   DwarfExpr.addFragmentOffset(DIExpr);
-
-  // If the DIExpr is is an Entry Value, we want to follow the same code path
-  // regardless of whether the DBG_VALUE is variadic or not.
-  if (DIExpr && DIExpr->isEntryValue()) {
-    // Entry values can only be a single register with no additional DIExpr,
-    // so just add it directly.
-    assert(Value.getLocEntries().size() == 1);
-    assert(Value.getLocEntries()[0].isLocation());
-    MachineLocation Location = Value.getLocEntries()[0].getLoc();
+  // Regular entry.
+  if (Value.isInt()) {
+    if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
+               BT->getEncoding() == dwarf::DW_ATE_signed_char))
+      DwarfExpr.addSignedConstant(Value.getInt());
+    else
+      DwarfExpr.addUnsignedConstant(Value.getInt());
+  } else if (Value.isLocation()) {
+    MachineLocation Location = Value.getLoc();
     DwarfExpr.setLocation(Location, DIExpr);
+    DIExpressionCursor Cursor(DIExpr);
 
-    DwarfExpr.beginEntryValueExpression(ExprCursor);
+    if (DIExpr->isEntryValue())
+      DwarfExpr.beginEntryValueExpression(Cursor);
 
     const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
-    if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg()))
-      return;
-    return DwarfExpr.addExpression(std::move(ExprCursor));
-  }
-
-  // Regular entry.
-  auto EmitValueLocEntry = [&DwarfExpr, &BT,
-                            &AP](const DbgValueLocEntry &Entry,
-                                 DIExpressionCursor &Cursor) -> bool {
-    if (Entry.isInt()) {
-      if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
-                 BT->getEncoding() == dwarf::DW_ATE_signed_char))
-        DwarfExpr.addSignedConstant(Entry.getInt());
-      else
-        DwarfExpr.addUnsignedConstant(Entry.getInt());
-    } else if (Entry.isLocation()) {
-      MachineLocation Location = Entry.getLoc();
-      if (Location.isIndirect())
-        DwarfExpr.setMemoryLocationKind();
-
-      const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
-      if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
-        return false;
-    } else if (Entry.isTargetIndexLocation()) {
-      TargetIndexLocation Loc = Entry.getTargetIndexLocation();
-      // TODO TargetIndexLocation is a target-independent. Currently only the
-      // WebAssembly-specific encoding is supported.
-      assert(AP.TM.getTargetTriple().isWasm());
-      DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
-    } else if (Entry.isConstantFP()) {
-      if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() &&
-          !Cursor) {
-        DwarfExpr.addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
-      } else if (Entry.getConstantFP()
-                     ->getValueAPF()
-                     .bitcastToAPInt()
-                     .getBitWidth() <= 64 /*bits*/) {
-        DwarfExpr.addUnsignedConstant(
-            Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
-      } else {
-        LLVM_DEBUG(
-            dbgs() << "Skipped DwarfExpression creation for ConstantFP of size"
-                   << Entry.getConstantFP()
-                          ->getValueAPF()
-                          .bitcastToAPInt()
-                          .getBitWidth()
-                   << " bits\n");
-        return false;
-      }
-    } else {
-      llvm_unreachable("Invalid Entry for a DW_AT_location expression.");
-    }
-    return true;
-  };
-
-  if (!Value.isVariadic()) {
-    if (!EmitValueLocEntry(Value.getLocEntries()[0], ExprCursor))
+    if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
       return;
+    return DwarfExpr.addExpression(std::move(Cursor));
+  } else if (Value.isTargetIndexLocation()) {
+    TargetIndexLocation Loc = Value.getTargetIndexLocation();
+    // TODO TargetIndexLocation is a target-independent. Currently only the WebAssembly-specific
+    // encoding is supported.
+    assert(AP.TM.getTargetTriple().isWasm());
+    DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
     DwarfExpr.addExpression(std::move(ExprCursor));
     return;
+  } else if (Value.isConstantFP()) {
+    if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() &&
+        !ExprCursor) {
+      DwarfExpr.addConstantFP(Value.getConstantFP()->getValueAPF(), AP);
+      return;
+    }
+    if (Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth() <=
+        64 /*bits*/)
+      DwarfExpr.addUnsignedConstant(
+          Value.getConstantFP()->getValueAPF().bitcastToAPInt());
+    else
+      LLVM_DEBUG(
+          dbgs()
+          << "Skipped DwarfExpression creation for ConstantFP of size"
+          << Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth()
+          << " bits\n");
   }
-
-  // If any of the location entries are registers with the value 0, then the
-  // location is undefined.
-  if (any_of(Value.getLocEntries(), [](const DbgValueLocEntry &Entry) {
-        return Entry.isLocation() && !Entry.getLoc().getReg();
-      }))
-    return;
-
-  DwarfExpr.addExpression(
-      std::move(ExprCursor),
-      [EmitValueLocEntry, &Value](unsigned Idx,
-                                  DIExpressionCursor &Cursor) -> bool {
-        return EmitValueLocEntry(Value.getLocEntries()[Idx], Cursor);
-      });
+  DwarfExpr.addExpression(std::move(ExprCursor));
 }
 
 void DebugLocEntry::finalize(const AsmPrinter &AP,

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 8dc260130f46..ef61e2e55e18 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -302,12 +302,6 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
     }
 
     DwarfRegs.clear();
-    // If we need to mask out a subregister, do it now, unless the next
-    // operation would emit an OpPiece anyway.
-    auto NextOp = ExprCursor.peek();
-    if (SubRegisterSizeInBits && NextOp &&
-        (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
-      maskSubRegister();
     return true;
   }
 
@@ -360,14 +354,6 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
   else
     addBReg(Reg.DwarfRegNo, SignedOffset);
   DwarfRegs.clear();
-
-  // If we need to mask out a subregister, do it now, unless the next
-  // operation would emit an OpPiece anyway.
-  auto NextOp = ExprCursor.peek();
-  if (SubRegisterSizeInBits && NextOp &&
-      (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
-    maskSubRegister();
-
   return true;
 }
 
@@ -465,19 +451,16 @@ static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
 
 void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
                                     unsigned FragmentOffsetInBits) {
-  addExpression(std::move(ExprCursor),
-                [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
-                  llvm_unreachable("unhandled opcode found in expression");
-                });
-}
-
-void DwarfExpression::addExpression(
-    DIExpressionCursor &&ExprCursor,
-    std::function<bool(unsigned, DIExpressionCursor &)> InsertArg) {
   // Entry values can currently only cover the initial register location,
   // and not any other parts of the following DWARF expression.
   assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
 
+  // If we need to mask out a subregister, do it now, unless the next
+  // operation would emit an OpPiece anyway.
+  auto N = ExprCursor.peek();
+  if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
+    maskSubRegister();
+
   Optional<DIExpression::ExprOperand> PrevConvertOp = None;
 
   while (ExprCursor) {
@@ -493,12 +476,6 @@ void DwarfExpression::addExpression(
     }
 
     switch (OpNum) {
-    case dwarf::DW_OP_LLVM_arg:
-      if (!InsertArg(Op->getArg(0), ExprCursor)) {
-        LocationKind = Unknown;
-        return;
-      }
-      break;
     case dwarf::DW_OP_LLVM_fragment: {
       unsigned SizeInBits = Op->getArg(1);
       unsigned FragmentOffset = Op->getArg(0);

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 2e5edf18b38d..0d55144f9827 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -347,9 +347,6 @@ class DwarfExpression {
   ///                                 fragment inside the entire variable.
   void addExpression(DIExpressionCursor &&Expr,
                      unsigned FragmentOffsetInBits = 0);
-  void
-  addExpression(DIExpressionCursor &&Expr,
-                std::function<bool(unsigned, DIExpressionCursor &)> InsertArg);
 
   /// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
   /// the fragment described by \c Expr.

diff  --git a/llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir b/llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir
deleted file mode 100644
index 601067a80d01..000000000000
--- a/llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir
+++ /dev/null
@@ -1,84 +0,0 @@
-# RUN: llc %s --start-after=livedebugvalues -filetype=obj -o - \
-# RUN:     | llvm-dwarfdump - -name locala -o - | FileCheck %s
-#
-# Test that clobbers between DBG_VALUE_LIST and DBG_VALUE instructions work as
-# expected. Comments and test directives inline.
-
---- |
-  target triple = "x86_64-unknown-linux-gnu"
-  define dso_local i32 @fun() local_unnamed_addr !dbg !7 {
-  entry:
-    ret i32 0
-  }
-
-  !llvm.dbg.cu = !{!0}
-  !llvm.module.flags = !{!3, !4, !5}
-  !llvm.ident = !{!6}
-
-  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
-  !1 = !DIFile(filename: "example.c", directory: "/")
-  !2 = !{}
-  !3 = !{i32 7, !"Dwarf Version", i32 4}
-  !4 = !{i32 2, !"Debug Info Version", i32 3}
-  !5 = !{i32 1, !"wchar_size", i32 4}
-  !6 = !{!"clang version 11.0.0"}
-  !8 = !DISubroutineType(types: !9)
-  !9 = !{!10}
-  !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-  !11 = !{!12}
-  !22 = !DISubroutineType(types: !23)
-  !23 = !{!10, !10}
-  ; --- Important metadata ---
-  !7 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
-  !15 = !DILocation(line: 1, column: 1, scope: !7)
-  !12 = !DILocalVariable(name: "locala", scope: !7, file: !1, line: 1, type: !10)
-
-...
----
-name:            fun
-body:             |
-  bb.0.entry:
-    ; This test checks that we see expected location ranges for a single variable.
-    ; CHECK: {{.*}} DW_TAG_variable
-    ; CHECK-NEXT: DW_AT_location {{.*}}
-
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $eax, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value
-
-    $edi = MOV32ri 1
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $esi, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg4 RSI+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value
-
-    $eax = MOV32ri 2
-    DBG_VALUE $eax, $noreg, !12, !DIExpression(), debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_reg0 RAX
-
-    $ecx = MOV32ri 3
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $ecx, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value
-
-    ; Check that a reg clobber prevents identical locations merging.
-    $ecx = MOV32ri 4
-    $ecx = MOV32ri 5
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $ecx, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value
-
-    ; Check that fragments are composed correctly.
-    $ecx = MOV32ri 6
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 16), $eax, debug-location !15
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 16, 16), $ecx, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2
-
-    ; Check that fragments clobber preceeding overlap.
-    $edi = MOV32ri 7
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 16, 16), $edi, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_breg5 RDI+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2
-
-    ; Check that a (non-zero-offset) fragment works.
-    $ecx = MOV32ri 8
-    $ecx = MOV32ri 9
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 16, 16), $eax, $ecx, debug-location !15
-    ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value, DW_OP_piece 0x2
-
-    RETQ debug-location !15
-...

diff  --git a/llvm/test/DebugInfo/X86/dbg_value_list_emission.mir b/llvm/test/DebugInfo/X86/dbg_value_list_emission.mir
deleted file mode 100644
index e3380cb42a4b..000000000000
--- a/llvm/test/DebugInfo/X86/dbg_value_list_emission.mir
+++ /dev/null
@@ -1,101 +0,0 @@
-# RUN: llc %s --start-after=livedebugvalues -filetype=obj -o - \
-# RUN:     | llvm-dwarfdump - -name local* -regex \
-# RUN:     | FileCheck %s
-#
-# Test that we produce correct DWARF from DBG_VALUE_LIST instructions.
-# Comments and test directives inline.
-
---- |
-  target triple = "x86_64-unknown-linux-gnu"
-  define dso_local i32 @fun() local_unnamed_addr !dbg !7 {
-  entry:
-    ret i32 0
-  }
-
-  !llvm.dbg.cu = !{!0}
-  !llvm.module.flags = !{!3, !4, !5}
-  !llvm.ident = !{!6}
-
-  !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
-  !1 = !DIFile(filename: "example.c", directory: "/")
-  !2 = !{}
-  !3 = !{i32 7, !"Dwarf Version", i32 4}
-  !4 = !{i32 2, !"Debug Info Version", i32 3}
-  !5 = !{i32 1, !"wchar_size", i32 4}
-  !6 = !{!"clang version 11.0.0"}
-  !8 = !DISubroutineType(types: !9)
-  !9 = !{!10}
-  !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-  !11 = !{!12, !13, !25}
-  !22 = !DISubroutineType(types: !23)
-  !23 = !{!10, !10}
-  ; --- Important metadata ---
-  !7 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
-  !15 = !DILocation(line: 1, column: 1, scope: !7)
-  !12 = !DILocalVariable(name: "locala", scope: !7, file: !1, line: 1, type: !10)
-  !13 = !DILocalVariable(name: "localb", scope: !7, file: !1, line: 2, type: !10)
-  !25 = !DILocalVariable(name: "localc", scope: !7, file: !1, line: 3, type: !10)
-  !26 = !DILocalVariable(name: "locald", scope: !7, file: !1, line: 4, type: !10)
-  !27 = !DILocalVariable(name: "locale", scope: !7, file: !1, line: 5, type: !10)
-  !28 = !DILocalVariable(name: "localf", scope: !7, file: !1, line: 6, type: !10)
-  !29 = !DILocalVariable(name: "localg", scope: !7, file: !1, line: 6, type: !10)
-  !30 = !DILocalVariable(name: "localh", scope: !7, file: !1, line: 6, type: !10)
-
-...
----
-name:            fun
-body:             |
-  bb.0.entry:
-    ; NOTE: By design, all DBG_VALUE_LIST instructions describe stack_value
-    ;       locations, so they are always created with a DW_OP_stack_value op.
-    ;
-    ; (1) Check a single reg arg works.
-    DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $eax, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ;  CHECK-NEXT:   (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value)
-    ;  CHECK-NEXT:   DW_AT_name ("locala")
-
-    ; (2) Check multiple reg args work.
-    DBG_VALUE_LIST !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $edi, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg5 RDI+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value)
-    ; CHECK-NEXT:   DW_AT_name ("localb")
-
-    ; (3) Check that multiple references to one reg arg works.
-    DBG_VALUE_LIST !25, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 0, DW_OP_minus, DW_OP_stack_value), $eax, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_minus, DW_OP_stack_value)
-    ; CHECK-NEXT:   DW_AT_name ("localc")
-
-    ; (4) Check constant and reg args work together.
-    DBG_VALUE_LIST !26, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_mul, DW_OP_stack_value), $eax, 5, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_lit5, DW_OP_mul, DW_OP_stack_value)
-    ; CHECK-NEXT:   DW_AT_name ("locald")
-
-    ; (5) Check that arg deref works.
-    DBG_VALUE_LIST !27, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref, DW_OP_stack_value), $eax, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_deref, DW_OP_stack_value)
-    ; CHECK-NEXT:   DW_AT_name ("locale")
-
-    ; (6) Check that fragments work.
-    DBG_VALUE_LIST !28, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 16), $eax, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2)
-    ; CHECK-NEXT:   DW_AT_name ("localf")
-
-    ; (7) Check that constant register offsets are correctly folded.
-    DBG_VALUE_LIST !29, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 5, DW_OP_LLVM_arg, 1, DW_OP_plus_uconst, 17, DW_OP_plus, DW_OP_stack_value), $eax, $edi, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   (DW_OP_breg0 RAX+5, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg5 RDI+17, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value)
-    ; CHECK-NEXT:   DW_AT_name ("localg")
-    
-    ; (8) Check that a single $noreg location invalidates the entire entry.
-    DBG_VALUE_LIST !30, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $noreg, debug-location !15
-    ; CHECK:      DW_TAG_variable
-    ; CHECK-NEXT:   DW_AT_name ("localh")
-    ; CHECK-NOT:   DW_AT_location
-
-    RETQ debug-location !15
-...


        


More information about the llvm-commits mailing list