aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index 012bc37..2510b77 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -1290,6 +1290,27 @@ MLocTracker::emitLoc(const SmallVectorImpl<ResolvedDbgOp> &DbgOps,
}
}
+ // https://github.com/llvm/llvm-project/issues/64093
+ // in particular #issuecomment-2531264124. We use variable locations
+ // such as DBG_VALUE $xmm0 as shorthand to refer to "the low lane of
+ // $xmm0", and this is reflected in how DWARF is interpreted too.
+ // However InstrRefBasedLDV tries to be smart and interprets such a
+ // DBG_VALUE as a 128-bit reference. We then issue a DW_OP_deref_size
+ // of 128 bits to the stack, which isn't permitted by DWARF (it's
+ // larger than a pointer).
+ //
+ // Solve this for now by not using DW_OP_deref_size if it would be
+ // illegal. Instead we'll use DW_OP_deref, and the consumer will load
+ // the variable type from the stack, which should be correct.
+ //
+ // There's still a risk of imprecision when LLVM decides to use
+ // smaller or larger value types than the source-variable type, which
+ // manifests as too-little or too-much memory being read from the stack.
+ // However we can't solve that without putting more type information in
+ // debug-info.
+ if (ValueSizeInBits > MF.getTarget().getPointerSizeInBits(0))
+ UseDerefSize = false;
+
SmallVector<uint64_t, 5> OffsetOps;
TRI.getOffsetOpcodes(Spill.SpillOffset, OffsetOps);
bool StackValue = false;