Investigating a buggy/bit-rotten test case (llvm/test/DebugInfo/X86/dbg-large-unsigned-const.ll) I stumbled across a bug in SROA+debug info.
Given this source:
long glbl; inline __attribute__((always_inline)) bool func(const long &l) { return l == glbl; } int main() { return func(9223372036854775807); }
The function is inlined, SROA removes the alloca and uses the constant directly (sorry, the constant could be smaller, it doesn't really matter - just some history from the test case I was investigating) and then replaces the dbg.value that references the memory location with a dbg.value using the constant directly.
What this does is cause the debug info to get very confused - the type of the variable is a reference, that means its value is the pointer to the value, not the value itself. So the debugger tries to dereference the constant.
No good.
It looks as if the entire chunk of code in AllocaPromoter::updateDebugInfo dedicated to looking through the loads and stores and creating a new dbg.value from that should be replaced with code to create dbg.values of undef. For situations where we still end up with a memory operand (we removed one layer of indirection, but there's still another) we can probably represent this in debug info one day. But for registers and constants I don't think there's anything we can do to represent their value in DWARF when we've lost the indirection they required.
Does this make sense to people?
Oh, and the other changes in this patch are one attempt at addressing a knock-on issue that fixing this bug triggers: since the parameter is undef, it goes missing later on. By preserving the dbg_values a bit further we don't lose the parameter anymore, even though we can't describe its location.