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