[llvm] c383f4d - [DebugInfo] Allow non-stack_value variadic expressions and use in DBG_INSTR_REF

Stephen Tozer via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 6 11:32:03 PST 2023


Author: Stephen Tozer
Date: 2023-01-06T19:31:10Z
New Revision: c383f4d6550e30866294a0e1907a4519245c03eb

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

LOG: [DebugInfo] Allow non-stack_value variadic expressions and use in DBG_INSTR_REF

Prior to this patch, variadic DIExpressions (i.e. ones that contain
DW_OP_LLVM_arg) could only be created by salvaging debug values to create
stack value expressions, resulting in a DBG_VALUE_LIST being created. As of
the previous patch in this patch stack, DBG_INSTR_REF's syntax has been
changed to match DBG_VALUE_LIST in preparation for supporting variadic
expressions. This patch adds some minor changes needed to allow variadic
expressions that aren't stack values to exist, and allows variadic expressions
that are trivially reduceable to non-variadic expressions to be handled
similarly to non-variadic expressions.

Reviewed by: jmorse

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

Added: 
    

Modified: 
    llvm/docs/MIRLangRef.rst
    llvm/include/llvm/IR/DebugInfoMetadata.h
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
    llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
    llvm/lib/CodeGen/LiveDebugVariables.cpp
    llvm/lib/CodeGen/MachineFunction.cpp
    llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
    llvm/lib/IR/DebugInfoMetadata.cpp
    llvm/lib/Transforms/Utils/Local.cpp
    llvm/test/CodeGen/X86/dbg-value-superreg-copy2.mir
    llvm/test/DebugInfo/COFF/pieces.ll
    llvm/test/DebugInfo/MIR/InstrRef/accept-nonlive-reg-phis.mir
    llvm/test/DebugInfo/MIR/InstrRef/dbg-phi-subregister-location.mir
    llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv.mir
    llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv2.mir
    llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-merging-in-ldv.mir
    llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-with-loops.mir
    llvm/test/DebugInfo/MIR/InstrRef/deref-spills-with-size.mir
    llvm/test/DebugInfo/MIR/InstrRef/follow-spill-of-live-value.mir
    llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_illegal_locs.mir
    llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_instrref_tolocs.mir
    llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_stackslot_subregs.mir
    llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_subreg_substitutions.mir
    llvm/test/DebugInfo/MIR/InstrRef/memory-operand-folding-tieddef.mir
    llvm/test/DebugInfo/MIR/InstrRef/memory-operand-load-folding.mir
    llvm/test/DebugInfo/MIR/InstrRef/memory-operand-tracking.mir
    llvm/test/DebugInfo/MIR/InstrRef/out-of-scope-blocks.mir
    llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir
    llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir
    llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced.mir
    llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced2.mir
    llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir
    llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir
    llvm/test/DebugInfo/MIR/InstrRef/pick-vphi-in-shifting-loop.mir
    llvm/test/DebugInfo/MIR/InstrRef/spill-slot-limits.mir
    llvm/test/DebugInfo/MIR/InstrRef/stack-coloring-dbg-phi.mir
    llvm/test/DebugInfo/MIR/InstrRef/survives-livedebugvars.mir
    llvm/test/DebugInfo/MIR/InstrRef/win32-chkctk-modifies-esp.mir
    llvm/test/DebugInfo/MIR/InstrRef/x86-drop-compare-inst.mir
    llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
    llvm/test/DebugInfo/X86/dbg-value-funcarg.ll
    llvm/test/DebugInfo/X86/dbg-value-funcarg2.ll
    llvm/test/DebugInfo/X86/dbg-value-funcarg4.ll
    llvm/test/DebugInfo/X86/dbg-value-list-selectiondag-salvage.ll
    llvm/test/DebugInfo/X86/debug_value_list_selectiondag.ll
    llvm/test/DebugInfo/X86/instr-ref-dbg-declare.ll
    llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll
    llvm/test/DebugInfo/X86/live-debug-values-expr-conflict.ll
    llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll
    llvm/test/DebugInfo/X86/pieces-4.ll
    llvm/test/DebugInfo/X86/pr34545.ll
    llvm/test/DebugInfo/X86/sdag-combine.ll
    llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
    llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll
    llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
    llvm/test/DebugInfo/X86/sdag-salvage-add.ll
    llvm/test/DebugInfo/X86/sdagsplit-1.ll
    llvm/test/DebugInfo/X86/spill-nospill.ll
    llvm/test/DebugInfo/assignment-tracking/X86/loop-sink.ll
    llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
    llvm/test/DebugInfo/assignment-tracking/X86/remove-undef-fragment.ll
    llvm/test/DebugInfo/assignment-tracking/X86/sdag-dangling-dbgassign.ll
    llvm/unittests/IR/MetadataTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/MIRLangRef.rst b/llvm/docs/MIRLangRef.rst
index cd7819ed5c7f0..223701599ebb8 100644
--- a/llvm/docs/MIRLangRef.rst
+++ b/llvm/docs/MIRLangRef.rst
@@ -747,7 +747,7 @@ The example below uses a reference to Instruction 1, Operand 0:
 
 .. code-block:: text
 
-    DBG_INSTR_REF !123, !DIExpression(), dbg-instr-ref(1, 0), debug-location !456
+    DBG_INSTR_REF !123, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !456
 
 CFIIndex Operands
 ^^^^^^^^^^^^^^^^^
@@ -913,7 +913,7 @@ instruction number and operand number. Consider the example below:
 .. code-block:: text
 
     $rbp = MOV64ri 0, debug-instr-number 1, debug-location !12
-    DBG_INSTR_REF !123, !DIExpression(), dbg-instr-ref(1, 0), debug-location !456
+    DBG_INSTR_REF !123, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !456
 
 Instruction numbers are directly attached to machine instructions with an
 optional ``debug-instr-number`` attachment, before the optional

diff  --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 26189382725c0..19bd6fdb5c9cb 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2794,6 +2794,17 @@ class DIExpression : public MDNode {
   /// it cannot be a simple register location.
   bool isComplex() const;
 
+  /// Return whether the evaluated expression makes use of a single location at
+  /// the start of the expression, i.e. if it contains only a single
+  /// DW_OP_LLVM_arg op as its first operand, or if it contains none.
+  bool isSingleLocationExpression() const;
+
+  /// If \p Expr is a non-variadic expression (i.e. one that does not contain
+  /// DW_OP_LLVM_arg), returns \p Expr converted to variadic form by adding a
+  /// leading [DW_OP_LLVM_arg, 0] to the expression; otherwise returns \p Expr.
+  static const DIExpression *
+  convertToVariadicExpression(const DIExpression *Expr);
+
   /// Inserts the elements of \p Expr into \p Ops modified to a canonical form,
   /// which uses DW_OP_LLVM_arg (i.e. is a variadic expression) and folds the
   /// implied derefence from the \p IsIndirect flag into the expression. This

diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index db511bff6d2ec..4d3fa1e09ff6b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1132,10 +1132,16 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
   OS << " <- ";
 
   const DIExpression *Expr = MI->getDebugExpression();
+  if (Expr->getNumElements() && Expr->isSingleLocationExpression() &&
+      Expr->expr_op_begin()->getOp() == dwarf::DW_OP_LLVM_arg) {
+    SmallVector<uint64_t> Ops(
+        make_range(Expr->elements_begin() + 2, Expr->elements_end()));
+    Expr = DIExpression::get(Expr->getContext(), Ops);
+  }
   if (Expr->getNumElements()) {
     OS << '[';
     ListSeparator LS;
-    for (auto Op : Expr->expr_ops()) {
+    for (auto &Op : Expr->expr_ops()) {
       OS << LS << dwarf::OperationEncodingString(Op.getOp());
       for (unsigned I = 0; I < Op.getNumArgs(); ++I)
         OS << ' ' << Op.getArg(I);

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 42146edb32d73..2008aa39ff87f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -119,13 +119,7 @@ class DbgValueLoc {
 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));
-#endif
-  }
+        IsVariadic(true) {}
 
   DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
               bool IsVariadic)
@@ -136,10 +130,6 @@ class DbgValueLoc {
            !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));
     }
 #endif
   }

diff  --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index 4f45501adf96f..01e810e1ef16d 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -1262,7 +1262,7 @@ MLocTracker::emitLoc(const SmallVectorImpl<ResolvedDbgOp> &DbgOps,
           // the pointer to the variable loaded off the stack with a deref:
           assert(!Expr->isImplicit());
           OffsetOps.push_back(dwarf::DW_OP_deref);
-        } else if (UseDerefSize && !Properties.IsVariadic) {
+        } else if (UseDerefSize && Expr->isSingleLocationExpression()) {
           // TODO: Figure out how to handle deref size issues for variadic
           // values.
           // We're loading a value off the stack that's not the same size as the
@@ -1271,7 +1271,7 @@ MLocTracker::emitLoc(const SmallVectorImpl<ResolvedDbgOp> &DbgOps,
           OffsetOps.push_back(dwarf::DW_OP_deref_size);
           OffsetOps.push_back(DerefSizeInBytes);
           StackValue = true;
-        } else if (Expr->isComplex()) {
+        } else if (Expr->isComplex() || Properties.IsVariadic) {
           // A variable with no size ambiguity, but with extra elements in it's
           // expression. Manually dereference the stack location.
           OffsetOps.push_back(dwarf::DW_OP_deref);
@@ -1590,7 +1590,7 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
   // about it. The rest of this LiveDebugValues implementation acts exactly the
   // same for DBG_INSTR_REFs as DBG_VALUEs (just, the former can refer to values
   // that aren't immediately available).
-  DbgValueProperties Properties(Expr, false, false);
+  DbgValueProperties Properties(Expr, false, true);
   SmallVector<DbgOpID> DbgOpIDs;
   if (NewID)
     DbgOpIDs.push_back(DbgOpStore.insert(*NewID));
@@ -1634,7 +1634,7 @@ bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
       NewID->getInst() > CurInst) {
     SmallVector<DbgOp> UseBeforeDefLocs;
     UseBeforeDefLocs.push_back(*NewID);
-    TTracker->addUseBeforeDef(V, {MI.getDebugExpression(), false, false},
+    TTracker->addUseBeforeDef(V, {MI.getDebugExpression(), false, true},
                               UseBeforeDefLocs, NewID->getInst());
   }
 

diff  --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 60e6dfb451513..ffc688e360dfe 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -138,8 +138,7 @@ class DbgVariableValue {
       // Turn this into an undef debug value list; right now, the simplest form
       // of this is an expression with one arg, and an undef debug operand.
       Expression =
-          DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0,
-                                                dwarf::DW_OP_stack_value});
+          DIExpression::get(Expr.getContext(), {dwarf::DW_OP_LLVM_arg, 0});
       if (auto FragmentInfoOpt = Expr.getFragmentInfo())
         Expression = *DIExpression::createFragmentExpression(
             Expression, FragmentInfoOpt->OffsetInBits,

diff  --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index fad5981695abd..9625099cfe2cf 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -44,6 +44,7 @@
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/Constant.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/GlobalValue.h"
@@ -1153,6 +1154,10 @@ void MachineFunction::finalizeDebugInstrRefs() {
         MakeUndefDbgValue(MI);
         continue;
       }
+      // Only convert Expr to variadic form when we're sure we're emitting a
+      // complete instruction reference.
+      MI.getDebugExpressionOp().setMetadata(
+          DIExpression::convertToVariadicExpression(MI.getDebugExpression()));
 
       assert(Reg.isVirtual());
       MachineInstr &DefMI = *RegInfo->def_instr_begin(Reg);

diff  --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index e37eb7e4cd0f5..2ee4a047a1deb 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -767,7 +767,7 @@ InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
   assert(!SD->isVariadic());
   SDDbgOperand DbgOperand = SD->getLocationOps()[0];
   MDNode *Var = SD->getVariable();
-  DIExpression *Expr = (DIExpression*)SD->getExpression();
+  const DIExpression *Expr = (DIExpression *)SD->getExpression();
   DebugLoc DL = SD->getDebugLoc();
   const MCInstrDesc &RefII = TII->get(TargetOpcode::DBG_INSTR_REF);
 
@@ -851,6 +851,10 @@ InstrEmitter::EmitDbgInstrRef(SDDbgValue *SD,
   }
   assert(OperandIdx < DefMI->getNumOperands());
 
+  // Only convert Expr to variadic form when we're sure we're emitting a
+  // complete instruction reference.
+  if (!SD->isVariadic())
+    Expr = DIExpression::convertToVariadicExpression(Expr);
   // Make the DBG_INSTR_REF refer to that instruction, and that operand.
   unsigned InstrNum = DefMI->getDebugInstrNum();
   SmallVector<MachineOperand, 1> MOs(

diff  --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 5808c3f2c8419..41f9ca2e9772a 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1358,12 +1358,15 @@ bool DIExpression::isValid() const {
       break;
     }
     case dwarf::DW_OP_LLVM_entry_value: {
-      // An entry value operator must appear at the beginning and the number of
-      // operations it cover can currently only be 1, because we support only
-      // entry values of a simple register location. One reason for this is that
-      // we currently can't calculate the size of the resulting DWARF block for
-      // other expressions.
-      return I->get() == expr_op_begin()->get() && I->getArg(0) == 1;
+      // An entry value operator must appear at the beginning or immediately
+      // following `DW_OP_LLVM_arg 0`, and the number of operations it cover can
+      // currently only be 1, because we support only entry values of a simple
+      // register location. One reason for this is that we currently can't
+      // calculate the size of the resulting DWARF block for other expressions.
+      auto FirstOp = expr_op_begin();
+      if (FirstOp->getOp() == dwarf::DW_OP_LLVM_arg && FirstOp->getArg(0) == 0)
+        ++FirstOp;
+      return I->get() == FirstOp->get() && I->getArg(0) == 1;
     }
     case dwarf::DW_OP_LLVM_implicit_pointer:
     case dwarf::DW_OP_LLVM_convert:
@@ -1432,6 +1435,7 @@ bool DIExpression::isComplex() const {
     switch (It.getOp()) {
     case dwarf::DW_OP_LLVM_tag_offset:
     case dwarf::DW_OP_LLVM_fragment:
+    case dwarf::DW_OP_LLVM_arg:
       continue;
     default:
       return true;
@@ -1441,6 +1445,36 @@ bool DIExpression::isComplex() const {
   return false;
 }
 
+bool DIExpression::isSingleLocationExpression() const {
+  if (!isValid())
+    return false;
+
+  if (getNumElements() == 0)
+    return true;
+
+  auto ExprOpBegin = expr_ops().begin();
+  auto ExprOpEnd = expr_ops().end();
+  if (ExprOpBegin->getOp() == dwarf::DW_OP_LLVM_arg)
+    ++ExprOpBegin;
+
+  return !std::any_of(ExprOpBegin, ExprOpEnd, [](auto Op) {
+    return Op.getOp() == dwarf::DW_OP_LLVM_arg;
+  });
+}
+
+const DIExpression *
+DIExpression::convertToVariadicExpression(const DIExpression *Expr) {
+  if (any_of(Expr->expr_ops(), [](auto ExprOp) {
+        return ExprOp.getOp() == dwarf::DW_OP_LLVM_arg;
+      }))
+    return Expr;
+  SmallVector<uint64_t> NewOps;
+  NewOps.reserve(Expr->getNumElements() + 2);
+  NewOps.append({dwarf::DW_OP_LLVM_arg, 0});
+  NewOps.append(Expr->elements_begin(), Expr->elements_end());
+  return DIExpression::get(Expr->getContext(), NewOps);
+}
+
 void DIExpression::canonicalizeExpressionOps(SmallVectorImpl<uint64_t> &Ops,
                                              const DIExpression *Expr,
                                              bool IsIndirect) {
@@ -1596,10 +1630,21 @@ DIExpression *DIExpression::appendOpsToArg(const DIExpression *Expr,
 
   SmallVector<uint64_t, 8> NewOps;
   for (auto Op : Expr->expr_ops()) {
+    // A DW_OP_stack_value comes at the end, but before a DW_OP_LLVM_fragment.
+    if (StackValue) {
+      if (Op.getOp() == dwarf::DW_OP_stack_value)
+        StackValue = false;
+      else if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
+        NewOps.push_back(dwarf::DW_OP_stack_value);
+        StackValue = false;
+      }
+    }
     Op.appendToVector(NewOps);
     if (Op.getOp() == dwarf::DW_OP_LLVM_arg && Op.getArg(0) == ArgNo)
       NewOps.insert(NewOps.end(), Ops.begin(), Ops.end());
   }
+  if (StackValue)
+    NewOps.push_back(dwarf::DW_OP_stack_value);
 
   return DIExpression::get(Expr->getContext(), NewOps);
 }

diff  --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index a1c4bc8986c3a..e43a3fbaefdbe 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1908,8 +1908,8 @@ void llvm::salvageDebugInfoForDbgValues(
       DII->addVariableLocationOps(AdditionalValues, SalvagedExpr);
     } else {
       // Do not salvage using DIArgList for dbg.addr/dbg.declare, as it is
-      // currently only valid for stack value expressions. Do not salvage
-      // using DIArgList for dbg.assign yet. FIXME: support this.
+      // not currently supported in those instructions. Do not salvage using
+      // DIArgList for dbg.assign yet. FIXME: support this.
       // Also do not salvage if the resulting DIArgList would contain an
       // unreasonably large number of values.
       DII->setKillLocation();

diff  --git a/llvm/test/CodeGen/X86/dbg-value-superreg-copy2.mir b/llvm/test/CodeGen/X86/dbg-value-superreg-copy2.mir
index cfda97f77874f..6f8a05d302a4a 100644
--- a/llvm/test/CodeGen/X86/dbg-value-superreg-copy2.mir
+++ b/llvm/test/CodeGen/X86/dbg-value-superreg-copy2.mir
@@ -39,7 +39,7 @@ body:             |
     %0:gr16_abcd = MOV16ri 1, debug-instr-number 1, debug-location !9
 
   bb.1:
-    DBG_INSTR_REF !7, !DIExpression(), dbg-instr-ref(2, 0), debug-location !9
+    DBG_INSTR_REF !7, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !9
     %1:gr16 = COPY %0, debug-location !9
     %2:gr16 = COPY %0
 

diff  --git a/llvm/test/DebugInfo/COFF/pieces.ll b/llvm/test/DebugInfo/COFF/pieces.ll
index a447c92ba60c1..2d20b50751e71 100644
--- a/llvm/test/DebugInfo/COFF/pieces.ll
+++ b/llvm/test/DebugInfo/COFF/pieces.ll
@@ -101,7 +101,7 @@
 ; ASM:         callq   g
 ; ASM:         movl    %eax, [[offset_o_x:[0-9]+]](%rsp)          # 4-byte Spill
 ; ASM: [[spill_o_x_start:\.Ltmp[0-9]+]]:
-; ASM:         #DEBUG_VALUE: bitpiece_spill:o <- [DW_OP_plus_uconst [[offset_o_x]], DW_OP_LLVM_fragment 32 32] [$rsp+0]
+; ASM:         #DEBUG_VALUE: bitpiece_spill:o <- [DW_OP_plus_uconst [[offset_o_x]], DW_OP_deref, DW_OP_LLVM_fragment 32 32] $rsp
 ; ASM:         #APP
 ; ASM:         #NO_APP
 ; ASM:         movl    [[offset_o_x]](%rsp), %eax          # 4-byte Reload

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/accept-nonlive-reg-phis.mir b/llvm/test/DebugInfo/MIR/InstrRef/accept-nonlive-reg-phis.mir
index d6186bd2cacaa..9f88a423ff390 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/accept-nonlive-reg-phis.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/accept-nonlive-reg-phis.mir
@@ -80,7 +80,7 @@ body:             |
   bb.0.entry:
   
     DBG_PHI $fp0, 3
-    DBG_INSTR_REF !17, !DIExpression(), dbg-instr-ref(3, 0), debug-location !30
+    DBG_INSTR_REF !17, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !30
     $eax = MOV32ri 0
     RET 0, debug-location !36
 

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phi-subregister-location.mir b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phi-subregister-location.mir
index f1841072cc798..d1431ab0d34ff 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phi-subregister-location.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phi-subregister-location.mir
@@ -10,7 +10,7 @@
 # CHECK-LABEL: name: foo
 # CHECK:       DBG_PHI $edi
 # CHECK-NEXT:  DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-# CHECK-NEXT:  DBG_VALUE $dil
+# CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $dil
 --- |
   ; ModuleID = 'out.ll'
   source_filename = "out.ll"
@@ -63,7 +63,7 @@ body:             |
     liveins: $edi
 
     DBG_PHI $edi, 1
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(2, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
     renamable $rax = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @someglobal, $noreg, debug-location !13 :: (load (s64) from got)
     MOV8mr killed renamable $rax, 1, $noreg, 0, $noreg, renamable $dil, debug-location !13 :: (store (s8) into @someglobal)
     RET64 debug-location !13

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv.mir b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv.mir
index 1ff3b2d1272ea..08e9b302221be 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv.mir
@@ -134,7 +134,7 @@ body:             |
     DBG_PHI $rbx, 1
     $rax = COPY $rbx
     $rbx = MOV64ri 0
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
 
     ; This sequence should mark the contents of rbx on block entry as being the
     ; value for the variable at this DBG_INSTR_REF. We've force it to be in
@@ -143,7 +143,7 @@ body:             |
     ; CHECK-NEXT: $rax = COPY $rbx
     ; CHECK-NEXT: $rbx = MOV64ri 0
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT: DBG_VALUE $rax, $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}} $rax
 
     $rbx = COPY $rax
     renamable $rbx = ADD64rr killed renamable $rbx, killed renamable $r14, implicit-def $eflags, debug-location !23

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv2.mir b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv2.mir
index e6118ab249fcf..7255788c8b540 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv2.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-in-ldv2.mir
@@ -84,9 +84,9 @@ body:             |
     MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)
 
     ;; This should resolve to the loaded register.
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT: DBG_VALUE $rcx
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}} $rcx
 
     ;; And if we say it's a smaller size, we should be able to pick out smaller
     ;; subregisters within the stack slot.
@@ -96,9 +96,9 @@ body:             |
     MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)
 
     ;; This should pick out the 32 bit value.
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(2, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT: DBG_VALUE $ecx
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}} $ecx
 
     ;; Try all the other subregs.
     DBG_PHI %stack.0, 3, 16
@@ -106,18 +106,18 @@ body:             |
     $rcx = MOV64rm $rsp, 1, $noreg, 8, $noreg :: (load 8 from %stack.0)
     MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)
 
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(3, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !13
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 0)
-    ; CHECK-NEXT: DBG_VALUE $cx
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}} $cx
 
     DBG_PHI %stack.0, 4, 8
     $rax = MOV64ri 0
     $rcx = MOV64rm $rsp, 1, $noreg, 8, $noreg :: (load 8 from %stack.0)
     MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)
 
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(4, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(4, 0), debug-location !13
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(4, 0)
-    ; CHECK-NEXT: DBG_VALUE $cl
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}} $cl
 
     ;; We can't, at this time, describe subregister fields with nonzero offset.
     ;; It's easily achieved by attaching more data to stack DBG_PHIs, but it's

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-merging-in-ldv.mir b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-merging-in-ldv.mir
index d02d2a6c1512f..e06fa4335ad08 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-merging-in-ldv.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-merging-in-ldv.mir
@@ -158,32 +158,32 @@ body:             |
   bb.3.if.end:
     liveins: $rbx, $r14
   
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(2, 0), debug-location !13
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(3, 0), debug-location !13
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !13
 
     ; Value number 1 is live-through the above control flow from the two
     ; DBG_PHIs:
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT:  DBG_VALUE $r14
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $r14
     ;
     ; While value number 2 has 
diff erent defs that merge on entry to bb.3.
     ; These are both in $rbx though, and we should find its location:
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT:  DBG_VALUE $rbx
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $rbx
     ;
     ; Value number 3 cannot be resolved because $rax is clobbered in bb.2,
     ; meaning the merged value in bb.3 is incorrect. It should produce a
     ; DBG_VALUE $noreg.
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 0)
-    ; CHECK-NEXT:  DBG_VALUE $noreg
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $noreg
 
     renamable $rbx = ADD64rr killed renamable $rbx, killed renamable $r14, implicit-def $eflags, debug-location !28
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(2, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
 
     ; After clobbering rbx, the variable location should not be available.
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT:  DBG_VALUE $noreg
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $noreg
 
     $rdi = MOV64rr $rbx, debug-location !29
     CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !29

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-with-loops.mir b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-with-loops.mir
index 05bdd37312020..a9cb23ffbc12f 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-with-loops.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/dbg-phis-with-loops.mir
@@ -164,32 +164,32 @@ body:             |
   bb.4:
     liveins: $rbx, $r14
   
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(2, 0), debug-location !13
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(3, 0), debug-location !13
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !13
 
     ; Value number 1 is live-through the above control flow from the two
     ; DBG_PHIs:
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT:  DBG_VALUE $r14
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $r14
     ;
     ; While value number 2 has 
diff erent defs that merge on entry to bb.3.
     ; These are both in $rbx though, and we should find its location:
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT:  DBG_VALUE $rbx
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $rbx
     ;
     ; Value number 3 cannot be resolved because $rax is clobbered in bb.2,
     ; meaning the merged value in bb.3 is incorrect. It should produce a
     ; DBG_VALUE $noreg.
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 0)
-    ; CHECK-NEXT:  DBG_VALUE $noreg
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $noreg
 
     renamable $rbx = ADD64rr killed renamable $rbx, killed renamable $r14, implicit-def $eflags, debug-location !28
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(2, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !13
 
     ; After clobbering rbx, the variable location should not be available.
     ; CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT:  DBG_VALUE $noreg
+    ; CHECK-NEXT:  DBG_VALUE_LIST {{.+}} $noreg
 
     $rdi = MOV64rr $rbx, debug-location !29
     CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, debug-location !29

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/deref-spills-with-size.mir b/llvm/test/DebugInfo/MIR/InstrRef/deref-spills-with-size.mir
index 0fcf5d85f3ead..352e41d00203d 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/deref-spills-with-size.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/deref-spills-with-size.mir
@@ -168,19 +168,19 @@ body:             |
     ;; the size of the value on the stack makes it through to the expression.
 
     $al = MOV8ri 0, debug-instr-number 1, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), dbg-instr-ref(1, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $al, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed,
-    ; CHECK-SAME     : DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value)
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), dbg-instr-ref(1, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_convert, 8, DW_ATE_signed,
+    ; CHECK-SAME     : DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), $al
 
     MOV8mr $rsp, 1, $noreg, -8, $noreg, renamable $al :: (store 1 into %stack.0)
     ;; Clobber to force variable location onto stack. We should use a
     ;; deref_size 1 because the value is smaller than the variable.
     $al = MOV8ri 0, debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, 
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, 
     ; CHECK-SAME:     DW_OP_deref_size, 1, DW_OP_LLVM_convert, 8, DW_ATE_signed,
-    ; CHECK-SAME:     DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value),
+    ; CHECK-SAME:     DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), $rsp
 
     ; Terminate the current variable location,
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
@@ -189,11 +189,11 @@ body:             |
     ;; Try again, but with the value originating on the stack, to ensure that
     ;; we can find its size. It should be deref_size 1 again.
     INC8m $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, debug-instr-number 2, debug-location !7 :: (store (s8) into %stack.0)
-    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), dbg-instr-ref(2, 1000000), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus,
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_convert, 8, DW_ATE_signed, DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), dbg-instr-ref(2, 1000000), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus,
     ; CHECK-SAME:     DW_OP_deref_size, 1, DW_OP_LLVM_convert, 8, DW_ATE_signed,
-    ; CHECK-SAME:     DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value),
+    ; CHECK-SAME:     DW_OP_LLVM_convert, 32, DW_ATE_signed, DW_OP_stack_value), $rsp
 
     $eax = MOV32ri 0, debug-location !7
 
@@ -209,17 +209,17 @@ body:             |
 
     MOV32mr $rsp, 1, $noreg, -8, $noreg, renamable $eax :: (store 4 into %stack.0)
     $eax = MOV32ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(), dbg-instr-ref(7, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_stack_value)
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(7, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_stack_value), $rsp
 
     $eax = MOV32ri 0, debug-location !7
 
     ;; And for when the DBG_PHI specifies a stack size...
     DBG_PHI %stack.0, 8, 16
-    DBG_INSTR_REF !8, !DIExpression(), dbg-instr-ref(8, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 2, DW_OP_stack_value)
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(8, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 2, DW_OP_stack_value), $rsp
 
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
@@ -237,9 +237,9 @@ body:             |
     $rax = MOV64ri 0, debug-instr-number 10, debug-location !7
     MOV64mr $rsp, 1, $noreg, -8, $noreg, renamable $rax :: (store 8 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(), dbg-instr-ref(10, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_stack_value),
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(10, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_stack_value), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -248,9 +248,9 @@ body:             |
     $eax = MOV32ri 0, debug-instr-number 11, debug-location !7
     MOV32mr $rsp, 1, $noreg, -8, $noreg, renamable $eax :: (store 4 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(), dbg-instr-ref(11, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, 0, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus),
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(11, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -259,9 +259,9 @@ body:             |
     $al = MOV8ri 0, debug-instr-number 12, debug-location !7
     MOV8mr $rsp, 1, $noreg, -8, $noreg, renamable $al :: (store 1 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(), dbg-instr-ref(12, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_stack_value),
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(12, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_stack_value), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -270,9 +270,9 @@ body:             |
     $rax = MOV64ri 0, debug-instr-number 13, debug-location !7
     MOV64mr $rsp, 1, $noreg, -8, $noreg, renamable $rax :: (store 8 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(13, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM2]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32),
+    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(13, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM2]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -281,9 +281,9 @@ body:             |
     $eax = MOV32ri 0, debug-instr-number 14, debug-location !7
     MOV32mr $rsp, 1, $noreg, -8, $noreg, renamable $eax :: (store 4 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(14, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, 0, ![[VARNUM2]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_LLVM_fragment, 0, 32),
+    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(14, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM2]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_LLVM_fragment, 0, 32), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -292,9 +292,9 @@ body:             |
     $al = MOV8ri 0, debug-instr-number 15, debug-location !7
     MOV8mr $rsp, 1, $noreg, -8, $noreg, renamable $al :: (store 1 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(15, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM2]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32),
+    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(15, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM2]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -305,9 +305,9 @@ body:             |
     $rax = MOV64ri 0, debug-instr-number 16, debug-location !7
     MOV64mr $rsp, 1, $noreg, -8, $noreg, renamable $rax :: (store 8 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), dbg-instr-ref(16, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value),
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), dbg-instr-ref(16, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -316,9 +316,9 @@ body:             |
     $eax = MOV32ri 0, debug-instr-number 17, debug-location !7
     MOV32mr $rsp, 1, $noreg, -8, $noreg, renamable $eax :: (store 4 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), dbg-instr-ref(17, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value),
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), dbg-instr-ref(17, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -327,9 +327,9 @@ body:             |
     $al = MOV8ri 0, debug-instr-number 18, debug-location !7
     MOV8mr $rsp, 1, $noreg, -8, $noreg, renamable $al :: (store 1 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !8, !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), dbg-instr-ref(18, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value),
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), dbg-instr-ref(18, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !8, !DIExpression(), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -338,9 +338,9 @@ body:             |
     $rax = MOV64ri 0, debug-instr-number 19, debug-location !7
     MOV64mr $rsp, 1, $noreg, -8, $noreg, renamable $rax :: (store 8 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !10, !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(19, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM2]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32),
+    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(19, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM2]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 8, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -349,9 +349,9 @@ body:             |
     $eax = MOV32ri 0, debug-instr-number 20, debug-location !7
     MOV32mr $rsp, 1, $noreg, -8, $noreg, renamable $eax :: (store 4 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !10, !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(20, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM2]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 4, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32),
+    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(20, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM2]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 4, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg
@@ -360,9 +360,9 @@ body:             |
     $al = MOV8ri 0, debug-instr-number 21, debug-location !7
     MOV8mr $rsp, 1, $noreg, -8, $noreg, renamable $al :: (store 1 into %stack.0)
     $rax = MOV64ri 0, debug-location !7
-    DBG_INSTR_REF !10, !DIExpression(DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(21, 0), debug-location !7
-    ; CHECK:      DBG_VALUE $rsp, $noreg, ![[VARNUM2]],
-    ; CHECK-SAME: !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32),
+    DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(21, 0), debug-location !7
+    ; CHECK:      DBG_VALUE_LIST ![[VARNUM2]],
+    ; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref_size, 1, DW_OP_constu, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 32), $rsp
     $eax = MOV32ri 0, debug-location !7
     DBG_VALUE $noreg, $noreg, !10, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location !7
     ; CHECK: DBG_VALUE $noreg, $noreg

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/follow-spill-of-live-value.mir b/llvm/test/DebugInfo/MIR/InstrRef/follow-spill-of-live-value.mir
index 516c4fbafacfd..159a70c82bcdf 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/follow-spill-of-live-value.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/follow-spill-of-live-value.mir
@@ -20,9 +20,9 @@
 # CHECK: ![[VARNUM:[0-9]+]] = !DILocalVariable
 #
 # CHECK-LABEL: bb.8:
-# CHECK:       DBG_VALUE $rsp, 0, ![[VARNUM]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_LLVM_fragment, 64, 64),
+# CHECK:       DBG_VALUE_LIST ![[VARNUM]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_LLVM_fragment, 64, 64), $rsp,
 # CHECK-LABEL:  bb.9:
-# CHECK:       DBG_VALUE $rsp, 0, ![[VARNUM]], !DIExpression(DW_OP_constu, 8, DW_OP_minus, DW_OP_LLVM_fragment, 64, 64),
+# CHECK:       DBG_VALUE_LIST ![[VARNUM]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref, DW_OP_LLVM_fragment, 64, 64), $rsp,
 
 --- |
   ; ModuleID = 'missingvar.ll'
@@ -302,7 +302,7 @@ body:             |
     MOV64mr undef renamable $rax, 1, $noreg, 0, $noreg, killed renamable $r10, debug-location !7 :: (store 8 into `%"class.llvm::Loop"*** undef`)
     MOV64mr killed renamable $rdi, 1, $noreg, 40, $noreg, killed renamable $r9, debug-location !7 :: (store 8 into %ir.24)
     renamable $rax = MOV64rm killed renamable $rsi, 1, $noreg, 24, $noreg, debug-location !7 :: (load 8 from %ir.26)
-    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location !7
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location !7
     renamable $rax = SUB64rr killed renamable $rax, killed renamable $r11, implicit-def dead $eflags, debug-location !7
     renamable $r8 = SUB64rr killed renamable $r8, killed renamable $r14, implicit-def dead $eflags, debug-location !7
     renamable $r8 = exact SAR64ri killed renamable $r8, 3, implicit-def dead $eflags, debug-location !7

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_illegal_locs.mir b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_illegal_locs.mir
index a8435d8a20795..b543469a45985 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_illegal_locs.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_illegal_locs.mir
@@ -45,37 +45,37 @@ body:  |
     ; CHECK-LABE: bb.0.entry:
 
     $rax = MOV64ri 1, debug-instr-number 1, debug-location !17
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(1, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
     ;; First check that picking out location works as usual.
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT: DBG_VALUE $rax
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $rax
 
     $rax = MOV64ri 1, debug-instr-number 2, debug-location !17
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(2, 999), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 999), debug-location !17
     ;; Test out of bounds operand number.
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 999)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     $rax = MOV64ri 1, debug-instr-number 3, debug-location !17
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(3, 1), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 1), debug-location !17
     ;; Test non-register operand
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 1)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     ;; FIXME: We should test what happens when this meta-instruction is seen
     ;; by livedbugvalues with an instruction number. However, right now it's
     ;; impossible to turn the machine-code verifier off when loading MIR?
     ;KILL implicit killed $eflags, debug-instr-number 4, debug-location !17
-    ;DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(4, 0), debug-location !17
+    ;DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(4, 0), debug-location !17
     ;;; Test non-def operand
     ;; check:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(4, 0)
-    ;; check-next: DBG_VALUE $noreg
+    ;; check-next: DBG_VALUE_LIST {{.+}}, $noreg
 
     $noreg = MOV32ri 1, debug-instr-number 5, debug-location !17
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(5, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 0), debug-location !17
     ;; Def of $noreg?
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(5, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     JCC_1 %bb.1, 1, implicit $eflags
     JMP_1 %bb.2
@@ -85,10 +85,10 @@ body:  |
     ; CHECK-LABEL: bb.1:
 
     DBG_PHI $rax, 6
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(6, 1), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(6, 1), debug-location !17
     ;; Test out-of-bounds reference to a DBG_PHI.
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(6, 1)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     DBG_PHI $noreg, 7
     JMP_1 %bb.3
@@ -97,22 +97,22 @@ body:  |
     successors: %bb.3
     ; CHECK-LABEL: bb.2:
     DBG_PHI 1, 6
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(6, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(6, 0), debug-location !17
     ;; Test non-reg operand to DBG_PHI. It's not clear if this can ever happen
     ;; as the result of an optimisation, but lets test for it anyway.
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(6, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     DBG_PHI 1, 7
     JMP_1 %bb.3
 
   bb.3:
     ; CHECK-LABEL: bb.3:
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(7, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(7, 0), debug-location !17
     ;; PHI resolution of illegal inputs shouldn't crash either. It should also
     ;; come out as a $noreg location.
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(7, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     RET 0, debug-location !17
 

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_instrref_tolocs.mir b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_instrref_tolocs.mir
index 9ec72ca2a5465..593a9ee7a949b 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_instrref_tolocs.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_instrref_tolocs.mir
@@ -37,17 +37,17 @@ body:  |
   bb.0.entry:
     $rax = MOV64ri 1, debug-instr-number 1, debug-location !17
     ; This debug instruction should identify the value as being in $rax.
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(1, 0), debug-location !17
-    ; CHECK: DBG_VALUE $rax, $noreg
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !17
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rax
 
     $rbx = COPY killed $rax, debug-location !17
     $rax = MOV64ri 1, debug-location !17
-    ; CHECK: DBG_VALUE $rbx, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rbx
 
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(2, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !17
     ; No instruction is labelled with the number "2". This should produce an
     ; empty variable location.
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
 
     $rbx = MOV64ri 1, debug-instr-number 3, debug-location !17
     JMP_1 %bb.1
@@ -56,40 +56,40 @@ body:  |
     ; CHECK-LABEL: bb.1:
   bb.1:
 
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(3, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !17
     ; This refers to a value def'd in a parent block -- but it should be
     ; tracked into this block.
-    ; CHECK: DBG_VALUE $rbx, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rbx
     JMP_1 %bb.2
 
     ; CHECK-LABEL: bb.2:
   bb.2:
     ; Just like any other variable location, live-ins should be created for
     ; any successor blocks.
-    ; CHECK: DBG_VALUE $rbx, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rbx
 
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(5, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 0), debug-location !17
     ; This is a debug use-before-def: the value appears a few instructions
     ; later. Any earlier value should be terminated here, _and_ we should
     ; emit a DBG_VALUE when the value becomes available.
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
 
     $rax = MOV64ri 1, debug-location !17
     $rax = MOV64ri 1, debug-location !17
     $rcx = MOV64ri 1, debug-instr-number 5, debug-location !17
-    ; CHECK: DBG_VALUE $rcx, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rcx
     $rax = MOV64ri 1, debug-location !17
 
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(6, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(6, 0), debug-location !17
     ; Another debug use-before-def, but across block boundaries.
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
     JMP_1 %bb.3
 
     ; CHECK-LABEL: bb.3:
   bb.3:
     $rax = MOV64ri 1, debug-location !17
     $rdx = MOV64ri 1, debug-instr-number 6, debug-location !17
-    ; CHECK: DBG_VALUE $rdx, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rdx
 
     ; Terminate variable location for next few blocks,
     DBG_VALUE $noreg, $noreg, !16, !DIExpression(), debug-location !17
@@ -104,8 +104,8 @@ body:  |
     $rdx = MOV64ri 1, implicit-def $eflags, debug-location !17
     JCC_1 %bb.6, 4, implicit $eflags, debug-location !17
   bb.5:
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(7, 0), debug-location !17
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(7, 0), debug-location !17
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
     JMP_1 %bb.6, debug-location !17
   bb.6:
     $rsi = MOV64ri 1, debug-instr-number 7, debug-location !17
@@ -114,8 +114,8 @@ body:  |
   ; A use-before-def shouldn't pass another definition of the variable location
   ; or value.
   bb.7:
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(8, 0), debug-location !17
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(8, 0), debug-location !17
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
     DBG_VALUE $rax, $noreg, !16, !DIExpression(), debug-location !17
     ; CHECK: DBG_VALUE $rax, $noreg,
     $rdi = MOV64ri 1, debug-instr-number 8, debug-location !17
@@ -123,33 +123,33 @@ body:  |
   ; Loops: use-before-defs should be live-through loops, assuming that nothing
   ; in that loop modifies the variable location.
   bb.8:
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(9, 0), debug-location !17
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(9, 0), debug-location !17
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
     JCC_1 %bb.8, 4, implicit $eflags
   bb.9:
     $rax = MOV64ri 11, debug-instr-number 9, debug-location !17
-    ; CHECK: DBG_VALUE $rax, $noreg,
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rax
 
   ; Likewise, use-before-defs where anything changes the variable location
   ; or value in the loop, should be discarded.
   bb.10:
     ; live-in,
-    ; CHECK: DBG_VALUE $rax, $noreg,
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(10, 0), debug-location !17
-    ; CHECK: DBG_VALUE $noreg, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rax
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(10, 0), debug-location !17
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $noreg
 
   bb.11:
     $rbx = MOV64ri 1, debug-location !17
 
   bb.12:
-    DBG_INSTR_REF !16, !DIExpression(), dbg-instr-ref(9, 0), debug-location !17
+    DBG_INSTR_REF !16, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(9, 0), debug-location !17
     ; This still has a value in $rax,
-    ; CHECK: DBG_VALUE $rax, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rax
     JCC_1 %bb.11, 4, implicit $eflags
 
   bb.13:
     ; Live in,
-    ; CHECK: DBG_VALUE $rax, $noreg
+    ; CHECK: DBG_VALUE_LIST {{.+}}, $rax
     $rbx = MOV64ri 11, debug-instr-number 10, debug-location !17
     ; This is instruction 10 referred to in bb.10. However, as the variable
     ; location/value has been modified in the meantime, no DBG_VALUE should be

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_stackslot_subregs.mir b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_stackslot_subregs.mir
index f6c53a77e68a7..0270f8d0cfe84 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_stackslot_subregs.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_stackslot_subregs.mir
@@ -49,8 +49,8 @@ body:  |
     $rax = MOV64ri 0
     $rdi = MOV64ri 0
 
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK:      DBG_INSTR_REF
-    ; CHECK-NEXT: DBG_VALUE $esi
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $esi
     RET64 $rsi, debug-location !12
 ...

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_subreg_substitutions.mir b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_subreg_substitutions.mir
index 615585bc43f6e..f75de1102c2c6 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_subreg_substitutions.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_subreg_substitutions.mir
@@ -71,39 +71,39 @@ body:  |
   liveins: $rdi, $rax
     CALL64pcrel32 @ext, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rax, debug-instr-number 4, debug-location !12
     ; CHECK:      CALL64pcrel32
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT: DBG_VALUE $al
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(5, 0), debug-location !12
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $al
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(5, 0)
-    ; CHECK-NEXT: DBG_VALUE $ah
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(8, 0), debug-location !12
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $ah
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(8, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(8, 0)
-    ; CHECK-NEXT: DBG_VALUE $ah
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(13, 0), debug-location !12
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $ah
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(13, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(13, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
     MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax :: (store 8 into %stack.0)
     $rax = MOV64ri 0, debug-location !12
     ; CHECK:      $rax = MOV64ri 0
     ; The value is now located in a spill slot, as a subregister within the
     ; slot, which InstrRefBasedLDV should be able to find.
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT: DBG_VALUE $rsp, 0, !{{[0-9]*}}, !DIExpression(DW_OP_constu, 8, DW_OP_minus)
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(5, 0), debug-location !12
+    ; CHECK-NEXT: DBG_VALUE_LIST !{{[0-9]*}}, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 8, DW_OP_minus, DW_OP_deref), $rsp
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 0), debug-location !12
     ; This and the next DBG_INSTR_REF refer to a value that is on the stack, but
     ; is located at a non-zero offset from the start of the slot -- $ah within
     ; $rax is 8 bits in. Today, InstrRefBasedLDV can't express this. It also
     ; doesn't seem likely to be profitable.
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(5, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(8, 0), debug-location !12
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(8, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(8, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(13, 0), debug-location !12
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(13, 0), debug-location !12
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(13, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
     $rax = MOV64rm $rsp, 1, $noreg, 8, $noreg :: (load 8 from %stack.0)
     RET64 $rax, debug-location !12
 ...

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-folding-tieddef.mir b/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-folding-tieddef.mir
index e55f6993a5b82..54ab5b06735ef 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-folding-tieddef.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-folding-tieddef.mir
@@ -171,6 +171,6 @@ body:             |
     CALL64r %37, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit $rsi, implicit-def $rsp, implicit-def $ssp, implicit-def $al, debug-location !13
     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp, debug-location !13
     %13:gr32 = INC32r %6, implicit-def dead $eflags, debug-instr-number 1, debug-location !13
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
     JMP_1 %bb.1, debug-location !13
 ...

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-load-folding.mir b/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-load-folding.mir
index db8bd10990564..a90512f3245b2 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-load-folding.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-load-folding.mir
@@ -111,7 +111,7 @@ body:             |
   
     %7:gr32 = nofpexcept CVTTSS2SIrr killed %1, implicit $mxcsr, debug-instr-number 1
     %8:gr8 = COPY killed %7.sub_8bit
-    DBG_INSTR_REF !6, !DIExpression(), dbg-instr-ref(2, 0), debug-location !17
+    DBG_INSTR_REF !6, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !17
     TEST8rr killed %8, %8, implicit-def $eflags
     JCC_1 %bb.3, 5, implicit killed $eflags
     JMP_1 %bb.2

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-tracking.mir b/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-tracking.mir
index e6d51c2b7bd6b..420edb5088861 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-tracking.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/memory-operand-tracking.mir
@@ -52,33 +52,33 @@ body:  |
     MOV64mr $rsp, 1, $noreg, 16, $noreg, $rdi :: (store 8 into %stack.0)
     $rax = MOV64ri 0, debug-location !12
     INC32m $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, debug-instr-number 3, debug-location !DILocation(line: 0, scope: !7) :: (store (s32) into %stack.0)
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(2, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !12
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT: DBG_VALUE $rsp
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $rsp
     ;; Test that the old value (from the DBG_PHI) is not tracked anywhere. It
     ;; should not be considered as being on the stack any more.
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
     INC32m $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, debug-location !12 :: (store (s32) into %stack.0)
     ;; The above INC32m should be detected as clobbering the stack location,
     ;; even though it isn't debug labelled.
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(2, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !12
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     ;; Store another debug-labelled value to the stack,
     INC32m $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, debug-instr-number 5, debug-location !DILocation(line: 0, scope: !7) :: (store (s32) into %stack.0)
     ;; Point the variable at that value.
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(4, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(4, 0), debug-location !12
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(4, 0),
-    ; CHECK-NEXT: DBG_VALUE $rsp
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $rsp
     ;; Overwrite the stack: LiveDebugValues should explicitly undef the stack
-    ;; location with DBG_VALUE $noreg, as DbgEntityHistoryCalculator doesn't
+    ;; location with DBG_VALUE_LIST $noreg, as DbgEntityHistoryCalculator doesn't
     ;; look at the stack.
     INC32m $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, debug-location !DILocation(line: 0, scope: !7) :: (store (s32) into %stack.0)
     ; CHECK:      INC32m $rsp
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     $rax = MOV64rm $rsp, 1, $noreg, 8, $noreg :: (load 8 from %stack.0)
     RET64 $rax, debug-location !12

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/out-of-scope-blocks.mir b/llvm/test/DebugInfo/MIR/InstrRef/out-of-scope-blocks.mir
index 7752f8059ab2f..cb150cb0fd8c1 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/out-of-scope-blocks.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/out-of-scope-blocks.mir
@@ -11,22 +11,22 @@
 # CHECK:       ![[FIRSTVAR:[0-9]+]] = !DILocalVariable(name: "_First",
 #
 # CHECK-LABEL: bb.0.entry:
-# CHECK:       DBG_VALUE $rbx, $noreg, ![[FIRSTVAR]],
-# CHECK-SAME:        !DIExpression(DW_OP_LLVM_fragment, 64, 64)
+# CHECK:       DBG_VALUE_LIST ![[FIRSTVAR]],
+# CHECK-SAME:        !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), $rbx
 #
 # CHECK-LABEL: bb.1.if.then.i.i.i.i.i:
-# CHECK:       DBG_VALUE $rbx, $noreg, ![[FIRSTVAR]],
-# CHECK-SAME:        !DIExpression(DW_OP_LLVM_fragment, 64, 64)
+# CHECK:       DBG_VALUE_LIST ![[FIRSTVAR]],
+# CHECK-SAME:        !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), $rbx
 # CHECK:       DBG_INSTR_REF ![[FIRSTVAR]],
-# CHECK:       DBG_VALUE $rbx, $noreg, ![[FIRSTVAR]],
-# CHECK-SAME:        !DIExpression(DW_OP_LLVM_fragment, 64, 64)
+# CHECK:       DBG_VALUE_LIST ![[FIRSTVAR]],
+# CHECK-SAME:        !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), $rbx
 
 # CHECK-LABEL: bb.2._Z17do_insert_cv_testI5_TreeEvv.exit:
-# CHECK:       DBG_VALUE $rbx, $noreg, ![[FIRSTVAR]],
-# CHECK-SAME:        !DIExpression(DW_OP_LLVM_fragment, 64, 64)
+# CHECK:       DBG_VALUE_LIST ![[FIRSTVAR]],
+# CHECK-SAME:        !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), $rbx
 # CHECK:       DBG_INSTR_REF ![[FIRSTVAR]],
-# CHECK:       DBG_VALUE $rbx, $noreg, ![[FIRSTVAR]],
-# CHECK-SAME:        !DIExpression(DW_OP_LLVM_fragment, 64, 64)
+# CHECK:       DBG_VALUE_LIST ![[FIRSTVAR]],
+# CHECK-SAME:        !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), $rbx
 
 --- |
   source_filename = "reduced.ll"
@@ -118,7 +118,7 @@ body:             |
     renamable $r14d = XOR32rr undef $r14d, undef $r14d, implicit-def dead $eflags, implicit-def $r14
     dead $edi = XOR32rr undef $edi, undef $edi, implicit-def dead $eflags, implicit-def $rdi
     CALL64r undef renamable $rax, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def dead $eax, implicit-def dead $rdx
-    DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(2, 0), debug-location !15
+    DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(2, 0), debug-location !15
     dead $edi = XOR32rr undef $edi, undef $edi, implicit-def dead $eflags, implicit-def $rdi, debug-location !15
     CALL64r undef renamable $rax, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def dead $al, debug-location !15
     TEST8rr renamable $r14b, renamable $r14b, implicit-def $eflags, implicit killed $r14
@@ -128,13 +128,13 @@ body:             |
     dead $edi = XOR32rr undef $edi, undef $edi, implicit-def dead $eflags, implicit-def $rdi
     CALL64r undef renamable $rax, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax, debug-instr-number 3
     $rbx = MOV64rr killed $rax
-    DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(3, 7), debug-location !15
+    DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(3, 7), debug-location !15
   
   bb.2._Z17do_insert_cv_testI5_TreeEvv.exit:
     liveins: $rbx
   
     DBG_PHI $rbx, 1
-    DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location !15
+    DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location !15
     dead $edi = XOR32rr undef $edi, undef $edi, implicit-def dead $eflags, implicit-def $rdi, debug-location !16
     $esi = XOR32rr undef $esi, undef $esi, implicit-def dead $eflags, debug-location !16
     $rdx = MOV64rr killed $rbx, debug-location !16

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir
index bee2975368bbb..0a2a375d7c781 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalesce-subreg.mir
@@ -144,7 +144,7 @@ body:             |
   bb.2.if.end:
     %2:gr16 = PHI %11, %bb.0, %17, %bb.1, debug-instr-number 1, debug-location !13
   ; CHECK:              DBG_PHI $bp, 1
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
     %31:gr32 = MOVSX32rr16 %6, debug-location !13
     %30:gr32 = MOVSX32rr16 killed %2, debug-location !13
     %29:gr32 = ADD32rr killed %30, killed %31, implicit-def $eflags, debug-location !13

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir
index 2cff265ab7680..95ef05e765964 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-coalescing.mir
@@ -147,7 +147,7 @@ body:             |
   bb.2.if.end:
     %2:gr64 = PHI %9, %bb.0, %10, %bb.1, debug-instr-number 1, debug-location !13
   ; CHECK:              DBG_PHI $r14, 1
-    DBG_INSTR_REF !12, !DIExpression(), dbg-instr-ref(1, 0), debug-location !13
+    DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !13
     %2:gr64 = ADD64rr killed %2, %6, implicit-def $eflags, debug-location !13
     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !13
     $rdi = COPY %2, debug-location !13

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced.mir
index c8096be6b0303..1378224354114 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced.mir
@@ -146,7 +146,7 @@ body:             |
     %64:gr32 = PHI %24, %bb.0, %44, %bb.1, debug-location !18
 
     INLINEASM &"", 1, 12, %50, 12, %51, 12, %52, 12, %53, 12, %54, 12, %55, 12, %56, 12, %57, 12, %58, 12, %59, 12, %60, 12, %61, 12, %62, 12, %63, 12, %64
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK:      DBG_PHI %stack.0, 1, 16
     ; CHECK:      DBG_INSTR_REF {{.+}} dbg-instr-ref(1, 0)
     ; CHECK:      renamable $eax = MOV32rm %stack.0,

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced2.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced2.mir
index 8768836a0b2ca..529259716d3a4 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced2.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-on-stack-coalesced2.mir
@@ -145,7 +145,7 @@ body:             |
     %64:gr32 = PHI %24, %bb.0, %44, %bb.1, debug-location !18
 
     INLINEASM &"", 1, 12, %50, 12, %51, 12, %52, 12, %53, 12, %54, 12, %55, 12, %56, 12, %57, 12, %58, 12, %59, 12, %60, 12, %61, 12, %62, 12, %63, 12, %64
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK-NOT:  DBG_PHI
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
     ; CHECK-NOT:  DBG_PHI

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir
index 7ccfbd42443cd..f6cf169ffe2ed 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-regallocd-to-stack.mir
@@ -139,7 +139,7 @@ body:             |
     %63:gr32 = PHI %23, %bb.0, %43, %bb.1, debug-location !18
     %64:gr32 = PHI %24, %bb.0, %44, %bb.1, debug-location !18
 
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK:      DBG_PHI %stack.1, 1, 32
     ; CHECK:      renamable $eax = MOV32rm %stack.1,
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir b/llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir
index 9ecd7e46c36ef..720cc609ccbaa 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/phi-through-regalloc.mir
@@ -120,7 +120,7 @@ body:             |
     ; CHECK-LABEL: bb.2.if.end:
   bb.2.if.end:
     %0:gr32 = PHI %1, %bb.0, %2, %bb.1, debug-instr-number 1, debug-location !18
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; CHECK:      DBG_PHI $ebp, 1
     ; CHECK:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
     $eax = COPY killed %0, debug-location !19

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/pick-vphi-in-shifting-loop.mir b/llvm/test/DebugInfo/MIR/InstrRef/pick-vphi-in-shifting-loop.mir
index d969102bf8c46..4c1b3cca45692 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/pick-vphi-in-shifting-loop.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/pick-vphi-in-shifting-loop.mir
@@ -12,11 +12,11 @@
 # in block 5.
 #
 # CHECK-LABEL: bb.3:
-# CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(7, 0)
-# CHECK-NEXT:  DBG_VALUE $rdx
+# CHECK:       DBG_INSTR_REF {{.+}}, dbg-instr-ref(7, 0)
+# CHECK-NEXT:  DBG_VALUE_LIST {{.+}}, $rdx
 # CHECK-NEXT:  $rcx = MOV64rr $rdx
 # CHECK-LABEL: bb.4:
-# CHECK:       DBG_VALUE $rcx
+# CHECK:       DBG_VALUE_LIST {{.+}}, $rcx
 # CHECK-NEXT:  $rdx = MOV64rr killed $rcx
 # CHECK-LABEL: bb.5:
 # CHECK-NOT:   DBG_VALUE
@@ -91,7 +91,7 @@ body:             |
     liveins: $rcx, $rdi, $rdx, $eflags
   
     DBG_PHI $rcx, 2
-    DBG_INSTR_REF !18, !DIExpression(), dbg-instr-ref(2, 0), debug-location !22
+    DBG_INSTR_REF !18, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !22
     JCC_1 %bb.1, 4, implicit $eflags, debug-location !22
   
   bb.2:
@@ -105,7 +105,7 @@ body:             |
     liveins: $rcx, $rdi, $eflags
   
     $rdx = MOV64ri 0, debug-instr-number 7, debug-location !22
-    DBG_INSTR_REF !18, !DIExpression(), dbg-instr-ref(7, 0), debug-location !22
+    DBG_INSTR_REF !18, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(7, 0), debug-location !22
     $rcx = MOV64rr $rdx
     JMP_1 %bb.5, debug-location !22
   

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/spill-slot-limits.mir b/llvm/test/DebugInfo/MIR/InstrRef/spill-slot-limits.mir
index 7f1d25e42962a..e7410a6f977b9 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/spill-slot-limits.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/spill-slot-limits.mir
@@ -19,17 +19,17 @@
 # CHECK: ![[VARNUM:[0-9]+]] = !DILocalVariable
 #
 ## There should be no variable location, just a single DBG_VALUE $noreg.
-# CHECK:     DBG_VALUE $noreg
+# CHECK:     DBG_VALUE_LIST {{.+}} $noreg
 #
 ## And then another.
-# CHECK:     DBG_VALUE $noreg
+# CHECK:     DBG_VALUE_LIST {{.+}} $noreg
 #
 ## Test that if there's no limit, we _do_ get some locations.
 # NOLIMIT:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-# NOLIMIT-NEXT: DBG_VALUE $esi
+# NOLIMIT-NEXT: DBG_VALUE_LIST {{.+}} $esi
 #
 # NOLIMIT:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(5,
-# NOLIMIT-NEXT: DBG_VALUE $rsp
+# NOLIMIT-NEXT: DBG_VALUE_LIST {{.+}} $rsp
 --- |
   define i8 @test(i32 %bar) local_unnamed_addr !dbg !7 {
   entry:
@@ -75,7 +75,7 @@ body:  |
     $rax = MOV64ri 0
     $rdi = MOV64ri 0
 
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(1, 0), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !12
     ; This shouldn't find anything -- we have disabled tracking of spills.
 
     ; In addition to plain spills, spills that are folded into instructions
@@ -83,7 +83,7 @@ body:  |
     INC32m $rsp, 1, $noreg, 4, $noreg, implicit-def dead $eflags, debug-instr-number 5, debug-location !12 :: (store (s32) into %stack.0)
 
 
-    DBG_INSTR_REF !11, !DIExpression(), dbg-instr-ref(5, 1000000), debug-location !12
+    DBG_INSTR_REF !11, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 1000000), debug-location !12
     ; Shouldn't be able to find the reference to instr 5's memory operand.
 
     RET64 $rsi, debug-location !12

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/stack-coloring-dbg-phi.mir b/llvm/test/DebugInfo/MIR/InstrRef/stack-coloring-dbg-phi.mir
index 2079ec7305370..e76f142b9349d 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/stack-coloring-dbg-phi.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/stack-coloring-dbg-phi.mir
@@ -219,7 +219,7 @@ body:             |
     ;AAAAAA %4:gr32 = PHI %0, %bb.11, %10, %bb.21, debug-instr-number 1
     ;BBBBBB %4:gr32 = PHI %0, %bb.11, %10, %bb.21
     %5:gr32 = PHI undef %35:gr32, %bb.11, %9, %bb.21
-    ;AAAAAA DBG_INSTR_REF !10, !DIExpression(), dbg-instr-ref(1, 0), debug-location !9
+    ;AAAAAA DBG_INSTR_REF !10, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !9
     ;BBBBBB DBG_VALUE %4, 0, !10, !DIExpression(), debug-location !9
     %39:gr8 = COPY %27.sub_8bit
     TEST8rr killed %39, %39, implicit-def $eflags, debug-location !9

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/survives-livedebugvars.mir b/llvm/test/DebugInfo/MIR/InstrRef/survives-livedebugvars.mir
index 2c9808027fff3..ed4c6a7e71f24 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/survives-livedebugvars.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/survives-livedebugvars.mir
@@ -112,18 +112,18 @@ body:             |
     %2:gr64 = COPY $rdi
     %3:gr64 = COPY killed %2
     %5:gr32 = COPY killed %4
-    DBG_INSTR_REF !9, !DIExpression(), dbg-instr-ref(1, 0), debug-location !16
+    DBG_INSTR_REF !9, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !16
     JMP_1 %bb.3
 
   bb.1:
-    DBG_INSTR_REF !9, !DIExpression(), dbg-instr-ref(2, 0), debug-location !16
+    DBG_INSTR_REF !9, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(2, 0), debug-location !16
     JMP_1 %bb.4
 
   bb.2:
     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !19
     $edi = COPY %6, debug-location !19
     $al = MOV8ri 0, debug-location !19
-    DBG_INSTR_REF !9, !DIExpression(), dbg-instr-ref(3, 0), debug-location !16
+    DBG_INSTR_REF !9, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !16
     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $al, implicit $edi, implicit-def $eax, debug-location !19
     ADJCALLSTACKUP64 0, 0, implicit-def $rsp, implicit-def $eflags, implicit-def $ssp, implicit $rsp, implicit $ssp, debug-location !19
     %7:gr32 = COPY $eax, debug-location !19
@@ -131,12 +131,12 @@ body:             |
 
   bb.3:
     %6:gr32 = MOV32rm %3, 1, $noreg, 0, $noreg, debug-location !17
-    DBG_INSTR_REF !9, !DIExpression(), dbg-instr-ref(4, 0), debug-location !16
+    DBG_INSTR_REF !9, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(4, 0), debug-location !16
     JMP_1 %bb.2
 
   bb.4:
     $eax = COPY %5, debug-location !18
-    DBG_INSTR_REF !9, !DIExpression(), dbg-instr-ref(5, 0), debug-location !16
+    DBG_INSTR_REF !9, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 0), debug-location !16
     RET64 implicit $eax, debug-location !18
 
 ...

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/win32-chkctk-modifies-esp.mir b/llvm/test/DebugInfo/MIR/InstrRef/win32-chkctk-modifies-esp.mir
index 42907a676f966..738c5d4fd762f 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/win32-chkctk-modifies-esp.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/win32-chkctk-modifies-esp.mir
@@ -142,9 +142,9 @@ body:             |
     CALLpcrel32 &_chkstk, implicit $esp, implicit $ssp, implicit $eax, implicit $esp, implicit-def dead $eax, implicit-def $esp, implicit-def dead $eflags, debug-instr-number 2, debug-location !41
     $ebx = MOV32rr $esp, debug-location !41
     $eax = MOV32ri 0
-    DBG_INSTR_REF !42, !DIExpression(DW_OP_deref), dbg-instr-ref(2, 6), debug-location !46
+    DBG_INSTR_REF !42, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref), dbg-instr-ref(2, 6), debug-location !46
     ; CHECK-LABEL: DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 6)
-    ; CHECK:       DBG_VALUE $esp
+    ; CHECK:       DBG_VALUE_LIST {{.+}}, $esp
 
     ;; Variable value is $esp / $ebx, will be based on $esp initially. We'll now
     ;; allocate more stack space, and several things should happen:
@@ -156,18 +156,18 @@ body:             |
     ;;    $ebx, which comes from the first modified $esp.
     CALLpcrel32 &_chkstk, implicit $esp, implicit $ssp, implicit $eax, implicit $esp, implicit-def dead $eax, implicit-def $esp, implicit-def dead $eflags, debug-instr-number 3, debug-location !41
     ; CHECK-NEXT: CALLpcrel32
-    ; CHECK-NEXT: DBG_VALUE $ebx
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $ebx
 
-    DBG_INSTR_REF !42, !DIExpression(DW_OP_deref), dbg-instr-ref(3, 6), debug-location !46
+    DBG_INSTR_REF !42, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref), dbg-instr-ref(3, 6), debug-location !46
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 6)
-    ; CHECK-NEXT: DBG_VALUE $esp
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $esp
 
     $esp = ADD32ri killed $esp, 0, implicit-def dead $eflags
     ; CHECK-NEXT: ADD32ri
 
-    DBG_INSTR_REF !42, !DIExpression(DW_OP_deref), dbg-instr-ref(3, 6), debug-location !46
+    DBG_INSTR_REF !42, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref), dbg-instr-ref(3, 6), debug-location !46
     ; CHECK-NEXT: DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 6)
-    ; CHECK-NEXT: DBG_VALUE $noreg
+    ; CHECK-NEXT: DBG_VALUE_LIST {{.+}}, $noreg
 
     $esp = MOV32rr $ebp, debug-location !49
     $ebp = frame-destroy POP32r implicit-def $esp, implicit $esp, debug-location !49

diff  --git a/llvm/test/DebugInfo/MIR/InstrRef/x86-drop-compare-inst.mir b/llvm/test/DebugInfo/MIR/InstrRef/x86-drop-compare-inst.mir
index 6fe833d57cd69..9482d13a62819 100644
--- a/llvm/test/DebugInfo/MIR/InstrRef/x86-drop-compare-inst.mir
+++ b/llvm/test/DebugInfo/MIR/InstrRef/x86-drop-compare-inst.mir
@@ -82,7 +82,7 @@ body:             |
     %0:gr64 = MOV64rm killed %1, 1, $noreg, 0, $noreg, debug-location !7 :: (load (s64) from `i8** undef`)
     %2:gr32 = COPY %0.sub_32bit, debug-location !7
     %3:gr32 = SUB32rm %2, %0, 1, $noreg, 0, $noreg, implicit-def $eflags, debug-instr-number 1, debug-location !7 :: (load (s32) from %ir._M_start.i2756, align 8)
-    DBG_INSTR_REF !8, !DIExpression(), dbg-instr-ref(1, 0), debug-location !7
+    DBG_INSTR_REF !8, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0), debug-location !7
     JCC_1 %bb.2, 5, implicit $eflags, debug-location !7
     JMP_1 %bb.1, debug-location !7
   

diff  --git a/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir b/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
index 5fe6218c6cd96..b980e6abf1b21 100644
--- a/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
+++ b/llvm/test/DebugInfo/MIR/X86/instr-ref-join-def-vphi.mir
@@ -12,7 +12,7 @@
 # CHECK: ![[VAR:[0-9]+]] = !DILocalVariable(name: "a"
 
 # CHECK-LABEL: bb.6
-# CHECK: DBG_VALUE $esi, $noreg, ![[VAR]], !DIExpression()
+# CHECK: DBG_VALUE_LIST ![[VAR]], !DIExpression(DW_OP_LLVM_arg, 0), $esi
 
 --- |
   target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -197,7 +197,7 @@ body:             |
 
     DBG_PHI $esi, 3
     DBG_PHI $edi, 2
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(3, 0), debug-location !16
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(3, 0), debug-location !16
     CALL64pcrel32 @"?bar@@YAHXZ", csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !19
     renamable $edi = nsw SUB32rr killed renamable $edi, killed renamable $eax, implicit-def dead $eflags, debug-instr-number 1, debug-location !19
     renamable $eax = IMUL32rri renamable $edi, -1431655765, implicit-def dead $eflags, debug-location !21
@@ -211,7 +211,7 @@ body:             |
 
     CALL64pcrel32 @"?bar@@YAHXZ", csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !22
     renamable $esi = nsw ADD32rr killed renamable $esi, killed renamable $eax, implicit-def dead $eflags, debug-instr-number 4, debug-location !22
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(4, 0), debug-location !16
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(4, 0), debug-location !16
     JMP_1 %bb.3
 
   bb.4 (%ir-block.16):
@@ -226,7 +226,7 @@ body:             |
     liveins: $esi
 
     CALL64pcrel32 @"?bar@@YAHXZ", csr_win64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def $eax, debug-location !31
-    DBG_INSTR_REF !14, !DIExpression(), dbg-instr-ref(5, 0), debug-location !16
+    DBG_INSTR_REF !14, !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(5, 0), debug-location !16
 
   bb.6 (%ir-block.22):
     liveins: $esi

diff  --git a/llvm/test/DebugInfo/X86/dbg-value-funcarg.ll b/llvm/test/DebugInfo/X86/dbg-value-funcarg.ll
index a2ce754a8e780..fed8a6e409926 100644
--- a/llvm/test/DebugInfo/X86/dbg-value-funcarg.ll
+++ b/llvm/test/DebugInfo/X86/dbg-value-funcarg.ll
@@ -61,7 +61,7 @@ define dso_local void @foo_local(i32 %t1a) local_unnamed_addr #0 !dbg !7 {
 ; INSTRREF-NEXT: DBG_VALUE 123, $noreg, ![[LOCAL]], !DIExpression(),
 ; INSTRREF:      CALL64pcrel32 @bar,
 ; INSTRREF-NEXT: ADJCALLSTACKUP64
-; INSTRREF:      DBG_INSTR_REF ![[LOCAL]], !DIExpression(), dbg-instr-ref(1, 0),
+; INSTRREF:      DBG_INSTR_REF ![[LOCAL]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0),
 ; INSTRREF-NOT: DBG_
 ; INSTRREF:    TCRETURNdi64 @bar,
 
@@ -96,7 +96,7 @@ define dso_local void @foo_other_param(i32 %t2a, i32 %t2b) local_unnamed_addr #0
 ; INSTRREF: CALL64pcrel32 @bar,
 ; INSTRREF: DBG_VALUE 123, $noreg, ![[T2B]], !DIExpression(),
 ; INSTRREF: CALL64pcrel32 @bar,
-; INSTRREF: DBG_INSTR_REF ![[T2B]], !DIExpression(), dbg-instr-ref(1, 0),
+; INSTRREF: DBG_INSTR_REF ![[T2B]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0),
 ; INSTRREF: TCRETURNdi64 @bar,
 
 entry:
@@ -125,10 +125,10 @@ define dso_local void @foo_same_param(i32 %t3a) local_unnamed_addr #0 !dbg !31 {
 ; INSTRREF: DBG_PHI $edi, 1
 ; INSTRREF: DBG_VALUE $edi, $noreg, ![[T3A]], !DIExpression(),
 ; INSTRREF: CALL64pcrel32 @bar,
-; INSTRREF: DBG_INSTR_REF ![[TMP]], !DIExpression(), dbg-instr-ref(1, 0),
+; INSTRREF: DBG_INSTR_REF ![[TMP]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0),
 ; INSTRREF: DBG_VALUE 123, $noreg, ![[T3A]], !DIExpression(),
 ; INSTRREF: CALL64pcrel32 @bar,
-; INSTRREF: DBG_INSTR_REF ![[T3A]], !DIExpression(), dbg-instr-ref(1, 0),
+; INSTRREF: DBG_INSTR_REF ![[T3A]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0),
 ; INSTRREF: TCRETURNdi64 @bar,
 entry:
   call void @llvm.dbg.value(metadata i32 %t3a, metadata !33, metadata !DIExpression()), !dbg !35

diff  --git a/llvm/test/DebugInfo/X86/dbg-value-funcarg2.ll b/llvm/test/DebugInfo/X86/dbg-value-funcarg2.ll
index 970f1db46cdea..3d383bf9dfb3f 100644
--- a/llvm/test/DebugInfo/X86/dbg-value-funcarg2.ll
+++ b/llvm/test/DebugInfo/X86/dbg-value-funcarg2.ll
@@ -60,8 +60,8 @@ define dso_local i32 @f(i64 %s1.coerce0, i64 %s1.coerce1, i64 %s2.coerce0, i64 %
 ;; of the earlier DBG_PHIs.
 ; INSTRREF:     ADJCALLSTACKUP
 ; INSTRREF-NOT: DBG_
-; INSTRREF-DAG: DBG_INSTR_REF ![[S1]], !DIExpression(DW_OP_LLVM_fragment, 0, 64), dbg-instr-ref(1, 0)
-; INSTRREF-DAG: DBG_INSTR_REF ![[S1]], !DIExpression(DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(2, 0)
+; INSTRREF-DAG: DBG_INSTR_REF ![[S1]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 64), dbg-instr-ref(1, 0)
+; INSTRREF-DAG: DBG_INSTR_REF ![[S1]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(2, 0)
 
 ; And then no more DBG_ instructions before the add.
 ; COMMON-NOT: DBG_

diff  --git a/llvm/test/DebugInfo/X86/dbg-value-funcarg4.ll b/llvm/test/DebugInfo/X86/dbg-value-funcarg4.ll
index af3e317787574..b63269a51d093 100644
--- a/llvm/test/DebugInfo/X86/dbg-value-funcarg4.ll
+++ b/llvm/test/DebugInfo/X86/dbg-value-funcarg4.ll
@@ -9,8 +9,8 @@
 
 ; CHECK: DBG_PHI $edi, 1
 
-; CHECK: DBG_INSTR_REF ![[LOCAL]], !DIExpression(), dbg-instr-ref(1, 0)
-; CHECK: DBG_INSTR_REF ![[LOCAL2]], !DIExpression(), dbg-instr-ref(1, 0)
+; CHECK: DBG_INSTR_REF ![[LOCAL]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
+; CHECK: DBG_INSTR_REF ![[LOCAL2]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 
 declare void @bar(i32)
 declare void @llvm.dbg.value(metadata, metadata, metadata)

diff  --git a/llvm/test/DebugInfo/X86/dbg-value-list-selectiondag-salvage.ll b/llvm/test/DebugInfo/X86/dbg-value-list-selectiondag-salvage.ll
index 6cb37d1e09b76..7abd0262284db 100644
--- a/llvm/test/DebugInfo/X86/dbg-value-list-selectiondag-salvage.ll
+++ b/llvm/test/DebugInfo/X86/dbg-value-list-selectiondag-salvage.ll
@@ -1,4 +1,4 @@
-; RUN: llc %s -start-after=codegenprepare -stop-before=finalize-isel -o - | FileCheck %s
+; RUN: llc %s -start-after=codegenprepare -stop-before=finalize-isel -experimental-debug-variable-locations=false -o - | FileCheck %s
 
 ;; Generated from clang -O2 -emit-llvm -S -g reduce.c -o -
 ;; $ cat reduce.c

diff  --git a/llvm/test/DebugInfo/X86/debug_value_list_selectiondag.ll b/llvm/test/DebugInfo/X86/debug_value_list_selectiondag.ll
index 1607708e67c82..4ba8f5fabfc9f 100644
--- a/llvm/test/DebugInfo/X86/debug_value_list_selectiondag.ll
+++ b/llvm/test/DebugInfo/X86/debug_value_list_selectiondag.ll
@@ -1,6 +1,6 @@
-; RUN: llc %s -start-after=codegenprepare -stop-before=finalize-isel -o - | FileCheck --check-prefixes=CHECK,DAG %s
-; RUN: llc %s -fast-isel=true -start-after=codegenprepare -stop-before=finalize-isel -o - | FileCheck --check-prefixes=CHECK,FAST %s
-; RUN: llc %s -global-isel=true -start-after=codegenprepare -stop-before=finalize-isel -o - | FileCheck --check-prefixes=CHECK,GLOBAL %s
+; RUN: llc %s -start-after=codegenprepare -stop-before=finalize-isel -experimental-debug-variable-locations=false -o - | FileCheck --check-prefixes=CHECK,DAG %s
+; RUN: llc %s -fast-isel=true -start-after=codegenprepare -stop-before=finalize-isel -experimental-debug-variable-locations=false -o - | FileCheck --check-prefixes=CHECK,FAST %s
+; RUN: llc %s -global-isel=true -start-after=codegenprepare -stop-before=finalize-isel -experimental-debug-variable-locations=false -o - | FileCheck --check-prefixes=CHECK,GLOBAL %s
 
 ;; Test that a dbg.value that uses a DIArgList is correctly converted to a
 ;; DBG_VALUE_LIST that uses the registers corresponding to its operands.
@@ -8,16 +8,16 @@
 ; CHECK-DAG: [[A_VAR:![0-9]+]] = !DILocalVariable(name: "a"
 ; CHECK-DAG: [[B_VAR:![0-9]+]] = !DILocalVariable(name: "b"
 ; CHECK-DAG: [[C_VAR:![0-9]+]] = !DILocalVariable(name: "c"
-; CHECK-LABEL: bb.{{(0|1)}}.entry
-; DAG-DAG: DBG_VALUE_LIST [[A_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), %0, debug-location
-; DAG-DAG: DBG_VALUE_LIST [[B_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), %1, debug-location
-; DAG: DBG_VALUE_LIST [[C_VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %0, %1, debug-location
-; FAST-DAG: DBG_VALUE $noreg, $noreg, [[A_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
-; FAST-DAG: DBG_VALUE $noreg, $noreg, [[B_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
-; FAST: DBG_VALUE $noreg, $noreg, [[C_VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), debug-location
-; GLOBAL-DAG: DBG_VALUE $noreg, 0, [[A_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
-; GLOBAL-DAG: DBG_VALUE $noreg, 0, [[B_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
-; GLOBAL: DBG_VALUE $noreg, 0, [[C_VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), debug-location
+; CHECK-LABEL: bb.{{(0|1)}}.entry
+; DAG-DAG: DBG_VALUE_LIST [[A_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), %0, debug-location
+; DAG-DAG: DBG_VALUE_LIST [[B_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), %1, debug-location
+; DAG: DBG_VALUE_LIST [[C_VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), %0, %1, debug-location
+; FAST-DAG: DBG_VALUE $noreg, $noreg, [[A_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
+; FAST-DAG: DBG_VALUE $noreg, $noreg, [[B_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
+; FAST: DBG_VALUE $noreg, $noreg, [[C_VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), debug-location
+; GLOBAL-DAG: DBG_VALUE $noreg, 0, [[A_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
+; GLOBAL-DAG: DBG_VALUE $noreg, 0, [[B_VAR]], !DIExpression(DW_OP_LLVM_arg, 0), debug-location
+; GLOBAL: DBG_VALUE $noreg, 0, [[C_VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), debug-location
 
 target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc19.16.27034"

diff  --git a/llvm/test/DebugInfo/X86/instr-ref-dbg-declare.ll b/llvm/test/DebugInfo/X86/instr-ref-dbg-declare.ll
index 3954151091324..40ac544e0d248 100644
--- a/llvm/test/DebugInfo/X86/instr-ref-dbg-declare.ll
+++ b/llvm/test/DebugInfo/X86/instr-ref-dbg-declare.ll
@@ -11,7 +11,7 @@
 ;; NB: the original test has an additional spurious DW_OP_deref in the
 ;; dbg.declare's arguments, which is preserved here, translating to two derefs.
 
-; CHECK: DBG_INSTR_REF !{{[0-9]+}}, !DIExpression(DW_OP_deref, DW_OP_deref), dbg-instr-ref(1, 2)
+; CHECK: DBG_INSTR_REF !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref, DW_OP_deref), dbg-instr-ref(1, 2)
 
 source_filename = "test/DebugInfo/COFF/types-array-advanced.ll"
 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"

diff  --git a/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll b/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll
index 79ce92b567cc9..003f5f57b36c1 100644
--- a/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll
+++ b/llvm/test/DebugInfo/X86/instr-ref-selectiondag.ll
@@ -231,17 +231,17 @@ shoes:
 ; INSTRREF:      DBG_PHI $rdi, 1
 ; INSTRREF-NEXT: DBG_VALUE $rdi, 0, ![[SOCKS]], !DIExpression(),
 ; INSTRREF-NEXT: %0:gr64 = COPY $rdi
-; INSTRREF-NEXT: DBG_INSTR_REF ![[KNEES]], !DIExpression(DW_OP_deref), dbg-instr-ref(1, 0),
+; INSTRREF-NEXT: DBG_INSTR_REF ![[KNEES]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref), dbg-instr-ref(1, 0),
 
 ; In fast-isel mode, neither variable are hoisted or forwarded to a physreg.
 
 ; FASTISEL-INSTRREF-LABEL: name: qux
 
 ; FASTISEL-INSTRREF:      DBG_PHI $rdi, 1
-; FASTISEL-INSTRREF:      DBG_INSTR_REF ![[SOCKS]], !DIExpression(DW_OP_deref), dbg-instr-ref(1, 0),
+; FASTISEL-INSTRREF:      DBG_INSTR_REF ![[SOCKS]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref), dbg-instr-ref(1, 0),
 
 ; FASTISEL-INSTRREF-LABEL: bb.1.lala:
-; FASTISEL-INSTRREF:      DBG_INSTR_REF ![[KNEES]], !DIExpression(DW_OP_deref), dbg-instr-ref(1, 0),
+; FASTISEL-INSTRREF:      DBG_INSTR_REF ![[KNEES]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref), dbg-instr-ref(1, 0),
 declare i64 @cheddar(ptr %arg)
 
 define void @qux(ptr noalias sret(i32) %agg.result) !dbg !40 {

diff  --git a/llvm/test/DebugInfo/X86/live-debug-values-expr-conflict.ll b/llvm/test/DebugInfo/X86/live-debug-values-expr-conflict.ll
index 1d02ee70e9b40..afce27ee4abb9 100644
--- a/llvm/test/DebugInfo/X86/live-debug-values-expr-conflict.ll
+++ b/llvm/test/DebugInfo/X86/live-debug-values-expr-conflict.ll
@@ -24,16 +24,18 @@
 ; one in the block two, and none in block three.
 ; CHECK:       ![[BAZVAR:[0-9]+]] = !DILocalVariable(name: "baz",
 ; CHECK-LABEL: bb.0.entry:
-; CHECK:       DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
+; CHECK:       DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]], 
 ; CHECK-SAME:     !DIExpression()
 ; CHECK-LABEL: bb.1.if.then:
 ; CHECK-LABEL: bb.2.if.else:
-; CHECK:       DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
+; CHECK:       DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]], 
 ; CHECK-SAME:     !DIExpression()
-; CHECK:       DBG_VALUE {{[0-9a-zA-Z$%_]*}}, $noreg, ![[BAZVAR]],
-; CHECK-SAME:     !DIExpression(DW_OP_plus_uconst, 1, DW_OP_stack_value)
+; CHECK:       DBG_VALUE_LIST ![[BAZVAR]], 
+; CHECK-SAME:     !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 1, DW_OP_stack_value)
+; CHECK-SAME:     {{[0-9a-zA-Z$%_]*}}
 ; CHECK-LABEL: bb.3.if.end:
 ; CHECK-NOT:   DBG_VALUE
+; CHECK-NOT:   DBG_VALUE_LIST
 
 declare void @escape1(i32)
 declare void @escape2(i32)

diff  --git a/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll b/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll
index a6781a0622803..4cacb495b84ce 100644
--- a/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll
+++ b/llvm/test/DebugInfo/X86/live-debug-vars-loc-limit.ll
@@ -1,4 +1,4 @@
-; RUN: llc --stop-after=virtregrewriter -o - %s | FileCheck %s
+; RUN: llc --stop-after=virtregrewriter -experimental-debug-variable-locations=false -o - %s | FileCheck %s
 
 ; Check that any debug value with 64+ unique machine location operands is set
 ; undef by LiveDebugVariables.
@@ -11,7 +11,7 @@
 ; CHECK: ![[VAR_A:[0-9]+]] = !DILocalVariable(name: "a"
 
 ; CHECK-NOT: DBG_VALUE
-; CHECK: DBG_VALUE_LIST ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $noreg
+; CHECK: DBG_VALUE_LIST ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0), $noreg
 ; CHECK-NOT: DBG_VALUE
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

diff  --git a/llvm/test/DebugInfo/X86/pieces-4.ll b/llvm/test/DebugInfo/X86/pieces-4.ll
index 08ab559aa6822..adc93fc93a2cd 100644
--- a/llvm/test/DebugInfo/X86/pieces-4.ll
+++ b/llvm/test/DebugInfo/X86/pieces-4.ll
@@ -16,7 +16,7 @@
 ; CHECK-LABEL: bitpiece_spill:                         # @bitpiece_spill
 ; CHECK:               callq   g
 ; CHECK:               movl    %eax, [[offs:[0-9]+]](%rsp)          # 4-byte Spill
-; CHECK:               #DEBUG_VALUE: bitpiece_spill:o <- [DW_OP_plus_uconst [[offs]], DW_OP_LLVM_fragment 0 32] [$rsp+0]
+; CHECK:               #DEBUG_VALUE: bitpiece_spill:o <- [DW_OP_plus_uconst [[offs]], DW_OP_deref, DW_OP_LLVM_fragment 0 32] $rsp
 ; CHECK:               #DEBUG_VALUE: bitpiece_spill:o <- [DW_OP_LLVM_fragment 32 32] 0
 ; CHECK:               #APP
 ; CHECK:               #NO_APP

diff  --git a/llvm/test/DebugInfo/X86/pr34545.ll b/llvm/test/DebugInfo/X86/pr34545.ll
index f4ecce8db447b..013428f4b5581 100644
--- a/llvm/test/DebugInfo/X86/pr34545.ll
+++ b/llvm/test/DebugInfo/X86/pr34545.ll
@@ -10,17 +10,21 @@
 ; CHECK:         $eax = MOV32rm
 ; INSTRREF-SAME:      debug-instr-number 1
 ; INSTRREF:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(1, 0)
-; CHECK:         DBG_VALUE $eax
+; VARLOCS:         DBG_VALUE $eax
+; INSTRREF:        DBG_VALUE_LIST {{.+}} $eax
 ; CHECK:         $eax = SHL32rCL killed renamable $eax,
 ; INSTRREF-SAME:      debug-instr-number 2
 ; INSTRREF:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(2, 0)
-; CHECK:         DBG_VALUE $eax
-; CHECK:         DBG_VALUE $rsp, 0, !{{[0-9]+}}, !DIExpression(DW_OP_constu, 4, DW_OP_minus)
+; VARLOCS:       DBG_VALUE $eax
+; INSTRREF:      DBG_VALUE_LIST {{.+}} $eax
+; VARLOCS:       DBG_VALUE $rsp, 0, !{{[0-9]+}}, !DIExpression(DW_OP_constu, 4, DW_OP_minus)
+; INSTRREF:      DBG_VALUE_LIST !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_constu, 4, DW_OP_minus, DW_OP_deref), $rsp
 ; VARLOCS:       DBG_VALUE $eax
 ; CHECK:         $eax = SHL32rCL killed renamable $eax,
 ; INSTRREF-SAME:      debug-instr-number 3
 ; INSTRREF:      DBG_INSTR_REF {{.+}}, dbg-instr-ref(3, 0)
-; CHECK:         DBG_VALUE $eax
+; VARLOCS:       DBG_VALUE $eax
+; INSTRREF:      DBG_VALUE_LIST {{.+}} $eax
 ; CHECK:         RET64 $eax
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

diff  --git a/llvm/test/DebugInfo/X86/sdag-combine.ll b/llvm/test/DebugInfo/X86/sdag-combine.ll
index e48f8f345e102..4b8708830fdd5 100644
--- a/llvm/test/DebugInfo/X86/sdag-combine.ll
+++ b/llvm/test/DebugInfo/X86/sdag-combine.ll
@@ -17,7 +17,7 @@ entry:
   %0 = alloca %TSb, align 1
   %1 = call swiftcc i1 @f(), !dbg !7
   ; CHECK: DBG_VALUE $rcx, $noreg, !8, !DIExpression(),
-  ; INSTRREF: DBG_VALUE $ecx, $noreg, !8, !DIExpression(),
+  ; INSTRREF: DBG_VALUE_LIST !8, !DIExpression(DW_OP_LLVM_arg, 0), $ecx
   call void @llvm.dbg.value(metadata i1 %1, metadata !8, metadata !DIExpression()), !dbg !7
   store i1 %1, ptr %0, align 1, !dbg !7
   %2 = zext i1 %1 to i64, !dbg !7

diff  --git a/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll b/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
index aaa530df72678..629c236f68319 100644
--- a/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
+++ b/llvm/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll
@@ -73,7 +73,7 @@ define i32 @test1() local_unnamed_addr #0 !dbg !17 {
 ; CHECK-NEXT:    DBG_VALUE 0, $noreg, ![[BAR1]], !DIExpression()
 ; CHECK-NEXT:    [[REG1:%[0-9]+]]:gr64 = LEA64r 
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT:  DBG_INSTR_REF ![[FOO1]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT:  DBG_INSTR_REF ![[FOO1]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT:  DBG_VALUE [[REG1]], $noreg, ![[FOO1]], !DIExpression()
 entry1:
   call void @llvm.dbg.value(metadata ptr @S, metadata !20, metadata !DIExpression()), !dbg !23
@@ -86,8 +86,8 @@ define i32 @test2() local_unnamed_addr #0 !dbg !26 {
 ; CHECK-LABEL: bb.0.entry2
 ; CHECK-NEXT:    [[REG2:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO2]], !DIExpression(), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR2]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO2]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR2]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, ![[FOO2]], !DIExpression
 ; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, ![[BAR2]], !DIExpression
 entry2:
@@ -101,8 +101,8 @@ define i32 @test3() local_unnamed_addr #0 !dbg !33 {
 ; CHECK-LABEL: bb.0.entry3
 ; CHECK-NEXT:    [[REG3:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR3]], !DIExpression(), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO3]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR3]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO3]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, ![[BAR3]], !DIExpression()
 ; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, ![[FOO3]], !DIExpression()
 entry3:
@@ -118,7 +118,7 @@ define i32 @test4() local_unnamed_addr #0 !dbg !40 {
 ; CHECK-NEXT:    DBG_VALUE 0, $noreg, ![[FOO4]], !DIExpression()
 ; CHECK-NEXT:    [[REG4:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR4]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR4]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG4]], $noreg, ![[BAR4]], !DIExpression()
 entry4:
   call void @llvm.dbg.value(metadata ptr @S, metadata !42, metadata !DIExpression()), !dbg !44
@@ -134,7 +134,7 @@ define i32 @test5() local_unnamed_addr #0 !dbg !47 {
 ; CHECK-NEXT:    DBG_VALUE 0, $noreg, ![[FOO5]], !DIExpression()
 ; CHECK-NEXT:    [[REG5:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR5]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR5]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG5]], $noreg, ![[BAR5]], !DIExpression()
 ; CHECK-NOT:     DBG_{{.*}} ![[FOO5]], !DIExpression()
 ; CHECK:         RET

diff  --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll
index 9a2dc13b129e6..0bba204a408b5 100644
--- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll
+++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-3.ll
@@ -75,12 +75,12 @@ for.body:                                         ; preds = %for.body.lr.ph, %fo
 ; INSTRREF-SAME:    debug-instr-number 9
 ; CHECK-NEXT:    [[REG7:%[0-9]+]]:gr32 = PHI
 ; INSTRREF-SAME:    debug-instr-number 10
-; INSTRREF-NEXT: DBG_INSTR_REF !19, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(5, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !19, !DIExpression(DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(6, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !18, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(7, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !18, !DIExpression(DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(8, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !17, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(9, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !17, !DIExpression(DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(10, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !19, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(5, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !19, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(6, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !18, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(7, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !18, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(8, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !17, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(9, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !17, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(10, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, !19, !DIExpression(DW_OP_LLVM_fragment, 0, 32)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, !19, !DIExpression(DW_OP_LLVM_fragment, 32, 32)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG4]], $noreg, !18, !DIExpression(DW_OP_LLVM_fragment, 0, 32)

diff  --git a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
index 214a689e0bd49..bcf646b56e68e 100644
--- a/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
+++ b/llvm/test/DebugInfo/X86/sdag-dbgvalue-phi-use-4.ll
@@ -19,11 +19,11 @@
 ; INSTRREF-SAME:    debug-instr-number 2
 ; CHECK-NEXT:    [[REG3:%[0-9]+]]:gr32 = PHI
 ; INSTRREF-SAME:    debug-instr-number 3
-; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(2, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_fragment, 64, 16), dbg-instr-ref(3, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_fragment, 10, 32), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_fragment, 42, 13), dbg-instr-ref(2, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), dbg-instr-ref(2, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 16), dbg-instr-ref(3, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 10, 32), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 42, 13), dbg-instr-ref(2, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG1]], $noreg,  !13, !DIExpression(DW_OP_LLVM_fragment, 0, 32)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg,  !13, !DIExpression(DW_OP_LLVM_fragment, 32, 32)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg,  !13, !DIExpression(DW_OP_LLVM_fragment, 64, 16)

diff  --git a/llvm/test/DebugInfo/X86/sdag-salvage-add.ll b/llvm/test/DebugInfo/X86/sdag-salvage-add.ll
index 8be1a6de15c20..ecd2c0dad3f1b 100644
--- a/llvm/test/DebugInfo/X86/sdag-salvage-add.ll
+++ b/llvm/test/DebugInfo/X86/sdag-salvage-add.ll
@@ -36,12 +36,14 @@
 ; INSTRREF-SAME: debug-instr-number 2,
 ; INSTRREF-NEXT: DBG_INSTR_REF ![[S4]],
 ; DBGVALUE-NEXT: DBG_VALUE $rax, $noreg, ![[MYVAR]],
-; CHECK-SAME:       !DIExpression(DW_OP_plus_uconst, 4096, DW_OP_stack_value)
+; DBGVALUE-SAME:       !DIExpression(DW_OP_plus_uconst, 4096, DW_OP_stack_value)
+; INSTRREF-SAME:       !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 4096, DW_OP_stack_value)
 ; INSTRREF-SAME: dbg-instr-ref(2, 0)
 
 ; INSTRREF:      DBG_INSTR_REF ![[MYVAR]],
 ; DBGVALUE:      DBG_VALUE $rax, $noreg, ![[S4]],
-; CHECK-SAME:           !DIExpression(DW_OP_plus_uconst, 4096, DW_OP_stack_value)
+; DBGVALUE-SAME:           !DIExpression(DW_OP_plus_uconst, 4096, DW_OP_stack_value)
+; INSTRREF-SAME:           !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 4096, DW_OP_stack_value)
 ; INSTRREF-SAME: dbg-instr-ref(2, 0)
 ; CHECK-NEXT: $rdi = MOV64rm killed renamable $rax, 1, $noreg, 4096, $noreg,
 

diff  --git a/llvm/test/DebugInfo/X86/sdagsplit-1.ll b/llvm/test/DebugInfo/X86/sdagsplit-1.ll
index be27370dd33ae..29c5f6967156e 100644
--- a/llvm/test/DebugInfo/X86/sdagsplit-1.ll
+++ b/llvm/test/DebugInfo/X86/sdagsplit-1.ll
@@ -13,8 +13,8 @@
 ;      return 0;
 ;    }
 ;
-; CHECK-DAG: DBG_VALUE ${{[a-z]+}}, $noreg, !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_fragment, 0, 32), debug-location
-; CHECK-DAG: DBG_VALUE ${{[a-z]+}}, $noreg, !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_fragment, 32, 32), debug-location
+; CHECK-DAG: DBG_VALUE_LIST !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 0, 32), ${{[a-z]+}}, debug-location
+; CHECK-DAG: DBG_VALUE_LIST !{{[0-9]+}}, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 32, 32), ${{[a-z]+}}, debug-location
 
 ; ModuleID = 'sdagsplit-1.c'
 target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"

diff  --git a/llvm/test/DebugInfo/X86/spill-nospill.ll b/llvm/test/DebugInfo/X86/spill-nospill.ll
index 7dec14e892f51..e6d34df836f82 100644
--- a/llvm/test/DebugInfo/X86/spill-nospill.ll
+++ b/llvm/test/DebugInfo/X86/spill-nospill.ll
@@ -24,7 +24,7 @@
 ; CHECK-LABEL: f: # @f
 ; CHECK: callq   g
 ; CHECK: movl    %eax, [[X_OFFS:[0-9]+]](%rsp)          # 4-byte Spill
-; CHECK: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[X_OFFS]]] [$rsp+0]
+; CHECK: #DEBUG_VALUE: f:x <- [DW_OP_plus_uconst [[X_OFFS]], DW_OP_deref] $rsp
 ; CHECK: #APP
 ; CHECK: #NO_APP
 ; CHECK: callq   g

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/loop-sink.ll b/llvm/test/DebugInfo/assignment-tracking/X86/loop-sink.ll
index b3025bed11c2b..feea162d0157b 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/loop-sink.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/loop-sink.ll
@@ -27,7 +27,7 @@
 ; CHECK: CALL64pcrel32 @getInt{{.*}}debug-instr-number 1
 
 ; CHECK-LABEL: bb.2.while.body:
-; CHECK: DBG_INSTR_REF ![[A]], !DIExpression(), dbg-instr-ref(1, 6)
+; CHECK: DBG_INSTR_REF ![[A]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 6)
 
 ; CHECK-LABEL: bb.3.while.end:
 ; CHECK: MOV32mr %stack.0.a.addr, 1, $noreg, 0, $noreg, %1

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll b/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
index 164f060162a4f..a9ba66d8444f4 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/lower-to-value.ll
@@ -49,7 +49,7 @@
 ; DBGVALUE: %2:gr64 = nsw ADD64ri8 %1, 2, implicit-def dead $eflags, debug-location
 ; DBGVALUE-NEXT: DBG_VALUE %2, $noreg, ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 64, 64), debug-location
 ; INSTRREF: %2:gr64 = nsw ADD64ri8 %1, 2, implicit-def dead $eflags, debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location
+; INSTRREF-NEXT: DBG_INSTR_REF ![[VAR]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_fragment, 64, 64), dbg-instr-ref(1, 0), debug-location
 
 source_filename = "test.cpp"
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/remove-undef-fragment.ll b/llvm/test/DebugInfo/assignment-tracking/X86/remove-undef-fragment.ll
index 749a2b4f61d5f..5a2c769952517 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/remove-undef-fragment.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/remove-undef-fragment.ll
@@ -23,8 +23,8 @@
 ;; (which happens to be the case here). It's just important that SelectionDAG
 ;; was fed these fragments.
 
-; CHECK: DBG{{.*}}DIExpression(DW_OP_LLVM_fragment, 0, 32)
-; CHECK: DBG{{.*}}DIExpression(DW_OP_LLVM_fragment, 64, 32)
+; CHECK: DBG{{.*}}DIExpression({{(DW_OP_LLVM_arg, 0, )?}}DW_OP_LLVM_fragment, 0, 32)
+; CHECK: DBG{{.*}}DIExpression({{(DW_OP_LLVM_arg, 0, )?}}DW_OP_LLVM_fragment, 64, 32)
 
 ;; Source
 ;; ------

diff  --git a/llvm/test/DebugInfo/assignment-tracking/X86/sdag-dangling-dbgassign.ll b/llvm/test/DebugInfo/assignment-tracking/X86/sdag-dangling-dbgassign.ll
index 64ede9c80a005..779242c3a460d 100644
--- a/llvm/test/DebugInfo/assignment-tracking/X86/sdag-dangling-dbgassign.ll
+++ b/llvm/test/DebugInfo/assignment-tracking/X86/sdag-dangling-dbgassign.ll
@@ -79,7 +79,7 @@ define i32 @test1() local_unnamed_addr #0 !dbg !17 {
 ; CHECK-NEXT:    DBG_VALUE 0, $noreg, ![[BAR1]], !DIExpression()
 ; CHECK-NEXT:    [[REG1:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT:  DBG_INSTR_REF ![[FOO1]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT:  DBG_INSTR_REF ![[FOO1]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT:  DBG_VALUE [[REG1]], $noreg, ![[FOO1]], !DIExpression()
 entry1:
   call void @llvm.dbg.assign(metadata ptr @S, metadata !20, metadata !DIExpression(), metadata !54, metadata ptr undef, metadata !DIExpression()), !dbg !23
@@ -92,8 +92,8 @@ define i32 @test2() local_unnamed_addr #0 !dbg !26 {
 ; CHECK-LABEL: bb.0.entry2
 ; CHECK-NEXT:    [[REG2:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO2]], !DIExpression(), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR2]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO2]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR2]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, ![[FOO2]], !DIExpression
 ; DBGVALUE-NEXT: DBG_VALUE [[REG2]], $noreg, ![[BAR2]], !DIExpression
 entry2:
@@ -107,8 +107,8 @@ define i32 @test3() local_unnamed_addr #0 !dbg !33 {
 ; CHECK-LABEL: bb.0.entry3
 ; CHECK-NEXT:    [[REG3:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR3]], !DIExpression(), dbg-instr-ref(1, 0)
-; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO3]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR3]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[FOO3]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, ![[BAR3]], !DIExpression()
 ; DBGVALUE-NEXT: DBG_VALUE [[REG3]], $noreg, ![[FOO3]], !DIExpression()
 entry3:
@@ -125,7 +125,7 @@ define i32 @test4() local_unnamed_addr #0 !dbg !40 {
 ; CHECK-NEXT:    DBG_VALUE 0, $noreg, ![[FOO4]], !DIExpression()
 ; CHECK-NEXT:    [[REG4:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR4]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR4]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG4]], $noreg, ![[BAR4]], !DIExpression()
 entry4:
   call void @llvm.dbg.assign(metadata ptr @S, metadata !42, metadata !DIExpression(), metadata !54, metadata ptr undef, metadata !DIExpression()), !dbg !44
@@ -141,7 +141,7 @@ define i32 @test5() local_unnamed_addr #0 !dbg !47 {
 ; CHECK-NEXT:    DBG_VALUE 0, $noreg, ![[FOO5]], !DIExpression()
 ; CHECK-NEXT:    [[REG5:%[0-9]+]]:gr64 = LEA64r
 ; INSTRREF-SAME:    debug-instr-number 1
-; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR5]], !DIExpression(), dbg-instr-ref(1, 0)
+; INSTRREF-NEXT: DBG_INSTR_REF ![[BAR5]], !DIExpression(DW_OP_LLVM_arg, 0), dbg-instr-ref(1, 0)
 ; DBGVALUE-NEXT: DBG_VALUE [[REG5]], $noreg, ![[BAR5]], !DIExpression()
 ; CHECK-NOT:     DBG_{{.*}} ![[FOO5]], !DIExpression()
 ; CHECK:         RET

diff  --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index f8a796ac2289f..c5b0060e79601 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -2980,7 +2980,7 @@ TEST_F(DIExpressionTest, isValid) {
   } while (false)
 
   // Empty expression should be valid.
-  EXPECT_TRUE(DIExpression::get(Context, std::nullopt));
+  EXPECT_TRUE(DIExpression::get(Context, std::nullopt)->isValid());
 
   // Valid constructions.
   EXPECT_VALID(dwarf::DW_OP_plus_uconst, 6);
@@ -2992,6 +2992,8 @@ TEST_F(DIExpressionTest, isValid) {
   EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_LLVM_fragment, 3, 7);
   EXPECT_VALID(dwarf::DW_OP_deref, dwarf::DW_OP_plus_uconst, 6,
                dwarf::DW_OP_LLVM_fragment, 3, 7);
+  EXPECT_VALID(dwarf::DW_OP_LLVM_entry_value, 1);
+  EXPECT_VALID(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_LLVM_entry_value, 1);
 
   // Invalid constructions.
   EXPECT_INVALID(~0u);
@@ -3001,6 +3003,11 @@ TEST_F(DIExpressionTest, isValid) {
   EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3);
   EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_plus_uconst, 3);
   EXPECT_INVALID(dwarf::DW_OP_LLVM_fragment, 3, 7, dwarf::DW_OP_deref);
+  EXPECT_INVALID(dwarf::DW_OP_LLVM_entry_value, 2);
+  EXPECT_INVALID(dwarf::DW_OP_plus_uconst, 5, dwarf::DW_OP_LLVM_entry_value, 1);
+  EXPECT_INVALID(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 5,
+                 dwarf::DW_OP_LLVM_entry_value, 1);
+  EXPECT_INVALID(dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_LLVM_entry_value, 1);
 
 #undef EXPECT_VALID
 #undef EXPECT_INVALID
@@ -3082,6 +3089,59 @@ TEST_F(DIExpressionTest, createFragmentExpression) {
 #undef EXPECT_INVALID_FRAGMENT
 }
 
+TEST_F(DIExpressionTest, convertToVariadicExpression) {
+#define EXPECT_CONVERT_IS_NOOP(TestExpr)                                       \
+  do {                                                                         \
+    const DIExpression *Variadic =                                             \
+        DIExpression::convertToVariadicExpression(TestExpr);                   \
+    EXPECT_EQ(Variadic, TestExpr);                                             \
+  } while (false)
+#define EXPECT_VARIADIC_OPS_EQUAL(TestExpr, Expected)                          \
+  do {                                                                         \
+    const DIExpression *Variadic =                                             \
+        DIExpression::convertToVariadicExpression(TestExpr);                   \
+    EXPECT_EQ(Variadic, Expected);                                             \
+  } while (false)
+#define GET_EXPR(...) DIExpression::get(Context, {__VA_ARGS__})
+
+  // Expressions which are already variadic should be unaffected.
+  EXPECT_CONVERT_IS_NOOP(
+      GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_stack_value));
+  EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
+                                  dwarf::DW_OP_LLVM_arg, 1, dwarf::DW_OP_plus,
+                                  dwarf::DW_OP_stack_value));
+  EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_constu, 5, dwarf::DW_OP_LLVM_arg,
+                                  0, dwarf::DW_OP_plus,
+                                  dwarf::DW_OP_stack_value));
+  EXPECT_CONVERT_IS_NOOP(GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
+                                  dwarf::DW_OP_stack_value,
+                                  dwarf::DW_OP_LLVM_fragment, 0, 32));
+
+  // Other expressions should receive a leading `LLVM_arg 0`.
+  EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(), GET_EXPR(dwarf::DW_OP_LLVM_arg, 0));
+  EXPECT_VARIADIC_OPS_EQUAL(
+      GET_EXPR(dwarf::DW_OP_plus_uconst, 4),
+      GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4));
+  EXPECT_VARIADIC_OPS_EQUAL(
+      GET_EXPR(dwarf::DW_OP_plus_uconst, 4, dwarf::DW_OP_stack_value),
+      GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 4,
+               dwarf::DW_OP_stack_value));
+  EXPECT_VARIADIC_OPS_EQUAL(
+      GET_EXPR(dwarf::DW_OP_plus_uconst, 6, dwarf::DW_OP_stack_value,
+               dwarf::DW_OP_LLVM_fragment, 32, 32),
+      GET_EXPR(dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_plus_uconst, 6,
+               dwarf::DW_OP_stack_value, dwarf::DW_OP_LLVM_fragment, 32, 32));
+  EXPECT_VARIADIC_OPS_EQUAL(GET_EXPR(dwarf::DW_OP_plus_uconst, 14,
+                                     dwarf::DW_OP_LLVM_fragment, 32, 32),
+                            GET_EXPR(dwarf::DW_OP_LLVM_arg, 0,
+                                     dwarf::DW_OP_plus_uconst, 14,
+                                     dwarf::DW_OP_LLVM_fragment, 32, 32));
+
+#undef EXPECT_CONVERT_IS_NOOP
+#undef EXPECT_VARIADIC_OPS_EQUAL
+#undef GET_EXPR
+}
+
 TEST_F(DIExpressionTest, replaceArg) {
 #define EXPECT_REPLACE_ARG_EQ(Expr, OldArg, NewArg, ...)                       \
   do {                                                                         \


        


More information about the llvm-commits mailing list