<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - pass-by-reference arg shows incorrect debuginfo value within loop after LICM"
href="https://bugs.llvm.org/show_bug.cgi?id=37682">37682</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>pass-by-reference arg shows incorrect debuginfo value within loop after LICM
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>greg.bedwell@sony.com
</td>
</tr>
<tr>
<th>CC</th>
<td>anastasis.gramm2@gmail.com, aprantl@apple.com, ftee@flametop.co.uk, llvm-bugs@lists.llvm.org, paul_robinson@playstation.sony.com, vsk@apple.com
</td>
</tr></table>
<p>
<div>
<pre>Versions:
~~~~~~
$ clang --version
clang version 7.0.0 (trunk 333874) (llvm/trunk 333894)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: e:\build\Release\bin
$ lldb --version
lldb version 7.0.0 (<a href="https://git.llvm.org/git/lldb.git/">https://git.llvm.org/git/lldb.git/</a> revision
0fbc22d3ed13e6825ddd28e9fdf50e8c7887850f)
clang revision 333874
llvm revision 333894
~~~~~~
Repro case:
~~~~~~
$ cat tests\fibonacci\test.cpp
__attribute__((__noinline__))
void Fibonacci(int terms, int& total)
{
int first = 0;
int second = 1;
for (int i = 0; i < terms; ++i)
{
int next = first + second; // DexWatch('total', '*(int*)$rdx', '$r10')
total += first; // DexWatch('total', '*(int*)$rdx', '$r10')
first = second; // DexWatch('total', '*(int*)$rdx', '$r10')
second = next; // DexWatch('total', '*(int*)$rdx', '$r10')
}
}
int main()
{
int total = 0;
Fibonacci(6, total);
return total;
}
~~~~~~
Trace output from DExTer (
<a href="http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf">http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf</a>
) with -opt-bisect-limit=31. Each line represents stepping once in the
debugger. The values in the {} are the results of evaluating those expressions
in the debugger while paused at that step.
We can see that variable total which is a function argument that has been
passed by reference lives in the memory pointed at by $rdx, so the values
match. Ignore $r10 for now.
~~~~~~
$ py -3 dexter.py test --builder clang --debugger lldb tests\fibonacci -v
--cflags="-O2 -g -mllvm -opt-bisect-limit=31" --ldflags="-g"
## BEGIN ##
[1, "main", "test.cpp", 18, 7, "BREAKPOINT", "FUNC", {}]
[2, "main", "test.cpp", 19, 3, "BREAKPOINT", "FORWARD", {}]
. [3, "void Fibonacci(int,int &)", "test.cpp", 7, 21, "BREAKPOINT", "FUNC",
{}]
. [4, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "0"}]
. [5, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "1"}]
. [6, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD", {}]
. [7, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "1"}]
. [8, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "2"}]
. [9, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD", {}]
. [10, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "1", "*(int*)$rdx": "1", "$r10": "2"}]
. [11, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "1", "*(int*)$rdx": "1", "$r10": "3"}]
. [12, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [13, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "2", "*(int*)$rdx": "2", "$r10": "3"}]
. [14, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "2", "*(int*)$rdx": "2", "$r10": "5"}]
. [15, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [16, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "4", "*(int*)$rdx": "4", "$r10": "5"}]
. [17, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "4", "*(int*)$rdx": "4", "$r10": "8"}]
. [18, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [19, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "7", "*(int*)$rdx": "7", "$r10": "8"}]
. [20, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "7", "*(int*)$rdx": "7", "$r10": "13"}]
. [21, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [22, "void Fibonacci(int,int &)", "test.cpp", 14, 1, "BREAKPOINT",
"FORWARD", {}]
[23, "main", "test.cpp", 20, 10, "BREAKPOINT", "FUNC", {}]
## END (23 steps) ##
~~~~~~
Trace output from DExTer with -opt-bisect-limit=32 (BISECT: running pass (32)
Loop Invariant Code Motion on loop).
Within the loop, variable 'total' now lives in $r10 and is only stored back to
the address in $rdx after the loop terminates. The debug info for total still
appears to be pointing at address of $rdx throughout though, so we get an
incorrect value of 0.
~~~~~~
$ py -3 dexter.py test --builder clang --debugger lldb tests\fibonacci -v
--cflags="-O2 -g -mllvm -opt-bisect-limit=32" --ldflags="-g"
## BEGIN ##
[1, "main", "test.cpp", 18, 7, "BREAKPOINT", "FUNC", {}]
[2, "main", "test.cpp", 19, 3, "BREAKPOINT", "FORWARD", {}]
. [3, "void Fibonacci(int,int &)", "test.cpp", 7, 21, "BREAKPOINT", "FUNC",
{}]
. [4, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "0"}]
. [5, "void Fibonacci(int,int &)", "test.cpp", 7, 3, "STEP", "BACKWARD", {}]
. [6, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "0"}]
. [7, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "0"}]
. [8, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD", {}]
. [9, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "0"}]
. [10, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "0"}]
. [11, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [12, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "1"}]
. [13, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "1"}]
. [14, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [15, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "2"}]
. [16, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "2"}]
. [17, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [18, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "4"}]
. [19, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "4"}]
. [20, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [21, "void Fibonacci(int,int &)", "test.cpp", 9, 22, "BREAKPOINT",
"FORWARD", {"total": "0", "*(int*)$rdx": "0", "$r10": "7"}]
. [22, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "7"}]
. [23, "void Fibonacci(int,int &)", "test.cpp", 7, 30, "STEP", "BACKWARD",
{}]
. [24, "void Fibonacci(int,int &)", "test.cpp", 10, 11, "STEP", "FORWARD",
{"total": "0", "*(int*)$rdx": "0", "$r10": "12"}]
. [25, "void Fibonacci(int,int &)", "test.cpp", 14, 1, "BREAKPOINT",
"FORWARD", {}]
[26, "main", "test.cpp", 20, 10, "BREAKPOINT", "FUNC", {}]
## END (26 steps) ##
~~~~~~
Even though "total" comes in as a reference I think it would be fair to set the
location of total to the register throughout the loop. At the very least I'd
expect to see a "variable not visible due to optimization" type message.</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>