<html>
<head>
<base href="http://llvm.org/bugs/" />
</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 --- - fast-isel call lowering bail-out can destroy inalloca arg passing"
href="http://llvm.org/bugs/show_bug.cgi?id=20863">20863</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>fast-isel call lowering bail-out can destroy inalloca arg passing
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</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>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>LLVM Codegen
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>hans@chromium.org
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>To reproduce:
$ clang -cc1 -triple i686-pc-win32 -O0 -S -o - a.cc
struct S {
~S();
int x;
};
__declspec(dllimport) S g(int, int, int);
void f(S s, int i);
int main() {
f(g(1, 2, 3), 42);
return 0;
}
When lowering the call to g, FastISel will bail out when noticing the dllimport
function address. However, it leaves the arguments pushed on the stack, and we
end up with another set of arguments *pushed on top of the inalloca frame* when
the call is lowered again.
_main:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
subl $28, %esp
movl $1, %eax
movl $2, %ecx
movl $3, %edx
movl $0, -12(%ebp)
movl %esp, %esi
movl $8, %edi
movl %eax, -20(%ebp)
movl %edi, %eax
movl %esi, -24(%ebp)
movl %ecx, -28(%ebp)
movl %edx, -32(%ebp)
calll __chkstk
movl %esp, %eax
andl $-8, %eax
movl %eax, %esp
movl -24(%ebp), %ecx
movl %ecx, -16(%ebp)
subl $16, %esp
movl %eax, (%esp)
movl $1, 4(%esp)
movl $2, 8(%esp)
movl $3, 12(%esp)
subl $16, %esp <-- FastISel has bailed; pushing a frame on top of
inalloca range!
movl %esp, %edx
movl %eax, (%edx)
movl $3, 12(%edx)
movl $2, 8(%edx)
movl $1, 4(%edx)
movl "__imp_?g@@YA?AUS@@HHH@Z", %edx
movl %eax, -36(%ebp)
calll *%edx
addl $16, %esp
movl -36(%ebp), %eax <-- %eax is the inalloca stack
movl $42, 4(%eax) <-- Trying to pass 42 as 2nd argument
calll "?f@@YAXUS@@H@Z" <-- But the inalloca stack isn't on top
anymore!
addl $8, %esp
xorl %eax, %eax
movl -24(%ebp), %ecx
movl %ecx, %esp
leal -8(%ebp), %esp
popl %esi
popl %edi
popl %ebp
retl
When FastISel bails out from a call instruction, maybe it should consult
MachineFrameInfo to see if the function has dynamic allocations, and if so bail
out from fast-isel for the whole basic block?
Or maybe it could just fall back more gracefully, removing the argument pushing
instructions that it generated before falling back to selectiondag-isel.</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>