Files
clang-p2996/debuginfo-tests/dexter-tests/memvars/loop.c
OCHyams 66d03af88c [DebugInfo][dexter] Add dexter tests for escaped locals
Recently there has been renewed interest in improving debug-info for variables
that (partially or otherwise) live on the stack in optimised code.

At the moment instcombine speculates that stack slots are probably going to be
promoted to registers, and prepares the debug-info accordingly. It runs a
function called LowerDbgDeclare which converts dbg.declares to a set of
dbg.values after loads, and before stores and calls. Sometimes the stack
location remains (e.g. for escaped locals). If any dbg.values become undef
where the stack location is still valid we end up unnecessarily reducing
variable location coverage due to our inability to track multiple locations
simultaneously. There is a flag to disable this feature
(-instcombine-lower-dbg-declare=0), which prevents this conversion at the cost
of sometimes providing incorrect location info in the face of DSE, DCE, GVN,
CSE etc.

This has been discussed fairly extensively on PR34136.

The idea of these tests is to provide examples of situations that we should
consider when designing a new system, to aid discussions and eventually help
evaluate the implementation.

Dexter isn't ideal for observing specific optimisation behaviour. Writing an
exaustive test suite would be difficult, and the resultant suite would be
fragile. However, I think having some concrete executable examples is useful
at least as a reference.

Differential Revision: https://reviews.llvm.org/D89543
2020-10-26 10:57:36 +00:00

57 lines
1.7 KiB
C

// XFAIL: *
//// Suboptimal coverage, see below.
// REQUIRES: lldb
// UNSUPPORTED: system-windows
// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \
// RUN: --builder 'clang-c' --cflags "-O3 -glldb" -- %s
//// Check that escaped local 'param' in function 'fun' has sensible debug info
//// after the escaping function 'use' gets arg promotion (int* -> int). Currently
//// we lose track of param after the loop header.
int g = 0;
//// A no-inline, read-only function with internal linkage is a good candidate
//// for arg promotion.
__attribute__((__noinline__))
static void use(const int* p) {
//// Promoted args would be a good candidate for an DW_OP_implicit_pointer.
//// This desirable behaviour is checked for in the test implicit-ptr.c.
g = *p;
}
__attribute__((__noinline__))
void do_thing(int x) {
g *= x;
}
__attribute__((__noinline__))
int fun(int param) {
do_thing(0); // DexLabel('s2')
for (int i = 0; i < param; ++i) {
use(&param);
}
//// x86 loop body looks like this, with param in ebx:
//// 4004b0: mov edi,ebx
//// 4004b2: call 4004d0 <_ZL3usePKi>
//// 4004b7: add ebp,0xffffffff
//// 4004ba: jne 4004b0 <_Z3funi+0x20>
//// But we lose track of param's location before the loop:
//// DW_TAG_formal_parameter
//// DW_AT_location (0x00000039:
//// [0x0000000000400490, 0x0000000000400495): DW_OP_reg5 RDI
//// [0x0000000000400495, 0x00000000004004a2): DW_OP_reg3 RBX)
//// DW_AT_name ("param")
return g; // DexLabel('s3')
}
int main() {
return fun(5);
}
// DexExpectWatchValue('*p', 5, 5, 5, 5, 5, on_line='s1')
// DexExpectWatchValue('param', 5, from_line='s2', to_line='s3')