blob: b769284e990f72944deb83927a46cb8e4b3625bf [file] [log] [blame]
commit 386b66b2fc297cda121a3cc8a36887a6ecbcfc68
Author: Hans Wennborg <hans@chromium.org>
Date: Tue Jun 8 14:42:11 2021 +0200
Revert "3rd Reapply "[DebugInfo] Use variadic debug values to salvage BinOps and GEP instrs with non-const operands""
> This reapplies c0f3dfb9, which was reverted following the discovery of
> crashes on linux kernel and chromium builds - these issues have since
> been fixed, allowing this patch to re-land.
This reverts commit 36ec97f76ac0d8be76fb16ac521f55126766267d.
The change caused non-determinism in the compiler, see comments on the code
review at https://reviews.llvm.org/D91722.
Reverting to unbreak people's builds until that can be addressed.
This also reverts the follow-up "[DebugInfo] Limit the number of values
that may be referenced by a dbg.value" in
a0bd6105d80698c53ceaa64bbe6e3b7e7bbf99ee.
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 031f5c3a3914..e5d4c29ad228 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2589,16 +2589,6 @@ public:
// return it's sign information.
llvm::Optional<SignedOrUnsignedConstant> isConstant() const;
- /// Return the number of unique location operands referred to (via
- /// DW_OP_LLVM_arg) in this expression; this is not necessarily the number of
- /// instances of DW_OP_LLVM_arg within the expression.
- /// For example, for the expression:
- /// (DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_plus,
- /// DW_OP_LLVM_arg 0, DW_OP_mul)
- /// This function would return 2, as there are two unique location operands
- /// (0 and 1).
- uint64_t getNumLocationOperands() const;
-
using element_iterator = ArrayRef<uint64_t>::iterator;
element_iterator elements_begin() const { return getElements().begin(); }
@@ -2746,10 +2736,6 @@ public:
/// return true with an offset of zero.
bool extractIfOffset(int64_t &Offset) const;
- /// Returns true iff this DIExpression contains at least one instance of
- /// `DW_OP_LLVM_arg, n` for all n in [0, N).
- bool hasAllLocationOps(unsigned N) const;
-
/// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
/// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
/// Space>.
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index a008bb7cbb3c..a133267ffe9c 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -1148,9 +1148,7 @@ public:
/// must be at least as wide as the IntPtr type for the address space of
/// the base GEP pointer.
bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
- bool collectOffset(const DataLayout &DL, unsigned BitWidth,
- SmallDenseMap<Value *, APInt, 8> &VariableOffsets,
- APInt &ConstantOffset) const;
+
// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::GetElementPtr);
diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h
index 606c2b570c1b..e28544b6c097 100644
--- a/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/llvm/include/llvm/IR/IntrinsicInst.h
@@ -204,11 +204,6 @@ public:
void replaceVariableLocationOp(Value *OldValue, Value *NewValue);
void replaceVariableLocationOp(unsigned OpIdx, Value *NewValue);
- /// Adding a new location operand will always result in this intrinsic using
- /// an ArgList, and must always be accompanied by a new expression that uses
- /// the new operand.
- void addVariableLocationOps(ArrayRef<Value *> NewValues,
- DIExpression *NewExpr);
void setVariable(DILocalVariable *NewVar) {
setArgOperand(1, MetadataAsValue::get(NewVar->getContext(), NewVar));
diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h
index 303539fd0bfc..03bcea3d91f6 100644
--- a/llvm/include/llvm/IR/Operator.h
+++ b/llvm/include/llvm/IR/Operator.h
@@ -576,12 +576,6 @@ public:
Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
APInt &Offset,
function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
-
- /// Collect the offset of this GEP as a map of Values to their associated
- /// APInt multipliers, as well as a total Constant Offset.
- bool collectOffset(const DataLayout &DL, unsigned BitWidth,
- SmallDenseMap<Value *, APInt, 8> &VariableOffsets,
- APInt &ConstantOffset) const;
};
class PtrToIntOperator
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index 56dac033990c..9208ae8f2ad5 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -298,8 +298,7 @@ void salvageDebugInfoForDbgValues(Instruction &I,
/// appended to the expression. \p LocNo: the index of the location operand to
/// which \p I applies, should be 0 for debug info without a DIArgList.
DIExpression *salvageDebugInfoImpl(Instruction &I, DIExpression *DIExpr,
- bool StackVal, unsigned LocNo,
- SmallVectorImpl<Value *> &AdditionalValues);
+ bool StackVal, unsigned LocNo);
/// Point debug users of \p From to \p To or salvage them. Use this function
/// only when replacing all uses of \p From with \p To, with a guarantee that
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 62ebadaf3cbe..525b839d67a0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -121,6 +121,11 @@ public:
// Currently, DBG_VALUE_VAR expressions must use stack_value.
assert(Expr && Expr->isValid() &&
is_contained(Locs, dwarf::DW_OP_stack_value));
+ for (DbgValueLocEntry &Entry : ValueLocEntries) {
+ assert(!Entry.isConstantFP() && !Entry.isConstantInt() &&
+ "Constant values should only be present in non-variadic "
+ "DBG_VALUEs.");
+ }
#endif
}
@@ -137,6 +142,11 @@ public:
// Currently, DBG_VALUE_VAR expressions must use stack_value.
assert(Expr && Expr->isValid() &&
is_contained(Expr->getElements(), dwarf::DW_OP_stack_value));
+ for (DbgValueLocEntry &Entry : ValueLocEntries) {
+ assert(!Entry.isConstantFP() && !Entry.isConstantInt() &&
+ "Constant values should only be present in non-variadic "
+ "DBG_VALUEs.");
+ }
}
#endif
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 01b06279c0f4..696a28a76e76 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1248,10 +1248,6 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,
}
void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
- // TODO: For the variadic implementation, instead of only checking the fail
- // state of `handleDebugValue`, we need know specifically which values were
- // invalid, so that we attempt to salvage only those values when processing
- // a DIArgList.
assert(!DDI.getDI()->hasArgList() &&
"Not implemented for variadic dbg_values");
Value *V = DDI.getDI()->getValue(0);
@@ -1275,21 +1271,16 @@ void SelectionDAGBuilder::salvageUnresolvedDbgValue(DanglingDebugInfo &DDI) {
while (isa<Instruction>(V)) {
Instruction &VAsInst = *cast<Instruction>(V);
// Temporary "0", awaiting real implementation.
- SmallVector<Value *, 4> AdditionalValues;
- DIExpression *SalvagedExpr =
- salvageDebugInfoImpl(VAsInst, Expr, StackValue, 0, AdditionalValues);
+ DIExpression *NewExpr = salvageDebugInfoImpl(VAsInst, Expr, StackValue, 0);
// If we cannot salvage any further, and haven't yet found a suitable debug
// expression, bail out.
- // TODO: If AdditionalValues isn't empty, then the salvage can only be
- // represented with a DBG_VALUE_LIST, so we give up. When we have support
- // here for variadic dbg_values, remove that condition.
- if (!SalvagedExpr || !AdditionalValues.empty())
+ if (!NewExpr)
break;
// New value and expr now represent this debuginfo.
V = VAsInst.getOperand(0);
- Expr = SalvagedExpr;
+ Expr = NewExpr;
// Some kind of simplification occurred: check whether the operand of the
// salvaged debug expression can be encoded in this DAG.
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 7b0dab799e1a..5e8eaacfbdc7 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -1251,17 +1251,6 @@ bool DIExpression::extractIfOffset(int64_t &Offset) const {
return false;
}
-bool DIExpression::hasAllLocationOps(unsigned N) const {
- SmallDenseSet<uint64_t, 4> SeenOps;
- for (auto ExprOp : expr_ops())
- if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)
- SeenOps.insert(ExprOp.getArg(0));
- for (uint64_t Idx = 0; Idx < N; ++Idx)
- if (!is_contained(SeenOps, Idx))
- return false;
- return true;
-}
-
const DIExpression *DIExpression::extractAddressClass(const DIExpression *Expr,
unsigned &AddrClass) {
// FIXME: This seems fragile. Nothing that verifies that these elements
@@ -1476,16 +1465,6 @@ Optional<DIExpression *> DIExpression::createFragmentExpression(
return DIExpression::get(Expr->getContext(), Ops);
}
-uint64_t DIExpression::getNumLocationOperands() const {
- uint64_t Result = 0;
- for (auto ExprOp : expr_ops())
- if (ExprOp.getOp() == dwarf::DW_OP_LLVM_arg)
- Result = std::max(Result, ExprOp.getArg(0) + 1);
- assert(hasAllLocationOps(Result) &&
- "Expression is missing one or more location operands.");
- return Result;
-}
-
llvm::Optional<DIExpression::SignedOrUnsignedConstant>
DIExpression::isConstant() const {
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index f1df5001c134..f2316b609193 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -1798,15 +1798,6 @@ bool GetElementPtrInst::accumulateConstantOffset(const DataLayout &DL,
return cast<GEPOperator>(this)->accumulateConstantOffset(DL, Offset);
}
-bool GetElementPtrInst::collectOffset(
- const DataLayout &DL, unsigned BitWidth,
- SmallDenseMap<Value *, APInt, 8> &VariableOffsets,
- APInt &ConstantOffset) const {
- // Delegate to the generic GEPOperator implementation.
- return cast<GEPOperator>(this)->collectOffset(DL, BitWidth, VariableOffsets,
- ConstantOffset);
-}
-
//===----------------------------------------------------------------------===//
// ExtractElementInst Implementation
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 30c7ceb3c3f0..eab250adb738 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -118,23 +118,6 @@ void DbgVariableIntrinsic::replaceVariableLocationOp(unsigned OpIdx,
0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs)));
}
-void DbgVariableIntrinsic::addVariableLocationOps(ArrayRef<Value *> NewValues,
- DIExpression *NewExpr) {
- assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +
- NewValues.size()) &&
- "NewExpr for debug variable intrinsic does not reference every "
- "location operand.");
- assert(!is_contained(NewValues, nullptr) && "New values must be non-null");
- setArgOperand(2, MetadataAsValue::get(getContext(), NewExpr));
- SmallVector<ValueAsMetadata *, 4> MDs;
- for (auto *VMD : location_ops())
- MDs.push_back(getAsMetadata(VMD));
- for (auto *VMD : NewValues)
- MDs.push_back(getAsMetadata(VMD));
- setArgOperand(
- 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs)));
-}
-
Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
if (auto Fragment = getExpression()->getFragmentInfo())
return Fragment->SizeInBits;
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index e030cb552275..69181f35827b 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -142,61 +142,4 @@ bool GEPOperator::accumulateConstantOffset(
}
return true;
}
-
-bool GEPOperator::collectOffset(
- const DataLayout &DL, unsigned BitWidth,
- SmallDenseMap<Value *, APInt, 8> &VariableOffsets,
- APInt &ConstantOffset) const {
- assert(BitWidth == DL.getIndexSizeInBits(getPointerAddressSpace()) &&
- "The offset bit width does not match DL specification.");
-
- auto CollectConstantOffset = [&](APInt Index, uint64_t Size) {
- Index = Index.sextOrTrunc(BitWidth);
- APInt IndexedSize = APInt(BitWidth, Size);
- ConstantOffset += Index * IndexedSize;
- };
-
- for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this);
- GTI != GTE; ++GTI) {
- // Scalable vectors are multiplied by a runtime constant.
- bool ScalableType = isa<ScalableVectorType>(GTI.getIndexedType());
-
- Value *V = GTI.getOperand();
- StructType *STy = GTI.getStructTypeOrNull();
- // Handle ConstantInt if possible.
- if (auto ConstOffset = dyn_cast<ConstantInt>(V)) {
- if (ConstOffset->isZero())
- continue;
- // If the type is scalable and the constant is not zero (vscale * n * 0 =
- // 0) bailout.
- // TODO: If the runtime value is accessible at any point before DWARF
- // emission, then we could potentially keep a forward reference to it
- // in the debug value to be filled in later.
- if (ScalableType)
- return false;
- // Handle a struct index, which adds its field offset to the pointer.
- if (STy) {
- unsigned ElementIdx = ConstOffset->getZExtValue();
- const StructLayout *SL = DL.getStructLayout(STy);
- // Element offset is in bytes.
- CollectConstantOffset(APInt(BitWidth, SL->getElementOffset(ElementIdx)),
- 1);
- continue;
- }
- CollectConstantOffset(ConstOffset->getValue(),
- DL.getTypeAllocSize(GTI.getIndexedType()));
- continue;
- }
-
- if (STy || ScalableType)
- return false;
- // Insert an initial offset of 0 for V iff none exists already, then
- // increment the offset by IndexedSize.
- VariableOffsets.try_emplace(V, BitWidth, 0);
- APInt IndexedSize =
- APInt(BitWidth, DL.getTypeAllocSize(GTI.getIndexedType()));
- VariableOffsets[V] += IndexedSize;
- }
- return true;
-}
} // namespace llvm
diff --git a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
index 18f8e5e61a40..51cf5b22021c 100644
--- a/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroFrame.cpp
@@ -2467,15 +2467,10 @@ void coro::salvageDebugInfo(
} else if (auto *StInst = dyn_cast<StoreInst>(Storage)) {
Storage = StInst->getOperand(0);
} else if (auto *GEPInst = dyn_cast<GetElementPtrInst>(Storage)) {
- SmallVector<Value *> AdditionalValues;
- DIExpression *SalvagedExpr = llvm::salvageDebugInfoImpl(
- *GEPInst, Expr,
- /*WithStackValue=*/false, 0, AdditionalValues);
- // Debug declares cannot currently handle additional location
- // operands.
- if (!SalvagedExpr || !AdditionalValues.empty())
- break;
- Expr = SalvagedExpr;
+ Expr = llvm::salvageDebugInfoImpl(*GEPInst, Expr,
+ /*WithStackValue=*/false, 0);
+ if (!Expr)
+ return;
Storage = GEPInst->getOperand(0);
} else if (auto *BCInst = dyn_cast<llvm::BitCastInst>(Storage))
Storage = BCInst->getOperand(0);
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index eeaf43a4a55d..13a2f30442cc 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1724,9 +1724,6 @@ void llvm::salvageDebugInfo(Instruction &I) {
void llvm::salvageDebugInfoForDbgValues(
Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
- // This is an arbitrary chosen limit on the maximum number of values we can
- // salvage up to in a DIArgList, used for performance reasons.
- const unsigned MaxDebugArgs = 16;
bool Salvaged = false;
for (auto *DII : DbgUsers) {
@@ -1739,30 +1736,17 @@ void llvm::salvageDebugInfoForDbgValues(
is_contained(DIILocation, &I) &&
"DbgVariableIntrinsic must use salvaged instruction as its location");
unsigned LocNo = std::distance(DIILocation.begin(), find(DIILocation, &I));
- SmallVector<Value *, 4> AdditionalValues;
- DIExpression *SalvagedExpr = salvageDebugInfoImpl(
- I, DII->getExpression(), StackValue, LocNo, AdditionalValues);
+
+ DIExpression *DIExpr =
+ salvageDebugInfoImpl(I, DII->getExpression(), StackValue, LocNo);
// salvageDebugInfoImpl should fail on examining the first element of
// DbgUsers, or none of them.
- if (!SalvagedExpr)
+ if (!DIExpr)
break;
DII->replaceVariableLocationOp(&I, I.getOperand(0));
- if (AdditionalValues.empty()) {
- DII->setExpression(SalvagedExpr);
- } else if (isa<DbgValueInst>(DII) &&
- DII->getNumVariableLocationOps() + AdditionalValues.size() <=
- MaxDebugArgs) {
- 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.
- // Also do not salvage if the resulting DIArgList would contain an
- // unreasonably large number of values.
- Value *Undef = UndefValue::get(I.getOperand(0)->getType());
- DII->replaceVariableLocationOp(I.getOperand(0), Undef);
- }
+ DII->setExpression(DIExpr);
LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
Salvaged = true;
}
@@ -1777,27 +1761,12 @@ void llvm::salvageDebugInfoForDbgValues(
}
bool getSalvageOpsForGEP(GetElementPtrInst *GEP, const DataLayout &DL,
- uint64_t CurrentLocOps,
- SmallVectorImpl<uint64_t> &Opcodes,
- SmallVectorImpl<Value *> &AdditionalValues) {
+ SmallVectorImpl<uint64_t> &Opcodes) {
unsigned BitWidth = DL.getIndexSizeInBits(GEP->getPointerAddressSpace());
- // Rewrite a GEP into a DIExpression.
- SmallDenseMap<Value *, APInt, 8> VariableOffsets;
+ // Rewrite a constant GEP into a DIExpression.
APInt ConstantOffset(BitWidth, 0);
- if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset))
+ if (!GEP->accumulateConstantOffset(DL, ConstantOffset))
return false;
- if (!VariableOffsets.empty() && !CurrentLocOps) {
- Opcodes.insert(Opcodes.begin(), {dwarf::DW_OP_LLVM_arg, 0});
- CurrentLocOps = 1;
- }
- for (auto Offset : VariableOffsets) {
- AdditionalValues.push_back(Offset.first);
- assert(Offset.second.isStrictlyPositive() &&
- "Expected strictly positive multiplier for offset.");
- Opcodes.append({dwarf::DW_OP_LLVM_arg, CurrentLocOps++, dwarf::DW_OP_constu,
- Offset.second.getZExtValue(), dwarf::DW_OP_mul,
- dwarf::DW_OP_plus});
- }
DIExpression::appendOffset(Opcodes, ConstantOffset.getSExtValue());
return true;
}
@@ -1832,35 +1801,23 @@ uint64_t getDwarfOpForBinOp(Instruction::BinaryOps Opcode) {
}
}
-bool getSalvageOpsForBinOp(BinaryOperator *BI, uint64_t CurrentLocOps,
- SmallVectorImpl<uint64_t> &Opcodes,
- SmallVectorImpl<Value *> &AdditionalValues) {
- // Handle binary operations with constant integer operands as a special case.
+bool getSalvageOpsForBinOp(BinaryOperator *BI,
+ SmallVectorImpl<uint64_t> &Opcodes) {
+ // Rewrite binary operations with constant integer operands.
auto *ConstInt = dyn_cast<ConstantInt>(BI->getOperand(1));
- // Values wider than 64 bits cannot be represented within a DIExpression.
- if (ConstInt && ConstInt->getBitWidth() > 64)
+ if (!ConstInt || ConstInt->getBitWidth() > 64)
return false;
-
+ uint64_t Val = ConstInt->getSExtValue();
Instruction::BinaryOps BinOpcode = BI->getOpcode();
- // Push any Constant Int operand onto the expression stack.
- if (ConstInt) {
- uint64_t Val = ConstInt->getSExtValue();
- // Add or Sub Instructions with a constant operand can potentially be
- // simplified.
- if (BinOpcode == Instruction::Add || BinOpcode == Instruction::Sub) {
- uint64_t Offset = BinOpcode == Instruction::Add ? Val : -int64_t(Val);
- DIExpression::appendOffset(Opcodes, Offset);
- return true;
- }
- Opcodes.append({dwarf::DW_OP_constu, Val});
- } else {
- if (!CurrentLocOps) {
- Opcodes.append({dwarf::DW_OP_LLVM_arg, 0});
- CurrentLocOps = 1;
- }
- Opcodes.append({dwarf::DW_OP_LLVM_arg, CurrentLocOps});
- AdditionalValues.push_back(BI->getOperand(1));
+ // Add or Sub Instructions with a constant operand can potentially be
+ // simplified.
+ if (BinOpcode == Instruction::Add || BinOpcode == Instruction::Sub) {
+ uint64_t Offset = BinOpcode == Instruction::Add ? Val : -int64_t(Val);
+ DIExpression::appendOffset(Opcodes, Offset);
+ return true;
}
+ // Add constant int operand to expression stack.
+ Opcodes.append({dwarf::DW_OP_constu, Val});
// Add salvaged binary operator to expression stack, if it has a valid
// representation in a DIExpression.
@@ -1872,11 +1829,9 @@ bool getSalvageOpsForBinOp(BinaryOperator *BI, uint64_t CurrentLocOps,
return true;
}
-DIExpression *
-llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr,
- bool WithStackValue, unsigned LocNo,
- SmallVectorImpl<Value *> &AdditionalValues) {
- uint64_t CurrentLocOps = SrcDIExpr->getNumLocationOperands();
+DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,
+ DIExpression *SrcDIExpr,
+ bool WithStackValue, unsigned LocNo) {
auto &M = *I.getModule();
auto &DL = M.getDataLayout();
@@ -1890,7 +1845,7 @@ llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr,
};
// initializer-list helper for applying operators to the source DIExpression.
- auto applyOps = [&](ArrayRef<uint64_t> Opcodes) {
+ auto applyOps = [&](ArrayRef<uint64_t> Opcodes) -> DIExpression * {
SmallVector<uint64_t, 8> Ops(Opcodes.begin(), Opcodes.end());
return doSalvage(Ops);
};
@@ -1916,15 +1871,15 @@ llvm::salvageDebugInfoImpl(Instruction &I, DIExpression *SrcDIExpr,
SmallVector<uint64_t, 8> Ops;
if (auto *GEP = dyn_cast<GetElementPtrInst>(&I)) {
- if (getSalvageOpsForGEP(GEP, DL, CurrentLocOps, Ops, AdditionalValues))
+ if (getSalvageOpsForGEP(GEP, DL, Ops))
return doSalvage(Ops);
} else if (auto *BI = dyn_cast<BinaryOperator>(&I)) {
- if (getSalvageOpsForBinOp(BI, CurrentLocOps, Ops, AdditionalValues))
+ if (getSalvageOpsForBinOp(BI, Ops))
return doSalvage(Ops);
}
- // *Not* to do: we should not attempt to salvage load instructions,
- // because the validity and lifetime of a dbg.value containing
- // DW_OP_deref becomes difficult to analyze. See PR40628 for examples.
+ // *Not* to do: we should not attempt to salvage load instructions,
+ // because the validity and lifetime of a dbg.value containing
+ // DW_OP_deref becomes difficult to analyze. See PR40628 for examples.
return nullptr;
}
diff --git a/llvm/test/DebugInfo/NVPTX/debug-info.ll b/llvm/test/DebugInfo/NVPTX/debug-info.ll
index 15ea41e8ebdd..08a7e037ec49 100644
--- a/llvm/test/DebugInfo/NVPTX/debug-info.ll
+++ b/llvm/test/DebugInfo/NVPTX/debug-info.ll
@@ -702,12 +702,12 @@ if.end: ; preds = %if.then, %entry
; CHECK-NEXT: }
; CHECK-NEXT: .section .debug_info
; CHECK-NEXT: {
-; CHECK-NEXT:.b32 10034 // Length of Unit
+; CHECK-NEXT:.b32 10029 // Length of Unit
; CHECK-NEXT:.b8 2 // DWARF version number
; CHECK-NEXT:.b8 0
; CHECK-NEXT:.b32 .debug_abbrev // Offset Into Abbrev. Section
; CHECK-NEXT:.b8 8 // Address Size (in bytes)
-; CHECK-NEXT:.b8 1 // Abbrev [1] 0xb:0x272b DW_TAG_compile_unit
+; CHECK-NEXT:.b8 1 // Abbrev [1] 0xb:0x2726 DW_TAG_compile_unit
; CHECK-NEXT:.b8 0 // DW_AT_producer
; CHECK-NEXT:.b8 4 // DW_AT_language
; CHECK-NEXT:.b8 0
@@ -8306,7 +8306,7 @@ if.end: ; preds = %if.then, %entry
; CHECK-NEXT:.b8 3 // DW_AT_decl_line
; CHECK-NEXT:.b32 3345 // DW_AT_type
; CHECK-NEXT:.b8 0 // End Of Children Mark
-; CHECK-NEXT:.b8 40 // Abbrev [40] 0x2671:0xc4 DW_TAG_subprogram
+; CHECK-NEXT:.b8 40 // Abbrev [40] 0x2671:0xbf DW_TAG_subprogram
; CHECK-NEXT:.b64 Lfunc_begin0 // DW_AT_low_pc
; CHECK-NEXT:.b64 Lfunc_end0 // DW_AT_high_pc
; CHECK-NEXT:.b8 1 // DW_AT_frame_base
@@ -8386,7 +8386,7 @@ if.end: ; preds = %if.then, %entry
; CHECK-NEXT:.b8 12 // DW_AT_call_file
; CHECK-NEXT:.b8 6 // DW_AT_call_line
; CHECK-NEXT:.b8 37 // DW_AT_call_column
-; CHECK-NEXT:.b8 43 // Abbrev [43] 0x2711:0x23 DW_TAG_inlined_subroutine
+; CHECK-NEXT:.b8 43 // Abbrev [43] 0x2711:0x1e DW_TAG_inlined_subroutine
; CHECK-NEXT:.b32 9791 // DW_AT_abstract_origin
; CHECK-NEXT:.b64 Ltmp9 // DW_AT_low_pc
; CHECK-NEXT:.b64 Ltmp10 // DW_AT_high_pc
@@ -8395,8 +8395,6 @@ if.end: ; preds = %if.then, %entry
; CHECK-NEXT:.b8 5 // DW_AT_call_column
; CHECK-NEXT:.b8 44 // Abbrev [44] 0x2729:0x5 DW_TAG_formal_parameter
; CHECK-NEXT:.b32 9820 // DW_AT_abstract_origin
-; CHECK-NEXT:.b8 44 // Abbrev [44] 0x272e:0x5 DW_TAG_formal_parameter
-; CHECK-NEXT:.b32 9829 // DW_AT_abstract_origin
; CHECK-NEXT:.b8 0 // End Of Children Mark
; CHECK-NEXT:.b8 0 // End Of Children Mark
; CHECK-NEXT:.b8 0 // End Of Children Mark
diff --git a/llvm/test/DebugInfo/limit-arglist-size.ll b/llvm/test/DebugInfo/limit-arglist-size.ll
deleted file mode 100644
index 951cc0e1c3cc..000000000000
--- a/llvm/test/DebugInfo/limit-arglist-size.ll
+++ /dev/null
@@ -1,63 +0,0 @@
-; RUN: opt -S -instcombine %s -o - | FileCheck %s
-
-; For performance reasons, we currently limit the number of values that can be
-; referenced by a dbg.value to 16. This test checks that we do not exceed this
-; limit during salvaging.
-
-; CHECK: DIArgList(i32 undef
-; CHECK-NOT: DW_OP_LLVM_arg, 16
-
-target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-define i32 @_Z3foov() local_unnamed_addr !dbg !9 {
-entry:
- %call = call i32 @_Z3barv(), !dbg !14
- %call1 = call i32 @_Z3barv(), !dbg !14
- %add = add nsw i32 %call, %call1, !dbg !14
- %call2 = call i32 @_Z3barv(), !dbg !14
- %call4 = call i32 @_Z3barv(), !dbg !14
- %call6 = call i32 @_Z3barv(), !dbg !14
- %call8 = call i32 @_Z3barv(), !dbg !14
- %call10 = call i32 @_Z3barv(), !dbg !14
- %call12 = call i32 @_Z3barv(), !dbg !14
- %call14 = call i32 @_Z3barv(), !dbg !14
- %call16 = call i32 @_Z3barv(), !dbg !14
- %call18 = call i32 @_Z3barv(), !dbg !14
- %call20 = call i32 @_Z3barv(), !dbg !14
- %call22 = call i32 @_Z3barv(), !dbg !14
- %call24 = call i32 @_Z3barv(), !dbg !14
- %call26 = call i32 @_Z3barv(), !dbg !14
- %call28 = call i32 @_Z3barv(), !dbg !14
- %call30 = call i32 @_Z3barv(), !dbg !14
- call void @llvm.dbg.value(metadata !DIArgList(i32 %add, i32 %call30, i32 %call28, i32 %call26, i32 %call24, i32 %call22, i32 %call20, i32 %call18, i32 %call16, i32 %call14, i32 %call12, i32 %call10, i32 %call8, i32 %call6, i32 %call4, i32 %call2), metadata !15, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 15, DW_OP_plus, DW_OP_LLVM_arg, 14, DW_OP_plus, DW_OP_LLVM_arg, 13, DW_OP_plus, DW_OP_LLVM_arg, 12, DW_OP_plus, DW_OP_LLVM_arg, 11, DW_OP_plus, DW_OP_LLVM_arg, 10, DW_OP_plus, DW_OP_LLVM_arg, 9, DW_OP_plus, DW_OP_LLVM_arg, 8, DW_OP_plus, DW_OP_LLVM_arg, 7, DW_OP_plus, DW_OP_LLVM_arg, 6, DW_OP_plus, DW_OP_LLVM_arg, 5, DW_OP_plus, DW_OP_LLVM_arg, 4, DW_OP_plus, DW_OP_LLVM_arg, 3, DW_OP_plus, DW_OP_LLVM_arg, 2, DW_OP_plus, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)), !dbg !16
- %call32 = call i32 @_Z3barv(), !dbg !17
- ret i32 %call32, !dbg !17
-}
-
-declare dso_local i32 @_Z3barv() local_unnamed_addr
-
-declare void @llvm.dbg.value(metadata, metadata, metadata)
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5, !6, !7}
-!llvm.ident = !{!8}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 13.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
-!1 = !DIFile(filename: "limit-arglist-size.cpp", directory: "/")
-!2 = !{}
-!3 = !{i32 7, !"Dwarf Version", i32 4}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 4}
-!6 = !{i32 7, !"uwtable", i32 1}
-!7 = !{i32 7, !"frame-pointer", i32 2}
-!8 = !{!"clang version 13.0.0"}
-!9 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !10, file: !10, line: 3, type: !11, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
-!10 = !DIFile(filename: "./limit-arglist-size.cpp", directory: "/")
-!11 = !DISubroutineType(types: !12)
-!12 = !{!13}
-!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!14 = !DILocation(line: 4, scope: !9)
-!15 = !DILocalVariable(name: "v16", scope: !9, file: !10, line: 4, type: !13)
-!16 = !DILocation(line: 0, scope: !9)
-!17 = !DILocation(line: 5, scope: !9)
diff --git a/llvm/test/DebugInfo/salvage-gep.ll b/llvm/test/DebugInfo/salvage-gep.ll
deleted file mode 100644
index 6c31b0ff61de..000000000000
--- a/llvm/test/DebugInfo/salvage-gep.ll
+++ /dev/null
@@ -1,56 +0,0 @@
-; RUN: opt %s -dce -S | FileCheck %s
-
-; Tests the salvaging of GEP instructions, specifically struct indexing and
-; non-constant array indexing.
-
-%struct.S = type { i32, i32 }
-
-; CHECK: call void @llvm.dbg.value(metadata !DIArgList(%struct.S* %ptr, i64 %offset),
-; CHECK-SAME: ![[VAR_OFFSET_PTR:[0-9]+]],
-; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 8, DW_OP_mul, DW_OP_plus, DW_OP_plus_uconst, 4, DW_OP_stack_value))
-
-; CHECK: ![[VAR_OFFSET_PTR]] = !DILocalVariable(name: "offset_ptr"
-
-define void @"?foo@@YAXPEAUS@@_J@Z"(%struct.S* %ptr, i64 %offset) !dbg !8 {
-entry:
- call void @llvm.dbg.value(metadata i64 %offset, metadata !20, metadata !DIExpression()), !dbg !24
- call void @llvm.dbg.value(metadata %struct.S* %ptr, metadata !21, metadata !DIExpression()), !dbg !24
- %arrayidx = getelementptr inbounds %struct.S, %struct.S* %ptr, i64 %offset, !dbg !25
- %b = getelementptr inbounds %struct.S, %struct.S* %arrayidx, i32 0, i32 1, !dbg !25
- call void @llvm.dbg.value(metadata i32* %b, metadata !22, metadata !DIExpression()), !dbg !24
- ret void, !dbg !26
-}
-
-declare void @llvm.dbg.value(metadata, metadata, metadata)
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5, !6}
-!llvm.ident = !{!7}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
-!1 = !DIFile(filename: "salvage-gep.cpp", directory: "/")
-!2 = !{}
-!3 = !{i32 2, !"CodeView", i32 1}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 2}
-!6 = !{i32 7, !"PIC Level", i32 2}
-!7 = !{!"clang version 11.0.0"}
-!8 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAXPEAUS@@_J@Z", scope: !9, file: !9, line: 7, type: !10, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !19)
-!9 = !DIFile(filename: ".\\salvage-gep.cpp", directory: "/")
-!10 = !DISubroutineType(types: !11)
-!11 = !{null, !12, !18}
-!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
-!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !9, line: 2, size: 64, flags: DIFlagTypePassByValue, elements: !14, identifier: ".?AUS@@")
-!14 = !{!15, !17}
-!15 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !13, file: !9, line: 3, baseType: !16, size: 32)
-!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!17 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !13, file: !9, line: 4, baseType: !16, size: 32, offset: 32)
-!18 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed)
-!19 = !{!20, !21, !22}
-!20 = !DILocalVariable(name: "offset", arg: 2, scope: !8, file: !9, line: 7, type: !18)
-!21 = !DILocalVariable(name: "ptr", arg: 1, scope: !8, file: !9, line: 7, type: !12)
-!22 = !DILocalVariable(name: "offset_ptr", scope: !8, file: !9, line: 8, type: !23)
-!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64)
-!24 = !DILocation(line: 0, scope: !8)
-!25 = !DILocation(line: 8, scope: !8)
-!26 = !DILocation(line: 9, scope: !8)
diff --git a/llvm/test/DebugInfo/salvage-nonconst-binop.ll b/llvm/test/DebugInfo/salvage-nonconst-binop.ll
deleted file mode 100644
index b470bc1ad2a9..000000000000
--- a/llvm/test/DebugInfo/salvage-nonconst-binop.ll
+++ /dev/null
@@ -1,45 +0,0 @@
-; RUN: opt %s -dce -S | FileCheck %s
-
-; Tests the salvaging of binary operators that use more than one non-constant
-; SSA value.
-
-; CHECK: call void @llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %b),
-; CHECK-SAME: ![[VAR_C:[0-9]+]],
-; CHECK-SAME: !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value))
-
-; CHECK: ![[VAR_C]] = !DILocalVariable(name: "c"
-
-define i32 @"?multiply@@YAHHH@Z"(i32 %a, i32 %b) !dbg !8 {
-entry:
- call void @llvm.dbg.value(metadata i32 %b, metadata !12, metadata !DIExpression()), !dbg !13
- call void @llvm.dbg.value(metadata i32 %a, metadata !14, metadata !DIExpression()), !dbg !13
- %add = add nsw i32 %a, %b, !dbg !15
- call void @llvm.dbg.value(metadata i32 %add, metadata !16, metadata !DIExpression()), !dbg !13
- %mul = mul nsw i32 %a, %b, !dbg !17
- ret i32 %mul, !dbg !17
-}
-
-declare void @llvm.dbg.value(metadata, metadata, metadata)
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!3, !4, !5, !6}
-!llvm.ident = !{!7}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
-!1 = !DIFile(filename: "test.cpp", directory: "/")
-!2 = !{}
-!3 = !{i32 2, !"CodeView", i32 1}
-!4 = !{i32 2, !"Debug Info Version", i32 3}
-!5 = !{i32 1, !"wchar_size", i32 2}
-!6 = !{i32 7, !"PIC Level", i32 2}
-!7 = !{!"clang version 11.0.0"}
-!8 = distinct !DISubprogram(name: "multiply", linkageName: "?multiply@@YAHHH@Z", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
-!9 = !DISubroutineType(types: !10)
-!10 = !{!11, !11, !11}
-!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!12 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 1, type: !11)
-!13 = !DILocation(line: 0, scope: !8)
-!14 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11)
-!15 = !DILocation(line: 2, scope: !8)
-!16 = !DILocalVariable(name: "c", scope: !8, file: !1, line: 2, type: !11)
-!17 = !DILocation(line: 3, scope: !8)
diff --git a/llvm/test/Transforms/InstCombine/debuginfo-sink.ll b/llvm/test/Transforms/InstCombine/debuginfo-sink.ll
index 3fb27637022a..5a8cc78b08c2 100644
--- a/llvm/test/Transforms/InstCombine/debuginfo-sink.ll
+++ b/llvm/test/Transforms/InstCombine/debuginfo-sink.ll
@@ -33,25 +33,23 @@ sink1:
; value range.
; CHECK-LABEL: define i32 @bar(
-; CHECK: call void @llvm.dbg.value(metadata <vscale x 4 x i32>* undef,
+; CHECK: call void @llvm.dbg.value(metadata i32* undef,
; CHECK-NEXT: br label %sink2
-define i32 @bar(<vscale x 4 x i32>* %a, i32 %b) !dbg !70 {
+define i32 @bar(i32 *%a, i32 %b) !dbg !70 {
entry:
- %gep = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i32 %b
- call void @llvm.dbg.value(metadata <vscale x 4 x i32>* %gep, metadata !73, metadata !12), !dbg !74
+ %gep = getelementptr i32, i32 *%a, i32 %b
+ call void @llvm.dbg.value(metadata i32* %gep, metadata !73, metadata !12), !dbg !74
br label %sink2
sink2:
; CHECK-LABEL: sink2:
-; CHECK: call void @llvm.dbg.value(metadata <vscale x 4 x i32>* %gep,
+; CHECK: call void @llvm.dbg.value(metadata i32* %gep,
; CHECK-SAME: metadata !{{[0-9]+}}, metadata !DIExpression())
; CHECK-NEXT: load
-; CHECK-NEXT: extractelement
; CHECK-NEXT: ret
- %0 = load <vscale x 4 x i32>, <vscale x 4 x i32>* %gep
- %extract = extractelement <vscale x 4 x i32> %0, i32 1
- ret i32 %extract
+ %0 = load i32, i32* %gep
+ ret i32 %0
}
; This GEP is sunk, and has multiple debug uses in the same block. Check that
diff --git a/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll b/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll
index 349da85cc80f..98c51c5cf8bb 100644
--- a/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll
+++ b/llvm/test/Transforms/Reassociate/undef_intrinsics_when_deleting_instructions.ll
@@ -1,73 +1,95 @@
-; RUN: opt < %s -reassociate -S | FileCheck %s
-
-; Check that reassociate pass now undefs debug intrinsics that reference a value
-; that gets dropped and cannot be salvaged.
-
-; CHECK-NOT: %add = fadd fast float %a, %b
-; CHECK: call void @llvm.dbg.value(metadata float undef, metadata [[VAR_X:![0-9]+]], metadata !DIExpression())
-
-; CHECK-LABEL: if.then:
-; CHECK-NOT: %add1 = fadd fast float %add, %c
-; CHECK: call void @llvm.dbg.value(metadata float undef, metadata [[VAR_Y:![0-9]+]], metadata !DIExpression())
-; CHECK-LABEL: !0 =
-; CHECK-DAG: [[VAR_Y]] = !DILocalVariable(name: "y"
-; CHECK-DAG: [[VAR_X]] = !DILocalVariable(name: "x"
-
-define float @"?foo@@YAMMMMM@Z"(float %a, float %b, float %c, float %d) !dbg !8 {
-entry:
- call void @llvm.dbg.value(metadata float %d, metadata !12, metadata !DIExpression()), !dbg !13
- call void @llvm.dbg.value(metadata float %c, metadata !14, metadata !DIExpression()), !dbg !13
- call void @llvm.dbg.value(metadata float %b, metadata !15, metadata !DIExpression()), !dbg !13
- call void @llvm.dbg.value(metadata float %a, metadata !16, metadata !DIExpression()), !dbg !13
- %add = fadd fast float %a, %b, !dbg !17
- call void @llvm.dbg.value(metadata float %add, metadata !18, metadata !DIExpression()), !dbg !13
- %cmp = fcmp fast oeq float %d, 4.000000e+00, !dbg !19
- br i1 %cmp, label %if.then, label %return, !dbg !19
+; RUN: opt < %s -reassociate -S | FileCheck %s
-if.then: ; preds = %entry
- %add1 = fadd fast float %add, %c, !dbg !20
- call void @llvm.dbg.value(metadata float %add1, metadata !23, metadata !DIExpression()), !dbg !24
- %sub = fsub fast float %add, 1.200000e+01, !dbg !25
- %sub2 = fsub fast float %add1, %sub, !dbg !25
- %mul = fmul fast float %sub2, 2.000000e+01, !dbg !25
- %div = fdiv fast float %mul, 3.000000e+00, !dbg !25
- br label %return, !dbg !25
+; Check that reassociate pass now undefs debug intrinsics that reference a value
+; that gets dropped and cannot be salvaged.
-return: ; preds = %entry, %if.then
- %retval.0 = phi float [ %div, %if.then ], [ 0.000000e+00, %entry ], !dbg !13
- ret float %retval.0, !dbg !26
+define hidden i32 @main() local_unnamed_addr {
+entry:
+ %foo = alloca i32, align 4, !dbg !20
+ %foo.0.foo.0..sroa_cast = bitcast i32* %foo to i8*, !dbg !20
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %foo.0.foo.0..sroa_cast), !dbg !20
+ store volatile i32 4, i32* %foo, align 4, !dbg !20, !tbaa !21
+ %foo.0.foo.0. = load volatile i32, i32* %foo, align 4, !dbg !25, !tbaa !21
+ %foo.0.foo.0.15 = load volatile i32, i32* %foo, align 4, !dbg !27, !tbaa !21
+ %foo.0.foo.0.16 = load volatile i32, i32* %foo, align 4, !dbg !28, !tbaa !21
+ ; CHECK-NOT: %add = add nsw i32 %foo.0.foo.0., %foo.0.foo.0.15
+ %add = add nsw i32 %foo.0.foo.0., %foo.0.foo.0.15, !dbg !29
+ ; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata [[VAR_A:![0-9]+]], metadata !DIExpression())
+ call void @llvm.dbg.value(metadata i32 %add, metadata !19, metadata !DIExpression()), !dbg !26
+ %foo.0.foo.0.17 = load volatile i32, i32* %foo, align 4, !dbg !30, !tbaa !21
+ %cmp = icmp eq i32 %foo.0.foo.0.17, 4, !dbg !30
+ br i1 %cmp, label %if.then, label %if.end, !dbg !32
+
+ ; CHECK-LABEL: if.then:
+if.then:
+ ; CHECK-NOT: %add1 = add nsw i32 %add, %foo.0.foo.0.16
+ %add1 = add nsw i32 %add, %foo.0.foo.0.16, !dbg !33
+ ; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata [[VAR_A]], metadata !DIExpression())
+ call void @llvm.dbg.value(metadata i32 %add1, metadata !19, metadata !DIExpression()), !dbg !26
+ ; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata [[VAR_CHEESE:![0-9]+]], metadata !DIExpression())
+ call void @llvm.dbg.value(metadata i32 %add, metadata !18, metadata !DIExpression()), !dbg !26
+ %sub = add nsw i32 %add, -12, !dbg !34
+ %sub3 = sub nsw i32 %add1, %sub, !dbg !34
+ %mul = mul nsw i32 %sub3, 20, !dbg !36
+ %div = sdiv i32 %mul, 3, !dbg !37
+ br label %if.end, !dbg !38
+
+if.end:
+ %a.0 = phi i32 [ %div, %if.then ], [ 0, %entry ], !dbg !39
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %foo.0.foo.0..sroa_cast), !dbg !40
+ ret i32 %a.0, !dbg !41
}
-declare void @llvm.dbg.value(metadata, metadata, metadata)
+declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1
+declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1
+declare void @llvm.dbg.value(metadata, metadata, metadata) #2
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5, !6}
!llvm.ident = !{!7}
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 11.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
-!1 = !DIFile(filename: "undef_intrinsics_when_deleting_instructions.cpp", directory: "/")
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, debugInfoForProfiling: true, nameTableKind: None)
+!1 = !DIFile(filename: "test.cpp", directory: "F:\")
!2 = !{}
-!3 = !{i32 2, !"CodeView", i32 1}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 2}
!6 = !{i32 7, !"PIC Level", i32 2}
-!7 = !{!"clang version 11.0.0"}
-!8 = distinct !DISubprogram(name: "foo", linkageName: "?foo@@YAMMMMM@Z", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
-!9 = !DISubroutineType(types: !10)
-!10 = !{!11, !11, !11, !11, !11}
-!11 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
-!12 = !DILocalVariable(name: "d", arg: 4, scope: !8, file: !1, line: 1, type: !11)
-!13 = !DILocation(line: 0, scope: !8)
-!14 = !DILocalVariable(name: "c", arg: 3, scope: !8, file: !1, line: 1, type: !11)
-!15 = !DILocalVariable(name: "b", arg: 2, scope: !8, file: !1, line: 1, type: !11)
-!16 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11)
-!17 = !DILocation(line: 2, scope: !8)
-!18 = !DILocalVariable(name: "x", scope: !8, file: !1, line: 2, type: !11)
-!19 = !DILocation(line: 3, scope: !8)
-!20 = !DILocation(line: 4, scope: !21)
-!21 = distinct !DILexicalBlock(scope: !22, file: !1, line: 3)
-!22 = distinct !DILexicalBlock(scope: !8, file: !1, line: 3)
-!23 = !DILocalVariable(name: "y", scope: !21, file: !1, line: 4, type: !11)
-!24 = !DILocation(line: 0, scope: !21)
-!25 = !DILocation(line: 5, scope: !21)
-!26 = !DILocation(line: 8, scope: !8)
+!7 = !{!"clang version 10.0.0"}
+!8 = distinct !DISubprogram(name: "main", scope: !9, file: !9, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13)
+!9 = !DIFile(filename: "./test.cpp", directory: "F:\")
+!10 = !DISubroutineType(types: !11)
+!11 = !{!12}
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !{!14, !16, !17, !18, !19}
+!14 = !DILocalVariable(name: "foo", scope: !8, file: !9, line: 2, type: !15)
+!15 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !12)
+!16 = !DILocalVariable(name: "read1", scope: !8, file: !9, line: 3, type: !12)
+!17 = !DILocalVariable(name: "read2", scope: !8, file: !9, line: 4, type: !12)
+; CHECK: [[VAR_CHEESE]] = !DILocalVariable(name: "cheese"
+!18 = !DILocalVariable(name: "cheese", scope: !8, file: !9, line: 6, type: !12)
+; CHECK: [[VAR_A]] = !DILocalVariable(name: "a"
+!19 = !DILocalVariable(name: "a", scope: !8, file: !9, line: 7, type: !12)
+!20 = !DILocation(line: 2, scope: !8)
+!21 = !{!22, !22, i64 0}
+!22 = !{!"int", !23, i64 0}
+!23 = !{!"omnipotent char", !24, i64 0}
+!24 = !{!"Simple C++ TBAA"}
+!25 = !DILocation(line: 3, scope: !8)
+!26 = !DILocation(line: 0, scope: !8)
+!27 = !DILocation(line: 4, scope: !8)
+!28 = !DILocation(line: 6, scope: !8)
+!29 = !DILocation(line: 7, scope: !8)
+!30 = !DILocation(line: 10, scope: !31)
+!31 = distinct !DILexicalBlock(scope: !8, file: !9, line: 10)
+!32 = !DILocation(line: 10, scope: !8)
+!33 = !DILocation(line: 8, scope: !8)
+!34 = !DILocation(line: 12, scope: !35)
+!35 = distinct !DILexicalBlock(scope: !31, file: !9, line: 10)
+!36 = !DILocation(line: 13, scope: !35)
+!37 = !DILocation(line: 14, scope: !35)
+!38 = !DILocation(line: 15, scope: !35)
+!39 = !DILocation(line: 0, scope: !31)
+!40 = !DILocation(line: 20, scope: !8)
+!41 = !DILocation(line: 19, scope: !8)