[PATCH] D156545: [DebugInfo][InstrRef] Don't produce over-sized DW_OP_deref_size expressions for very wide stack spills

Jeremy Morse via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 1 08:01:00 PDT 2023


jmorse planned changes to this revision.
jmorse added a comment.

Sorry for the month delay, I was wandering up some mountains,

Coming back to this with fresh eyes, I missed something in the reproducer from GH ticket -- I thought it was spilling an entire vector register to the stack, however...

  push    rbp
  mov     rbp, rsp
  sub     rsp, 16
  movsd   qword ptr [rbp - 8], xmm0
  call    c()@PLT
  movsd   xmm0, qword ptr [rbp - 8]       # xmm0 = mem[0],zero
  call    b(double)@PLT
  add     rsp, 16
  pop     rbp
  ret

... it's actually performing a partial spill of the lower parts of xmm0, a fact that is encoded in the opcode (movsd not mov) but missed by InstrRefBasedLDV. So there's an extra factor of "where does that information go missing" to build into a different patch.



================
Comment at: llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp:1163
+  // size of value and the size of variable portion being read, on big endian
+  // systems. Consider:
+  //
----------------
Orlando wrote:
> Does a test for this part already exist? I assume so, since this patch is just narrowing the use cases rather than adding the functionally, but wanted to check to be sure.
Yup, it's `llvm/test/DebugInfo/MIR/InstrRef/deref-spills-with-size.mir` and tests pretty much every combination of sizes and derefs.


================
Comment at: llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp:1175
+  unsigned ValueSizeInBits = getLocSizeInBits(MLoc);
+  unsigned DerefSizeInBytes = ValueSizeInBits / 8;
+  if (DerefSizeInBytes > PointerSizeBytes) {
----------------
aprantl wrote:
> Orlando wrote:
> > Can `ValueSizeInBits` ever be a value that doesn't divide cleanly by 8? e.g. 1 from an `i1` type (I haven't looked at how `getLocSizeInBits` works). 
> > 
> > If so then I think we might need to use `divideCeil` from `MathExtras.h` here. Otherwise, with the code as is, a `1` would result in `DerefSizeInBytes` of `0`.
> Would using a PointerSizeInBits instead help?
I suppose switching to using bits instead of bytes will remove a category of weirdness that can occur, will implement that,


================
Comment at: llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp:1177-1178
+  if (DerefSizeInBytes > PointerSizeBytes) {
+    // This would be illegal DWARF. Perhaps the output will identify a
+    // flawed location, but it'll at least be legal output.
+    return false;
----------------
dblaikie wrote:
> Could you clarify/rephrase the "output will identify a flawed location" - I don't understand what you mean by that & I'd have expected the failure here to be "absence of a location" rather than possibly incorrect locations ("flawed" I assume means "incorrect"?)
Improved wording would be "There's a risk this is incorrect on big endian systems", however I'm going to back off this for a moment, see main comment.


================
Comment at: llvm/test/DebugInfo/MIR/InstrRef/livedebugvalues_deref_size_too_big.mir:6
+# exceeds the size of an address (64 bits). We should produce a plain
+# DW_OP_deref instead, as that's a legal output.
+#
----------------
dblaikie wrote:
> How would a plain DW_OP_deref work here - it'd still only be word-wide, right - so 64 bits, but the low 64 bit of a 128bit floating point value presumably isn't a valid floating point value, right?
Hrrm. It's technically valid for x86 as the 128-bit-and-higher registers are all vectors, but baking that assumption in here guarantees it'll break something else. I'm going to back off from this for a moment (see main comment) and come back with a re-rationalised approach.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D156545/new/

https://reviews.llvm.org/D156545



More information about the llvm-commits mailing list