[llvm-bugs] [Bug 37682] New: pass-by-reference arg shows incorrect debuginfo value within loop after LICM

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Jun 4 14:12:17 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=37682

            Bug ID: 37682
           Summary: pass-by-reference arg shows incorrect debuginfo value
                    within loop after LICM
           Product: new-bugs
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: greg.bedwell at sony.com
                CC: anastasis.gramm2 at gmail.com, aprantl at apple.com,
                    ftee at flametop.co.uk, llvm-bugs at lists.llvm.org,
                    paul_robinson at playstation.sony.com, vsk at apple.com

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 (https://git.llvm.org/git/lldb.git/ 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 (
http://llvm.org/devmtg/2018-04/slides/Bedwell-Measuring_the_User_Debugging_Experience.pdf
) 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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180604/92cf2618/attachment-0001.html>


More information about the llvm-bugs mailing list