<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 --- - invoke of fcn ptr under -O0 isnt correctly restore spilled reg before callq"
href="http://llvm.org/bugs/show_bug.cgi?id=17261">17261</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>invoke of fcn ptr under -O0 isnt correctly restore spilled reg before callq
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>Macintosh
</td>
</tr>
<tr>
<th>OS</th>
<td>MacOS X
</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>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>pfllvmbugz@pnkfx.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>Created <span class=""><a href="attachment.cgi?id=11216" name="attach_11216" title="isolate.invoke.ll: LLVM input using invoke">attachment 11216</a> <a href="attachment.cgi?id=11216&action=edit" title="isolate.invoke.ll: LLVM input using invoke">[details]</a></span>
isolate.invoke.ll: LLVM input using invoke
This bug is an attempt to isolate the problem identified on the Rust project
here:
<a href="https://github.com/mozilla/rust/issues/9129#issuecomment-24510246">https://github.com/mozilla/rust/issues/9129#issuecomment-24510246</a>
Summary bullet points for reproduction:
* It appears to be a problem with `invoke` reloading a spilled call target;
using `call` fixes the problem.
* You need `llc -O0` to see the problem; higher optimization levels mask the
problem.
* This bug report is written based on assembly code analysis, but the problem
was discovered (as you might expect) based on actual crashes of compiled code.
The plot:
I have found a standalone .ll input for which an `invoke` instruction compiles
via `llc` into code that loads from a location on the stack to which no value
has been previously assigned. When I substitute a `call` instruction for the
same spot, `llc` generates code that correctly loads a spilled value from the
stack back into a register in preparation for the call.
I am running llc via command lines like this:
llc -o isolate.invoke.ll.s isolate.invoke.ll -O0 -filetype=asm
In particular, to reproduce the bug, you need to use -O0.
I am running with `llc` compiled from:
"""
commit 107cfa2169299fe67caebe7d1f0d405ce727e420
Author: Tim Northover <<a href="mailto:tnorthover@apple.com">tnorthover@apple.com</a>>
Date: Mon Sep 16 17:33:40 2013 +0000
TableGen: fix constness of new comparison function.
libc++ didn't seem to like a non-const call operator.
git-svn-id: <a href="https://llvm.org/svn/llvm-project/llvm/trunk@190797">https://llvm.org/svn/llvm-project/llvm/trunk@190797</a>
91177308-0d34-0410-b5e6-96231b3b80d8
"""
I have not been able to come up with a C++ program that generates the offending
code. I am hoping that people will be able to see the same problem on their
own systems by inspecting the assembly (as I have been) and then be able to
figure out why `invoke` is not being compiled correctly.
I'm attaching four files: two are the input .ll files (one using `call`, and
the other using `invoke`), and the other two are the output .s files.
For ease of reference, I am posting the most relevant bits of generated
assembly here.
The variant that uses the call instruction generates correct machine code that
looks like this (snippet):
## BB#0: ## %function top level
subq $56, %rsp
Ltmp1:
.cfi_def_cfa_offset 64
addq $8, %rdi
movq %rdi, 8(%rsp) ## 8-byte Spill
callq __ZN9breakdown17haf444eb869dbfb724v0.0E
movq %rax, 32(%rsp)
movq 32(%rsp), %rdi
movq 8(%rsp), %rax ## 8-byte Reload
callq *%rax
In particular, the spill and reload are both referring to the same stack
location, `8(%rsp)`
Conversely, the code that is generated from using `invoke` looks like this:
## BB#0: ## %function top level
subq $88, %rsp
Ltmp4:
.cfi_def_cfa_offset 96
addq $8, %rdi
Ltmp0:
movq %rdi, 40(%rsp) ## 8-byte Spill
callq __ZN9breakdown17haf444eb869dbfb724v0.0E
Ltmp1:
movq %rax, 32(%rsp) ## 8-byte Spill
jmp LBB1_1
LBB1_1: ## %normal return
movq 32(%rsp), %rax ## 8-byte Reload
movq %rax, 64(%rsp)
movq 64(%rsp), %rdi
movq 24(%rsp), %rcx ## 8-byte Reload
callq *%rcx
Note that the reload that establishes %rcx is coming from `24(%rsp)`, a stack
location that has not been established by any register spills.
(Note: The attached code is only meant to illustrate incorrect assembly+machine
code generation; it is the result of me iteratively reducing an initial
function from the Rust bug linked above until I came up with something small
enough for reasonable submission, i.e. <50 lines. But it does not run on its
own, and at this point I removed so much of the original computation that it
almost certainly would break if you did actually run it.)</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>