[llvm] e5d958c - [DebugInfo] Support DIArgList in DbgVariableIntrinsic

Matt Morehouse via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 9 12:00:57 PST 2021


Hi Stephen,

This patch appears to be causing a use of uninitialized memory detected on
the MSan bot <https://lab.llvm.org:8011/#/builders/74>.  Could you please
take a look?

==1571992==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0xbcf31b0 in llvm::InstCombinerImpl::visitTrunc(llvm::TruncInst&)
llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
    #1 0xbb57e54 in llvm::InstVisitor<llvm::InstCombinerImpl,
llvm::Instruction*>::visit(llvm::Instruction&)
llvm-project/llvm/include/llvm/IR/Instruction.def:184:1
    #2 0xbb52196 in llvm::InstCombinerImpl::run()
llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:3730:31
    #3 0xbb6088b in combineInstructionsOverFunction(llvm::Function&,
llvm::InstCombineWorklist&, llvm::AAResults*, llvm::AssumptionCache&,
llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&,
llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*,
llvm::ProfileSummaryInfo*, unsigned int, llvm::LoopInfo*)
llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:4020:13
    #4 0xbb593cb in llvm::InstCombinePass::run(llvm::Function&,
llvm::AnalysisManager<llvm::Function>&)
llvm-project/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp:4051:8
    #5 0xe5c2ba1 in llvm::detail::PassModel<llvm::Function,
llvm::InstCombinePass, llvm::PreservedAnalyses,
llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&,
llvm::AnalysisManager<llvm::Function>&)
llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:85:17
    #6 0xaf42024 in llvm::PassManager<llvm::Function,
llvm::AnalysisManager<llvm::Function> >::run(llvm::Function&,
llvm::AnalysisManager<llvm::Function>&)
llvm-project/llvm/include/llvm/IR/PassManager.h:517:21
    #7 0x3b9cf71 in llvm::detail::PassModel<llvm::Function,
llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function> >,
llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>
>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)
llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:85:17
    #8 0xaf5b7d7 in llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&,
llvm::AnalysisManager<llvm::Module>&)
llvm-project/llvm/lib/IR/PassManager.cpp:117:22
    #9 0x296c961 in llvm::detail::PassModel<llvm::Module,
llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses,
llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&,
llvm::AnalysisManager<llvm::Module>&)
llvm-project/llvm/include/llvm/IR/PassManagerInternal.h:85:17
    #10 0xaf3bd24 in llvm::PassManager<llvm::Module,
llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&,
llvm::AnalysisManager<llvm::Module>&)
llvm-project/llvm/include/llvm/IR/PassManager.h:517:21
    #11 0x293e9c5 in llvm::runPassPipeline(llvm::StringRef, llvm::Module&,
llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*,
llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef,
llvm::ArrayRef<llvm::StringRef>, llvm::opt_tool::OutputKind,
llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool)
llvm-project/llvm/tools/opt/NewPMDriver.cpp:449:7
    #12 0x299f1e5 in main llvm-project/llvm/tools/opt/opt.cpp:819:12
    #13 0x7fed4cd9fd09 in __libc_start_main csu/../csu/libc-start.c:308:16
    #14 0x28ac269 in _start (llvm_build_msan/bin/opt+0x28ac269)

SUMMARY: MemorySanitizer: use-of-uninitialized-value
llvm-project/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp in
llvm::InstCombinerImpl::visitTrunc(llvm::TruncInst&)


On Mon, Mar 8, 2021 at 6:37 AM Stephen Tozer via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

>
> Author: gbtozers
> Date: 2021-03-08T14:36:13Z
> New Revision: e5d958c45629ccd2f5b5f7432756be1d0fcf052c
>
> URL:
> https://github.com/llvm/llvm-project/commit/e5d958c45629ccd2f5b5f7432756be1d0fcf052c
> DIFF:
> https://github.com/llvm/llvm-project/commit/e5d958c45629ccd2f5b5f7432756be1d0fcf052c.diff
>
> LOG: [DebugInfo] Support DIArgList in DbgVariableIntrinsic
>
> This patch updates DbgVariableIntrinsics to support use of a DIArgList for
> the
> location operand, resulting in a significant change to its interface. This
> patch
> does not update all IR passes to support multiple location operands in a
> dbg.value; the only change is to update the DbgVariableIntrinsic interface
> and
> its uses. All code outside of the intrinsic classes assumes that an
> intrinsic
> will always have exactly one location operand; they will still support
> DIArgLists, but only if they contain exactly one Value.
>
> Among other changes, the setOperand and setArgOperand functions in
> DbgVariableIntrinsic have been made private. This is to prevent code from
> setting the operands of these intrinsics directly, which could easily
> result in
> incorrect/invalid operands being set. This does not prevent these
> functions from
> being called on a debug intrinsic at all, as they can still be called on
> any
> CallInst pointer; it is assumed that any code directly setting the
> operands on a
> generic call instruction is doing so safely. The intention for making these
> functions private is to prevent DIArgLists from being overwritten by code
> that's
> naively trying to replace one of the Values it points to, and also to fail
> fast
> if a DbgVariableIntrinsic is updated to use a DIArgList without a valid
> corresponding DIExpression.
>
> Added:
>
>
> Modified:
>     llvm/include/llvm/IR/IntrinsicInst.h
>     llvm/lib/Bitcode/Reader/MetadataLoader.cpp
>     llvm/lib/CodeGen/CodeGenPrepare.cpp
>     llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>     llvm/lib/IR/Constants.cpp
>     llvm/lib/IR/IntrinsicInst.cpp
>     llvm/lib/IR/Verifier.cpp
>     llvm/lib/Target/AArch64/AArch64StackTagging.cpp
>     llvm/lib/Transforms/Coroutines/CoroFrame.cpp
>     llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
>     llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
>     llvm/lib/Transforms/Scalar/ADCE.cpp
>     llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
>     llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
>     llvm/lib/Transforms/Utils/CodeExtractor.cpp
>     llvm/lib/Transforms/Utils/LCSSA.cpp
>     llvm/lib/Transforms/Utils/Local.cpp
>     llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
>     llvm/unittests/Transforms/Utils/LocalTest.cpp
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/llvm/include/llvm/IR/IntrinsicInst.h
> b/llvm/include/llvm/IR/IntrinsicInst.h
> index a7dec8837bf8..a138e4bea8c0 100644
> --- a/llvm/include/llvm/IR/IntrinsicInst.h
> +++ b/llvm/include/llvm/IR/IntrinsicInst.h
> @@ -24,6 +24,7 @@
>  #define LLVM_IR_INTRINSICINST_H
>
>  #include "llvm/IR/Constants.h"
> +#include "llvm/IR/DebugInfoMetadata.h"
>  #include "llvm/IR/DerivedTypes.h"
>  #include "llvm/IR/FPEnv.h"
>  #include "llvm/IR/Function.h"
> @@ -146,10 +147,78 @@ class DbgInfoIntrinsic : public IntrinsicInst {
>  /// This is the common base class for debug info intrinsics for variables.
>  class DbgVariableIntrinsic : public DbgInfoIntrinsic {
>  public:
> -  /// Get the location corresponding to the variable referenced by the
> debug
> +  // Iterator for ValueAsMetadata that internally uses direct pointer
> iteration
> +  // over either a ValueAsMetadata* or a ValueAsMetadata**, dereferencing
> to the
> +  // ValueAsMetadata .
> +  class location_op_iterator
> +      : public iterator_facade_base<location_op_iterator,
> +                                    std::bidirectional_iterator_tag,
> Value *> {
> +    PointerUnion<ValueAsMetadata *, ValueAsMetadata **> I;
> +
> +  public:
> +    location_op_iterator(ValueAsMetadata *SingleIter) : I(SingleIter) {}
> +    location_op_iterator(ValueAsMetadata **MultiIter) : I(MultiIter) {}
> +
> +    location_op_iterator(const location_op_iterator &R) : I(R.I) {}
> +    location_op_iterator &operator=(const location_op_iterator &R) {
> +      I = R.I;
> +      return *this;
> +    }
> +    bool operator==(const location_op_iterator &RHS) const {
> +      return I == RHS.I;
> +    }
> +    const Value *operator*() const {
> +      ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
> +                                 ? I.get<ValueAsMetadata *>()
> +                                 : *I.get<ValueAsMetadata **>();
> +      return VAM->getValue();
> +    };
> +    Value *operator*() {
> +      ValueAsMetadata *VAM = I.is<ValueAsMetadata *>()
> +                                 ? I.get<ValueAsMetadata *>()
> +                                 : *I.get<ValueAsMetadata **>();
> +      return VAM->getValue();
> +    }
> +    location_op_iterator &operator++() {
> +      if (I.is<ValueAsMetadata *>())
> +        I = I.get<ValueAsMetadata *>() + 1;
> +      else
> +        I = I.get<ValueAsMetadata **>() + 1;
> +      return *this;
> +    }
> +    location_op_iterator &operator--() {
> +      if (I.is<ValueAsMetadata *>())
> +        I = I.get<ValueAsMetadata *>() - 1;
> +      else
> +        I = I.get<ValueAsMetadata **>() - 1;
> +      return *this;
> +    }
> +  };
> +
> +  /// Get the locations corresponding to the variable referenced by the
> debug
>    /// info intrinsic.  Depending on the intrinsic, this could be the
>    /// variable's value or its address.
> -  Value *getVariableLocation(bool AllowNullOp = true) const;
> +  iterator_range<location_op_iterator> location_ops() const;
> +
> +  Value *getVariableLocationOp(unsigned OpIdx) const;
> +
> +  void replaceVariableLocationOp(Value *OldValue, Value *NewValue);
> +
> +  void setVariable(DILocalVariable *NewVar) {
> +    setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar));
> +  }
> +
> +  void setExpression(DIExpression *NewExpr) {
> +    setArgOperand(2, MetadataAsValue::get(NewExpr->getContext(),
> NewExpr));
> +  }
> +
> +  unsigned getNumVariableLocationOps() const {
> +    if (hasArgList())
> +      return cast<DIArgList>(getRawLocation())->getArgs().size();
> +    return 1;
> +  }
> +
> +  bool hasArgList() const { return isa<DIArgList>(getRawLocation()); }
>
>    /// Does this describe the address of a local variable. True for
> dbg.addr
>    /// and dbg.declare, but not dbg.value, which describes its value.
> @@ -157,6 +226,24 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
>      return getIntrinsicID() != Intrinsic::dbg_value;
>    }
>
> +  void setUndef() {
> +    // TODO: When/if we remove duplicate values from DIArgLists, we don't
> need
> +    // this set anymore.
> +    SmallPtrSet<Value *, 4> RemovedValues;
> +    for (Value *OldValue : location_ops()) {
> +      if (!RemovedValues.insert(OldValue).second)
> +        continue;
> +      Value *Undef = UndefValue::get(OldValue->getType());
> +      replaceVariableLocationOp(OldValue, Undef);
> +    }
> +  }
> +
> +  bool isUndef() const {
> +    return (getNumVariableLocationOps() == 0 &&
> +            !getExpression()->isComplex()) ||
> +           any_of(location_ops(), [](Value *V) { return
> isa<UndefValue>(V); });
> +  }
> +
>    DILocalVariable *getVariable() const {
>      return cast<DILocalVariable>(getRawVariable());
>    }
> @@ -165,6 +252,10 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic {
>      return cast<DIExpression>(getRawExpression());
>    }
>
> +  Metadata *getRawLocation() const {
> +    return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
> +  }
> +
>    Metadata *getRawVariable() const {
>      return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
>    }
> @@ -193,12 +284,21 @@ class DbgVariableIntrinsic : public DbgInfoIntrinsic
> {
>      return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
>    }
>    /// @}
> +private:
> +  void setArgOperand(unsigned i, Value *v) {
> +    DbgInfoIntrinsic::setArgOperand(i, v);
> +  }
> +  void setOperand(unsigned i, Value *v) { DbgInfoIntrinsic::setOperand(i,
> v); }
>  };
>
>  /// This represents the llvm.dbg.declare instruction.
>  class DbgDeclareInst : public DbgVariableIntrinsic {
>  public:
> -  Value *getAddress() const { return getVariableLocation(); }
> +  Value *getAddress() const {
> +    assert(getNumVariableLocationOps() == 1 &&
> +           "dbg.declare must have exactly 1 location operand.");
> +    return getVariableLocationOp(0);
> +  }
>
>    /// \name Casting methods
>    /// @{
> @@ -214,7 +314,11 @@ class DbgDeclareInst : public DbgVariableIntrinsic {
>  /// This represents the llvm.dbg.addr instruction.
>  class DbgAddrIntrinsic : public DbgVariableIntrinsic {
>  public:
> -  Value *getAddress() const { return getVariableLocation(); }
> +  Value *getAddress() const {
> +    assert(getNumVariableLocationOps() == 1 &&
> +           "dbg.addr must have exactly 1 location operand.");
> +    return getVariableLocationOp(0);
> +  }
>
>    /// \name Casting methods
>    /// @{
> @@ -229,8 +333,13 @@ class DbgAddrIntrinsic : public DbgVariableIntrinsic {
>  /// This represents the llvm.dbg.value instruction.
>  class DbgValueInst : public DbgVariableIntrinsic {
>  public:
> -  Value *getValue() const {
> -    return getVariableLocation(/* AllowNullOp = */ false);
> +  // The default argument should only be used in ISel, and the default
> option
> +  // should be removed once ISel support for multiple location ops is
> complete.
> +  Value *getValue(unsigned OpIdx = 0) const {
> +    return getVariableLocationOp(OpIdx);
> +  }
> +  iterator_range<location_op_iterator> getValues() const {
> +    return location_ops();
>    }
>
>    /// \name Casting methods
>
> diff  --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
> b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
> index 0567f96c9c25..0cf547c57d9d 100644
> --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
> +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
> @@ -550,8 +550,7 @@ class MetadataLoader::MetadataLoaderImpl {
>                SmallVector<uint64_t, 8> Ops;
>                Ops.append(std::next(DIExpr->elements_begin()),
>                           DIExpr->elements_end());
> -              auto *E = DIExpression::get(Context, Ops);
> -              DDI->setOperand(2, MetadataAsValue::get(Context, E));
> +              DDI->setExpression(DIExpression::get(Context, Ops));
>              }
>    }
>
>
> diff  --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp
> b/llvm/lib/CodeGen/CodeGenPrepare.cpp
> index f4bf55d773a3..6e806b0c73a7 100644
> --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
> +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
> @@ -2883,11 +2883,8 @@ class TypePromotionTransaction {
>        // including the debug uses. Since we are undoing the replacements,
>        // the original debug uses must also be reinstated to maintain the
>        // correctness and utility of debug value instructions.
> -      for (auto *DVI: DbgValues) {
> -        LLVMContext &Ctx = Inst->getType()->getContext();
> -        auto *MV = MetadataAsValue::get(Ctx, ValueAsMetadata::get(Inst));
> -        DVI->setOperand(0, MV);
> -      }
> +      for (auto *DVI : DbgValues)
> +        DVI->replaceVariableLocationOp(DVI->getVariableLocationOp(0),
> Inst);
>      }
>    };
>
> @@ -7878,7 +7875,7 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
>    DbgValueInst &DVI = *cast<DbgValueInst>(I);
>
>    // Does this dbg.value refer to a sunk address calculation?
> -  Value *Location = DVI.getVariableLocation();
> +  Value *Location = DVI.getVariableLocationOp(0);
>    WeakTrackingVH SunkAddrVH = SunkAddrs[Location];
>    Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH :
> nullptr;
>    if (SunkAddr) {
> @@ -7886,8 +7883,7 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
>      // opportunity to be accurately lowered. This update may change the
> type of
>      // pointer being referred to; however this makes no
> diff erence to debugging
>      // information, and we can't generate bitcasts that may affect
> codegen.
> -    DVI.setOperand(0, MetadataAsValue::get(DVI.getContext(),
> -
>  ValueAsMetadata::get(SunkAddr)));
> +    DVI.replaceVariableLocationOp(Location, SunkAddr);
>      return true;
>    }
>    return false;
>
> diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> index 39730d03502b..f869b2c41f9f 100644
> --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
> @@ -1191,8 +1191,7 @@ void
> SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
>                            << "in EmitFuncArgumentDbgValue\n");
>      } else {
>        LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");
> -      auto Undef =
> -          UndefValue::get(DDI.getDI()->getVariableLocation()->getType());
> +      auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType());
>        auto SDV =
>            DAG.getConstantDbgValue(Variable, Expr, Undef, dl,
> DbgSDNodeOrder);
>        DAG.AddDbgValue(SDV, nullptr, false);
> @@ -1246,7 +1245,7 @@ void
> SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
>    // This was the final opportunity to salvage this debug information,
> and it
>    // couldn't be done. Place an undef DBG_VALUE at this location to
> terminate
>    // any earlier variable location.
> -  auto Undef =
> UndefValue::get(DDI.getDI()->getVariableLocation()->getType());
> +  auto Undef = UndefValue::get(DDI.getDI()->getValue()->getType());
>    auto SDV = DAG.getConstantDbgValue(Var, Expr, Undef, DL, SDNodeOrder);
>    DAG.AddDbgValue(SDV, nullptr, false);
>
> @@ -5885,7 +5884,7 @@ void SelectionDAGBuilder::visitIntrinsicCall(const
> CallInst &I,
>      LLVM_DEBUG(dbgs() << "SelectionDAG visiting debug intrinsic: " << DI
>                        << "\n");
>      // Check if address has undef value.
> -    const Value *Address = DI.getVariableLocation();
> +    const Value *Address = DI.getVariableLocationOp(0);
>      if (!Address || isa<UndefValue>(Address) ||
>          (Address->use_empty() && !isa<Argument>(Address))) {
>        LLVM_DEBUG(dbgs() << "Dropping debug info for " << DI
>
> diff  --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
> index ef0e5f6dd087..62760ff7aec2 100644
> --- a/llvm/lib/IR/Constants.cpp
> +++ b/llvm/lib/IR/Constants.cpp
> @@ -721,6 +721,12 @@ static bool removeDeadUsersOfConstant(const Constant
> *C) {
>        return false; // Constant wasn't dead
>    }
>
> +  // If C is only used by metadata, it should not be preserved but should
> have
> +  // its uses replaced.
> +  if (C->isUsedByMetadata()) {
> +    const_cast<Constant *>(C)->replaceAllUsesWith(
> +        UndefValue::get(C->getType()));
> +  }
>    const_cast<Constant*>(C)->destroyConstant();
>    return true;
>  }
>
> diff  --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
> index 3d1ea2853591..3d3f734ba5e0 100644
> --- a/llvm/lib/IR/IntrinsicInst.cpp
> +++ b/llvm/lib/IR/IntrinsicInst.cpp
> @@ -38,18 +38,65 @@ using namespace llvm;
>  /// intrinsics for variables.
>  ///
>
> -Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const {
> -  Value *Op = getArgOperand(0);
> -  if (AllowNullOp && !Op)
> +iterator_range<DbgVariableIntrinsic::location_op_iterator>
> +DbgVariableIntrinsic::location_ops() const {
> +  auto *MD = getRawLocation();
> +  assert(MD && "First operand of DbgVariableIntrinsic should be
> non-null.");
> +
> +  // If operand is ValueAsMetadata, return a range over just that operand.
> +  if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) {
> +    return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};
> +  }
> +  // If operand is DIArgList, return a range over its args.
> +  if (auto *AL = dyn_cast<DIArgList>(MD))
> +    return {location_op_iterator(AL->args_begin()),
> +            location_op_iterator(AL->args_end())};
> +  // Operand must be an empty metadata tuple, so return empty iterator.
> +  return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),
> +          location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};
> +}
> +
> +Value *DbgVariableIntrinsic::getVariableLocationOp(unsigned OpIdx) const {
> +  auto *MD = getRawLocation();
> +  assert(MD && "First operand of DbgVariableIntrinsic should be
> non-null.");
> +  if (auto *AL = dyn_cast<DIArgList>(MD))
> +    return AL->getArgs()[OpIdx]->getValue();
> +  if (isa<MDNode>(MD))
>      return nullptr;
> +  assert(
> +      isa<ValueAsMetadata>(MD) &&
> +      "Attempted to get location operand from DbgVariableIntrinsic with
> none.");
> +  auto *V = cast<ValueAsMetadata>(MD);
> +  assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic
> with a "
> +                       "single location operand.");
> +  return V->getValue();
> +}
>
> -  auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
> -  if (auto *V = dyn_cast<ValueAsMetadata>(MD))
> -    return V->getValue();
> +static ValueAsMetadata *getAsMetadata(Value *V) {
> +  return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(
> +
>  cast<MetadataAsValue>(V)->getMetadata())
> +                                 : ValueAsMetadata::get(V);
> +}
>
> -  // When the value goes to null, it gets replaced by an empty MDNode.
> -  assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty
> MDNode");
> -  return nullptr;
> +void DbgVariableIntrinsic::replaceVariableLocationOp(Value *OldValue,
> +                                                     Value *NewValue) {
> +  assert(NewValue && "Values must be non-null");
> +  auto Locations = location_ops();
> +  auto OldIt = find(Locations, OldValue);
> +  assert(OldIt != Locations.end() && "OldValue must be a current
> location");
> +  if (!hasArgList()) {
> +    Value *NewOperand = isa<MetadataAsValue>(NewValue)
> +                            ? NewValue
> +                            : MetadataAsValue::get(
> +                                  getContext(),
> ValueAsMetadata::get(NewValue));
> +    return setArgOperand(0, NewOperand);
> +  }
> +  SmallVector<ValueAsMetadata *, 4> MDs;
> +  ValueAsMetadata *NewOperand = getAsMetadata(NewValue);
> +  for (auto *VMD : Locations)
> +    MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));
> +  setArgOperand(
> +      0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(),
> MDs)));
>  }
>
>  Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
>
> diff  --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
> index be8663553b52..b7a002b0573b 100644
> --- a/llvm/lib/IR/Verifier.cpp
> +++ b/llvm/lib/IR/Verifier.cpp
> @@ -5371,7 +5371,7 @@ void
> Verifier::visitConstrainedFPIntrinsic(ConstrainedFPIntrinsic &FPI) {
>  }
>
>  void Verifier::visitDbgIntrinsic(StringRef Kind, DbgVariableIntrinsic
> &DII) {
> -  auto *MD = cast<MetadataAsValue>(DII.getArgOperand(0))->getMetadata();
> +  auto *MD = DII.getRawLocation();
>    AssertDI(isa<ValueAsMetadata>(MD) || isa<DIArgList>(MD) ||
>                 (isa<MDNode>(MD) && !cast<MDNode>(MD)->getNumOperands()),
>             "invalid llvm.dbg." + Kind + " intrinsic address/value", &DII,
> MD);
>
> diff  --git a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
> b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
> index ab49e0c3f937..793db06f79ad 100644
> --- a/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
> +++ b/llvm/lib/Target/AArch64/AArch64StackTagging.cpp
> @@ -284,6 +284,7 @@ class InitializerBuilder {
>  class AArch64StackTagging : public FunctionPass {
>    struct AllocaInfo {
>      AllocaInst *AI;
> +    TrackingVH<Instruction> OldAI; // Track through RAUW to replace debug
> uses.
>      SmallVector<IntrinsicInst *, 2> LifetimeStart;
>      SmallVector<IntrinsicInst *, 2> LifetimeEnd;
>      SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics;
> @@ -557,12 +558,13 @@ bool AArch64StackTagging::runOnFunction(Function
> &Fn) {
>        Instruction *I = &*IT;
>        if (auto *AI = dyn_cast<AllocaInst>(I)) {
>          Allocas[AI].AI = AI;
> +        Allocas[AI].OldAI = AI;
>          continue;
>        }
>
>        if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(I)) {
>          if (auto *AI =
> -                dyn_cast_or_null<AllocaInst>(DVI->getVariableLocation()))
> {
> +
> dyn_cast_or_null<AllocaInst>(DVI->getVariableLocationOp(0))) {
>            Allocas[AI].DbgVariableIntrinsics.push_back(DVI);
>          }
>          continue;
> @@ -705,9 +707,7 @@ bool AArch64StackTagging::runOnFunction(Function &Fn) {
>
>      // Fixup debug intrinsics to point to the new alloca.
>      for (auto DVI : Info.DbgVariableIntrinsics)
> -      DVI->setArgOperand(
> -          0,
> -          MetadataAsValue::get(F->getContext(),
> LocalAsMetadata::get(Info.AI)));
> +      DVI->replaceVariableLocationOp(Info.OldAI, Info.AI);
>    }
>
>    // If we have instrumented at least one alloca, all unrecognized
> lifetime
>
> diff  --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
> b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
> index 16b59f279ff9..accd3a6ce16a 100644
> --- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
> +++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
> @@ -2156,6 +2156,7 @@ void coro::salvageDebugInfo(
>    // function argument and convert into a DIExpression.
>    bool OutermostLoad = true;
>    Value *Storage = DDI->getAddress();
> +  Value *OriginalStorage = Storage;
>    while (Storage) {
>      if (auto *LdInst = dyn_cast<LoadInst>(Storage)) {
>        Storage = LdInst->getOperand(0);
> @@ -2206,10 +2207,8 @@ void coro::salvageDebugInfo(
>      if (Expr && Expr->isComplex())
>        Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
>    }
> -  auto &VMContext = DDI->getFunction()->getContext();
> -  DDI->setOperand(
> -      0, MetadataAsValue::get(VMContext, ValueAsMetadata::get(Storage)));
> -  DDI->setOperand(2, MetadataAsValue::get(VMContext, Expr));
> +  DDI->replaceVariableLocationOp(OriginalStorage, Storage);
> +  DDI->setExpression(Expr);
>    if (auto *InsertPt = dyn_cast_or_null<Instruction>(Storage))
>      DDI->moveAfter(InsertPt);
>  }
>
> diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
> b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
> index 54811628de95..62f761995257 100644
> --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
> +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
> @@ -3582,10 +3582,6 @@ static bool TryToSinkInstruction(Instruction *I,
> BasicBlock *DestBlock) {
>      if (!isa<DbgDeclareInst>(DII))
>        return false;
>
> -    if (isa<CastInst>(I))
> -      DII->setOperand(
> -          0, MetadataAsValue::get(I->getContext(),
> -
> ValueAsMetadata::get(I->getOperand(0))));
>      return true;
>    };
>
>
> diff  --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
> b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
> index fedd9bfc977e..e02076c74420 100644
> --- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
> +++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
> @@ -1153,9 +1153,10 @@ bool HWAddressSanitizer::instrumentStack(
>        // to put it at the beginning of the expression.
>        SmallVector<uint64_t, 8> NewOps = {dwarf::DW_OP_LLVM_tag_offset,
>                                           RetagMask(N)};
> -      DDI->setArgOperand(
> -          2, MetadataAsValue::get(*C, DIExpression::prependOpcodes(
> -                                          DDI->getExpression(), NewOps)));
> +      auto Locations = DDI->location_ops();
> +      unsigned LocNo = std::distance(Locations.begin(), find(Locations,
> AI));
> +      DDI->setExpression(
> +          DIExpression::appendOpsToArg(DDI->getExpression(), NewOps,
> LocNo));
>      }
>
>      size_t Size = getAllocaSizeInBytes(*AI);
> @@ -1219,7 +1220,7 @@ bool HWAddressSanitizer::sanitizeFunction(Function
> &F) {
>
>        if (auto *DDI = dyn_cast<DbgVariableIntrinsic>(&Inst))
>          if (auto *Alloca =
> -                dyn_cast_or_null<AllocaInst>(DDI->getVariableLocation()))
> +
> dyn_cast_or_null<AllocaInst>(DDI->getVariableLocationOp(0)))
>            AllocaDbgMap[Alloca].push_back(DDI);
>
>        if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
> @@ -1300,10 +1301,9 @@ bool HWAddressSanitizer::sanitizeFunction(Function
> &F) {
>        for (auto &Inst : BB)
>          if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&Inst))
>            if (auto *AI =
> -
> dyn_cast_or_null<AllocaInst>(DVI->getVariableLocation()))
> +
> dyn_cast_or_null<AllocaInst>(DVI->getVariableLocationOp(0)))
>              if (auto *NewAI = AllocaToPaddedAllocaMap.lookup(AI))
> -              DVI->setArgOperand(
> -                  0, MetadataAsValue::get(*C,
> LocalAsMetadata::get(NewAI)));
> +              DVI->replaceVariableLocationOp(AI, NewAI);
>      for (auto &P : AllocaToPaddedAllocaMap)
>        P.first->eraseFromParent();
>    }
>
> diff  --git a/llvm/lib/Transforms/Scalar/ADCE.cpp
> b/llvm/lib/Transforms/Scalar/ADCE.cpp
> index ce4e5e575fbf..c8fb9d106e32 100644
> --- a/llvm/lib/Transforms/Scalar/ADCE.cpp
> +++ b/llvm/lib/Transforms/Scalar/ADCE.cpp
> @@ -521,7 +521,7 @@ bool
> AggressiveDeadCodeElimination::removeDeadInstructions() {
>          // If intrinsic is pointing at a live SSA value, there may be an
>          // earlier optimization bug: if we know the location of the
> variable,
>          // why isn't the scope of the location alive?
> -        if (Value *V = DII->getVariableLocation())
> +        if (Value *V = DII->getVariableLocationOp(0))
>            if (Instruction *II = dyn_cast<Instruction>(V))
>              if (isLive(II))
>                dbgs() << "Dropping debug info for " << *DII << "\n";
>
> diff  --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
> b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
> index 3e26ef205d15..facbfce86d8e 100644
> --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
> +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
> @@ -5836,7 +5836,7 @@ static void DbgGatherEqualValues(Loop *L,
> ScalarEvolution &SE,
>        auto DVI = dyn_cast<DbgValueInst>(&I);
>        if (!DVI)
>          continue;
> -      auto V = DVI->getVariableLocation();
> +      auto V = DVI->getVariableLocationOp(0);
>        if (!V || !SE.isSCEVable(V->getType()))
>          continue;
>        auto DbgValueSCEV = SE.getSCEV(V);
> @@ -5862,7 +5862,7 @@ static void DbgApplyEqualValues(EqualValuesMap
> &DbgValueToEqualSet) {
>    for (auto A : DbgValueToEqualSet) {
>      auto DVI = A.first;
>      // Only update those that are now undef.
> -    if (!isa_and_nonnull<UndefValue>(DVI->getVariableLocation()))
> +    if (!isa_and_nonnull<UndefValue>(DVI->getVariableLocationOp(0)))
>        continue;
>      for (auto EV : A.second) {
>        auto V = std::get<WeakVH>(EV);
> @@ -5870,14 +5870,13 @@ static void DbgApplyEqualValues(EqualValuesMap
> &DbgValueToEqualSet) {
>          continue;
>        auto DbgDIExpr = std::get<DIExpression *>(EV);
>        auto Offset = std::get<int64_t>(EV);
> -      auto &Ctx = DVI->getContext();
> -      DVI->setOperand(0, MetadataAsValue::get(Ctx,
> ValueAsMetadata::get(V)));
> +      DVI->replaceVariableLocationOp(DVI->getVariableLocationOp(0), V);
>        if (Offset) {
>          SmallVector<uint64_t, 8> Ops;
>          DIExpression::appendOffset(Ops, Offset);
>          DbgDIExpr = DIExpression::prependOpcodes(DbgDIExpr, Ops, true);
>        }
> -      DVI->setOperand(2, MetadataAsValue::get(Ctx, DbgDIExpr));
> +      DVI->setExpression(DbgDIExpr);
>        break;
>      }
>    }
>
> diff  --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
> b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
> index ff9132206231..0cb9771b6e86 100644
> --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
> +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp
> @@ -267,7 +267,7 @@ bool SpeculativeExecutionPass::considerHoistingFromTo(
>      // Debug variable has special operand to check it's not hoisted.
>      if (const auto *DVI = dyn_cast<DbgVariableIntrinsic>(U)) {
>        if (const auto *I =
> -              dyn_cast_or_null<Instruction>(DVI->getVariableLocation()))
> +
> dyn_cast_or_null<Instruction>(DVI->getVariableLocationOp(0)))
>          if (NotHoisted.count(I) == 0)
>            return true;
>        return false;
>
> diff  --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
> b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
> index b9f886d6217d..2b0ee77f4c9b 100644
> --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
> +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
> @@ -1514,7 +1514,7 @@ static void fixupDebugInfoPostExtraction(Function
> &OldFunc, Function &NewFunc,
>      // If the location isn't a constant or an instruction, delete the
>      // intrinsic.
>      auto *DVI = cast<DbgVariableIntrinsic>(DII);
> -    Value *Location = DVI->getVariableLocation();
> +    Value *Location = DVI->getVariableLocationOp(0);
>      if (!Location ||
>          (!isa<Constant>(Location) && !isa<Instruction>(Location))) {
>        DebugIntrinsicsToDelete.push_back(DVI);
> @@ -1537,7 +1537,7 @@ static void fixupDebugInfoPostExtraction(Function
> &OldFunc, Function &NewFunc,
>            NewSP, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
>            OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
>            OldVar->getAlignInBits());
> -    DVI->setArgOperand(1, MetadataAsValue::get(Ctx, NewVar));
> +    DVI->setVariable(cast<DILocalVariable>(NewVar));
>    }
>    for (auto *DII : DebugIntrinsicsToDelete)
>      DII->eraseFromParent();
>
> diff  --git a/llvm/lib/Transforms/Utils/LCSSA.cpp
> b/llvm/lib/Transforms/Utils/LCSSA.cpp
> index 7437701f5339..c5328784d813 100644
> --- a/llvm/lib/Transforms/Utils/LCSSA.cpp
> +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp
> @@ -236,7 +236,6 @@ bool
> llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
>      llvm::findDbgValues(DbgValues, I);
>
>      // Update pre-existing debug value uses that reside outside the loop.
> -    auto &Ctx = I->getContext();
>      for (auto DVI : DbgValues) {
>        BasicBlock *UserBB = DVI->getParent();
>        if (InstBB == UserBB || L->contains(UserBB))
> @@ -247,7 +246,7 @@ bool
> llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
>        Value *V = AddedPHIs.size() == 1 ? AddedPHIs[0]
>                                         :
> SSAUpdate.FindValueForBlock(UserBB);
>        if (V)
> -        DVI->setOperand(0, MetadataAsValue::get(Ctx,
> ValueAsMetadata::get(V)));
> +        DVI->replaceVariableLocationOp(I, V);
>      }
>
>      // SSAUpdater might have inserted phi-nodes inside other loops. We'll
> need
>
> diff  --git a/llvm/lib/Transforms/Utils/Local.cpp
> b/llvm/lib/Transforms/Utils/Local.cpp
> index c6775d4f3f09..93e5b941c208 100644
> --- a/llvm/lib/Transforms/Utils/Local.cpp
> +++ b/llvm/lib/Transforms/Utils/Local.cpp
> @@ -566,8 +566,7 @@ bool llvm::replaceDbgUsesWithUndef(Instruction *I) {
>    findDbgUsers(DbgUsers, I);
>    for (auto *DII : DbgUsers) {
>      Value *Undef = UndefValue::get(I->getType());
> -    DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
> -                                            ValueAsMetadata::get(Undef)));
> +    DII->replaceVariableLocationOp(I, Undef);
>    }
>    return !DbgUsers.empty();
>  }
> @@ -1389,7 +1388,7 @@ static bool valueCoversEntireFragment(Type *ValTy,
> DbgVariableIntrinsic *DII) {
>    // VLA). Try to use the size of the alloca that the dbg intrinsic
> describes
>    // intead.
>    if (DII->isAddressOfVariable())
> -    if (auto *AI =
> dyn_cast_or_null<AllocaInst>(DII->getVariableLocation()))
> +    if (auto *AI =
> dyn_cast_or_null<AllocaInst>(DII->getVariableLocationOp(0)))
>        if (Optional<TypeSize> FragmentSize =
> AI->getAllocationSizeInBits(DL)) {
>          assert(ValueSize.isScalable() == FragmentSize->isScalable() &&
>                 "Both sizes should agree on the scalable flag.");
> @@ -1597,7 +1596,8 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
>    ValueToValueMapTy DbgValueMap;
>    for (auto &I : *BB) {
>      if (auto DbgII = dyn_cast<DbgVariableIntrinsic>(&I)) {
> -      if (auto *Loc =
> dyn_cast_or_null<PHINode>(DbgII->getVariableLocation()))
> +      if (auto *Loc =
> +              dyn_cast_or_null<PHINode>(DbgII->getVariableLocationOp(0)))
>          DbgValueMap.insert({Loc, DbgII});
>      }
>    }
> @@ -1607,19 +1607,18 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
>    // Then iterate through the new PHIs and look to see if they use one of
> the
>    // previously mapped PHIs. If so, insert a new dbg.value intrinsic that
> will
>    // propagate the info through the new PHI.
> -  LLVMContext &C = BB->getContext();
>    for (auto PHI : InsertedPHIs) {
>      BasicBlock *Parent = PHI->getParent();
>      // Avoid inserting an intrinsic into an EH block.
>      if (Parent->getFirstNonPHI()->isEHPad())
>        continue;
> -    auto PhiMAV = MetadataAsValue::get(C, ValueAsMetadata::get(PHI));
>      for (auto VI : PHI->operand_values()) {
>        auto V = DbgValueMap.find(VI);
>        if (V != DbgValueMap.end()) {
>          auto *DbgII = cast<DbgVariableIntrinsic>(V->second);
> -        Instruction *NewDbgII = DbgII->clone();
> -        NewDbgII->setOperand(0, PhiMAV);
> +        DbgVariableIntrinsic *NewDbgII =
> +            cast<DbgVariableIntrinsic>(DbgII->clone());
> +        NewDbgII->replaceVariableLocationOp(VI, PHI);
>          auto InsertionPt = Parent->getFirstInsertionPt();
>          assert(InsertionPt != Parent->end() && "Ill-formed basic block");
>          NewDbgII->insertBefore(&*InsertionPt);
> @@ -1736,11 +1735,6 @@ void llvm::replaceDbgValueForAlloca(AllocaInst *AI,
> Value *NewAllocaAddress,
>            replaceOneDbgValueForAlloca(DVI, NewAllocaAddress, Builder,
> Offset);
>  }
>
> -/// Wrap \p V in a ValueAsMetadata instance.
> -static MetadataAsValue *wrapValueInMetadata(LLVMContext &C, Value *V) {
> -  return MetadataAsValue::get(C, ValueAsMetadata::get(V));
> -}
> -
>  /// Where possible to salvage debug information for \p I do so
>  /// and return True. If not possible mark undef and return False.
>  void llvm::salvageDebugInfo(Instruction &I) {
> @@ -1751,9 +1745,7 @@ void llvm::salvageDebugInfo(Instruction &I) {
>
>  void llvm::salvageDebugInfoForDbgValues(
>      Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
> -  auto &Ctx = I.getContext();
>    bool Salvaged = false;
> -  auto wrapMD = [&](Value *V) { return wrapValueInMetadata(Ctx, V); };
>
>    for (auto *DII : DbgUsers) {
>      // Do not add DW_OP_stack_value for DbgDeclare and DbgAddr, because
> they
> @@ -1769,8 +1761,8 @@ void llvm::salvageDebugInfoForDbgValues(
>      if (!DIExpr)
>        break;
>
> -    DII->setOperand(0, wrapMD(I.getOperand(0)));
> -    DII->setOperand(2, MetadataAsValue::get(Ctx, DIExpr));
> +    DII->replaceVariableLocationOp(&I, I.getOperand(0));
> +    DII->setExpression(DIExpr);
>      LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
>      Salvaged = true;
>    }
> @@ -1780,8 +1772,7 @@ void llvm::salvageDebugInfoForDbgValues(
>
>    for (auto *DII : DbgUsers) {
>      Value *Undef = UndefValue::get(I.getType());
> -    DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
> -                                            ValueAsMetadata::get(Undef)));
> +    DII->replaceVariableLocationOp(&I, Undef);
>    }
>  }
>
> @@ -1925,13 +1916,12 @@ static bool rewriteDebugUsers(
>      if (UndefOrSalvage.count(DII))
>        continue;
>
> -    LLVMContext &Ctx = DII->getContext();
>      DbgValReplacement DVR = RewriteExpr(*DII);
>      if (!DVR)
>        continue;
>
> -    DII->setOperand(0, wrapValueInMetadata(Ctx, &To));
> -    DII->setOperand(2, MetadataAsValue::get(Ctx, *DVR));
> +    DII->replaceVariableLocationOp(&From, &To);
> +    DII->setExpression(*DVR);
>      LLVM_DEBUG(dbgs() << "REWRITE:  " << *DII << '\n');
>      Changed = true;
>    }
>
> diff  --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
> b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
> index b678efdc8d88..784d0e437ba0 100644
> --- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
> +++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
> @@ -179,9 +179,7 @@ static void RewriteUsesOfClonedInstructions(BasicBlock
> *OrigHeader,
>          NewVal = SSA.GetValueInMiddleOfBlock(UserBB);
>        else
>          NewVal = UndefValue::get(OrigHeaderVal->getType());
> -      DbgValue->setOperand(0,
> -
>  MetadataAsValue::get(OrigHeaderVal->getContext(),
> -
> ValueAsMetadata::get(NewVal)));
> +      DbgValue->replaceVariableLocationOp(OrigHeaderVal, NewVal);
>      }
>    }
>  }
> @@ -390,7 +388,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool
> SimplifiedLatch) {
>      using DbgIntrinsicHash =
>        std::pair<std::pair<Value *, DILocalVariable *>, DIExpression *>;
>      auto makeHash = [](DbgVariableIntrinsic *D) -> DbgIntrinsicHash {
> -      return {{D->getVariableLocation(), D->getVariable()},
> D->getExpression()};
> +      return {{D->getVariableLocationOp(0), D->getVariable()},
> +              D->getExpression()};
>      };
>      SmallDenseSet<DbgIntrinsicHash, 8> DbgIntrinsics;
>      for (auto I = std::next(OrigPreheader->rbegin()), E =
> OrigPreheader->rend();
>
> diff  --git a/llvm/unittests/Transforms/Utils/LocalTest.cpp
> b/llvm/unittests/Transforms/Utils/LocalTest.cpp
> index a57a18ce0be1..f2fce5e7d55d 100644
> --- a/llvm/unittests/Transforms/Utils/LocalTest.cpp
> +++ b/llvm/unittests/Transforms/Utils/LocalTest.cpp
> @@ -524,7 +524,9 @@ struct SalvageDebugInfoTest : ::testing::Test {
>    }
>
>    bool doesDebugValueDescribeX(const DbgValueInst &DI) {
> -    const auto &CI = *cast<ConstantInt>(DI.getValue());
> +    if (DI.getNumVariableLocationOps() != 1)
> +      return false;
> +    const auto &CI = *cast<ConstantInt>(DI.getValue(0));
>      if (CI.isZero())
>        return DI.getExpression()->getElements().equals(
>            {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_stack_value});
> @@ -534,7 +536,9 @@ struct SalvageDebugInfoTest : ::testing::Test {
>    }
>
>    bool doesDebugValueDescribeY(const DbgValueInst &DI) {
> -    const auto &CI = *cast<ConstantInt>(DI.getValue());
> +    if (DI.getNumVariableLocationOps() != 1)
> +      return false;
> +    const auto &CI = *cast<ConstantInt>(DI.getVariableLocationOp(0));
>      if (CI.isZero())
>        return DI.getExpression()->getElements().equals(
>            {dwarf::DW_OP_plus_uconst, 1, dwarf::DW_OP_plus_uconst, 2,
> @@ -758,13 +762,15 @@ TEST(Local, ReplaceAllDbgUsesWith) {
>    EXPECT_TRUE(replaceAllDbgUsesWith(A, F_, F_, DT));
>
>    auto *ADbgVal = cast<DbgValueInst>(A.getNextNode());
> -  EXPECT_EQ(ConstantInt::get(A.getType(), 0),
> ADbgVal->getVariableLocation());
> +  EXPECT_EQ(ADbgVal->getNumVariableLocationOps(), 1);
> +  EXPECT_EQ(ConstantInt::get(A.getType(), 0),
> ADbgVal->getVariableLocationOp(0));
>
>    // Introduce a use-before-def. Check that the dbg.values for %f become
> undef.
>    EXPECT_TRUE(replaceAllDbgUsesWith(F_, G, G, DT));
>
>    auto *FDbgVal = cast<DbgValueInst>(F_.getNextNode());
> -  EXPECT_TRUE(isa<UndefValue>(FDbgVal->getVariableLocation()));
> +  EXPECT_EQ(FDbgVal->getNumVariableLocationOps(), 1);
> +  EXPECT_TRUE(FDbgVal->isUndef());
>
>    SmallVector<DbgValueInst *, 1> FDbgVals;
>    findDbgValues(FDbgVals, &F_);
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210309/6ca86d37/attachment.html>


More information about the llvm-commits mailing list