diff --git a/debuginfo-tests/dexter-tests/memvars/inline-escaping-function.c b/debuginfo-tests/dexter-tests/memvars/inline-escaping-function.c new file mode 100644 --- /dev/null +++ b/debuginfo-tests/dexter-tests/memvars/inline-escaping-function.c @@ -0,0 +1,45 @@ +// XFAIL: * +// Incorrect location for variable "param", see PR48719. + +// REQUIRES: lldb +// UNSUPPORTED: system-windows +// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \ +// RUN: --builder 'clang-c' --cflags "-O3 -glldb" -- %s + +// 1. param is escaped by inlineme(¶m) so it is not promoted by +// SROA/mem2reg. +// 2. InstCombine's LowerDbgDeclare converts the dbg.declare to a set of +// dbg.values. +// 3. inlineme(¶m) is inlined. +// 4. SROA/mem2reg fully promotes param. It does not insert a dbg.value after the +// PHI it inserts which merges the values out of entry and if.then in the +// sucessor block. This behaviour is inconsistent. If the dbg.declare was +// still around (i.e. if param was promoted in the first round of mem2reg +// BEFORE LowerDbgDeclare) we would see a dbg.value insered for the PHI. +// 5. JumpThreading removes the if.then block, changing entry to +// unconditionally branch to if.end. +// 6. SimplifyCFG stitches entry and if.end together. + +// The debug info is not updated to account for the merged value prior to or +// during JumpThreading/SimplifyCFG so we end up seeing param=5 for the entire +// function, when we'd expect to see param=10 when stepping onto fluff(). + +__attribute__((always_inline)) +int inlineme(int* p) { return *p * 2; } + +__attribute__((optnone)) +void fluff() {} + +__attribute__((noinline)) +int fun(int param) { + if (param) + param = inlineme(¶m); + fluff(); // DexLabel('s0') + return 0; +} + +int main() { + return fun(5); +} + +// DexExpectWatchValue('param', 10, on_line='s0') diff --git a/debuginfo-tests/dexter-tests/memvars/merged-store.c b/debuginfo-tests/dexter-tests/memvars/merged-store.c new file mode 100644 --- /dev/null +++ b/debuginfo-tests/dexter-tests/memvars/merged-store.c @@ -0,0 +1,43 @@ +// XFAIL: * +// Incorrect location for variable "parama", see PR48719. + +// REQUIRES: lldb +// UNSUPPORTED: system-windows +// RUN: %dexter --fail-lt 1.0 -w --debugger lldb \ +// RUN: --builder 'clang-c' --cflags "-O3 -glldb" -- %s + +// 1. parama is escaped by esc(¶ma) so it is not promoted by +// SROA/mem2reg. +// 2. InstCombine's LowerDbgDeclare converts the dbg.declare to a set of +// dbg.values (tracking the stored SSA values). +// 3. InstCombine replaces the two stores to parama's alloca (the initial +// parameter register store in entry and the assignment in if.then) with a +// PHI+store in the common sucessor. +// 4. SimplifyCFG folds the blocks together and converts the PHI to a +// select. + +// The debug info is not updated to account for the merged value in the +// sucessor prior to SimplifyCFG when it exists as a PHI, or during when it +// becomes a select. As a result we see parama=5 for the entire function, when +// we'd expect to see param=20 when stepping onto fluff(). + +__attribute__((optnone)) +void esc(int* p) {} + +__attribute__((optnone)) +void fluff() {} + +__attribute__((noinline)) +int fun(int parama, int paramb) { + if (parama) + parama = paramb; + fluff(); // DexLabel('s0') + esc(¶ma); + return 0; +} + +int main() { + return fun(5, 20); +} + +// DexExpectWatchValue('parama', 20, on_line='s0') diff --git a/debuginfo-tests/dexter-tests/memvars/unused-merged-value.c b/debuginfo-tests/dexter-tests/memvars/unused-merged-value.c new file mode 100644 --- /dev/null +++ b/debuginfo-tests/dexter-tests/memvars/unused-merged-value.c @@ -0,0 +1,44 @@ +// XFAIL: * +// Incorrect location for variable "parama", see PR48719. + +// REQUIRES: lldb +// UNSUPPORTED: system-windows +// RUN: %dexter --fail-lt 0.1 -w --debugger lldb \ +// RUN: --builder 'clang-c' --cflags "-O3 -glldb" -- %s +// See NOTE at end for more info about the RUN command. + +// 1. SROA/mem2reg fully promotes parama. +// 2. parama's value in the final block is the merge of values for it coming +// out of entry and if.then. If the variable were used later in the function +// mem2reg would insert a PHI here and add a dbg.value to track the merged +// value in debug info. Because it is not used there is no PHI (the merged +// value is implicit) and subsequently no dbg.value. +// 3. SimplifyCFG later folds the blocks together (if.then does nothing besides +// provide debug info so it is removed and if.end is folded into the entry +// block). + +// The debug info is not updated to account for the implicit merged value prior +// to (e.g. during mem2reg) or during SimplifyCFG so we end up seeing parama=5 +// for the entire function, which is incorrect. + +__attribute__((optnone)) +void fluff() {} + +__attribute__((noinline)) +int fun(int parama, int paramb) { + if (parama) + parama = paramb; + fluff(); // DexLabel('s0') + return paramb; +} + +int main() { + return fun(5, 20); +} + +// DexExpectWatchValue('parama', 20, on_line='s0') +// +// NOTE: the dexter command uses --fail-lt 0.1 (instead of the standard 1.0) +// because seeing 'optimized out' would still be a win; it's the best we can do +// without using conditional DWARF operators in the location expression. Seeing +// 'optimized out' should result in a score higher than 0.1.