<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 - [codeview] Incorrect variable locations with stack realignment and call-frame optimization"
   href="https://bugs.llvm.org/show_bug.cgi?id=38857">38857</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[codeview] Incorrect variable locations with stack realignment and call-frame optimization
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </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>DebugInfo
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>rnk@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>brucedawson@chromium.org, llvm-bugs@lists.llvm.org, llvm@inglorion.net
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Consider this program:

struct Foo {
  int x = 42;
  int __declspec(noinline) foo();
  void __declspec(noinline) bar(int *a, int *b, double *c);
};
int Foo::foo() {
  int a = 1;
  int b = 2;
  double force_alignment = 0.42;
  bar(&a, &b, &force_alignment);
  x += (int)force_alignment;
  return x;
}
void Foo::bar(int *a, int *b, double *c) {
  __debugbreak();
  *c += *a + *b;
}
int main() {
  Foo o;
  o.foo();
}

Compile it this:
$ clang-cl -mllvm -instcombine-lower-dbg-declare=0 -GS- -m32 -Z7 -O2 t.cpp

Run it under windbg, and unwind the stack one level, and examine locals (dv).
It should print this:
0:000> dv
           this = 0x0113fc44
              a = 0n1
              b = 0n2
force_alignment = 0.41999999999999998446

Today it prints:
0:000> dv
           this = 0x007bfd40
              a = 0n1071309127
              b = 0n-1374389535
force_alignment = 2.4910886115092882213e-306


The debug info says that 'a' is at ESP+0x10, but that doesn't describe the 12
bytes used to push arguments for bar:
    7 00ca6afe c744241001000000 mov     dword ptr [esp+10h],1
    8 00ca6b06 c744240c02000000 mov     dword ptr [esp+0Ch],2
    9 00ca6b0e c744240447e1da3f mov     dword ptr [esp+4],3FDAE147h
    9 00ca6b16 c70424e17a14ae  mov     dword ptr [esp],0AE147AE1h
    9 00ca6b1d 8d4c240c        lea     ecx,[esp+0Ch]
    9 00ca6b21 8d542410        lea     edx,[esp+10h]
   10 00ca6b25 50              push    eax
   10 00ca6b26 51              push    ecx
   10 00ca6b27 52              push    edx
   10 00ca6b28 e870a8ffff      call    t!ILT+920(?barFooQAEXPAH0PANZ)
(00ca139d)

If I disable x86 call frame optimization to make us not use PUSH instructions,
the problem goes away, and we generate this code:
    7 00966b04 c744242001000000 mov     dword ptr [esp+20h],1
    8 00966b0c c744241c02000000 mov     dword ptr [esp+1Ch],2
    9 00966b14 c744241447e1da3f mov     dword ptr [esp+14h],3FDAE147h
    9 00966b1c c7442410e17a14ae mov     dword ptr [esp+10h],0AE147AE1h
   10 00966b24 89442408        mov     dword ptr [esp+8],eax
   10 00966b28 8d44241c        lea     eax,[esp+1Ch]
   10 00966b2c 891424          mov     dword ptr [esp],edx
   10 00966b2f 89442404        mov     dword ptr [esp+4],eax
   10 00966b33 e865a8ffff      call    t!ILT+920(?barFooQAEXPAH0PANZ)
(0096139d)
   10 00966b38 83ec0c          sub     esp,0Ch

I imagine there must be a way to indicate that a function is callee-cleanup,
and that would fix the bug when PUSH is used. However, once we do that, we'll
break the cases where we don't use PUSH. That optimization doesn't fire 100% of
the time.</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>