Following on from D68945, @uabelho pointed out a scenario where there's some confusion about where a DW_OP_deref should be added for arguments passed on the stack. A Value/Argument that gets placed in memory requires the stack slot it lands in to be dereferenced, and that deref would go at the start of the expression so that it operates on the slot. If the argument is the operand to a dbg.declare, then it might require a deref at the end of the expression as well, to make it a memory location.
In SelectionDAG::EmitFuncArgumentDbgValue that's what I've implemented, best illustrated by the baz function in the attached test:
define i8 @baz(i32 *%blah) !dbg !40 { entry: call void @llvm.dbg.declare(metadata i32* %blah, metadata !43, metadata !DIExpression(DW_OP_plus_uconst, 4)), !dbg !41 ret i8 0, !dbg !41 }
%blah is an incoming pointer, but it arrives in a stack slot, which must be dereferenced first. And because it is used by a dbg.declare, we append a deref to force it to be a memory location. With this patch, we get the DBG_VALUE:
DBG_VALUE %fixed-stack.0, $noreg, !123, !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 4, DW_OP_deref)
i.e., "load the stack slot, fiddle with the pointer, then be a memory location". I've added llvm-dwarfdump checks to ensure this comes out the far end in the correct format (I'm 97% the encoding is correct there).
I've deleted the "IsIndirect" var in EmitFuncArgumentDbgValue, as it wasn't doing anything useful IMO.
Nice, I think this is heading the right direction!
However, if we look at PEI::replaceFrameIndices which handles the indirect stuff, it uses DW_OP_deref_size rather than DW_OP_deref:
I think we need to take the size into consideration here in SelectionDAGBuilder too.
My out-of-tree big-endian target example now goes wrong since we read a value that is placed adjacent to the wanted value on the stack. I think using DW_OP_deref_size could perhaps solve that.