<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 --- - Bad register allocation compiling GCC inline assembly (ARM)"
href="http://llvm.org/bugs/show_bug.cgi?id=16326">16326</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Bad register allocation compiling GCC inline assembly (ARM)
</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>All
</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>Backend: ARM
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>lennox@cs.columbia.edu
</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=10677" name="attach_10677" title="File that (nearly) overloads LLVM's ARM registers.">attachment 10677</a> <a href="attachment.cgi?id=10677&action=edit" title="File that (nearly) overloads LLVM's ARM registers.">[details]</a></span>
File that (nearly) overloads LLVM's ARM registers.
The register allocation to constraints to GCC inline assembly is very poor,
leading to inefficient code, or in extreme cases to compilation failures.
Consider reg-alllocate-small.c (attached).
LLVM generates the following code. Notice the shuffling of values between the
stack and registers before the function.
_foo:
@ BB#0: @ %entry
push {r4, r5, r6, r7, lr}
add r7, sp, #12
push.w {r8, r10, r11}
sub sp, #32
add.w lr, r7, #8
add.w r8, sp, #12
ldm.w lr, {r4, r9, r12, lr}
add.w r10, sp, #16
add.w r11, sp, #20
str.w r12, [sp, #4]
add.w r12, sp, #4
str.w lr, [sp]
add.w lr, sp, #8
add r6, sp, #24
add r5, sp, #28
str.w r9, [sp, #8]
mov r9, sp
str r0, [sp, #28]
str r1, [sp, #24]
str r2, [sp, #20]
str r3, [sp, #16]
str r4, [sp, #12]
@ InlineAsm Start
ldr r0, [r5]
ldr r1, [r0]
ldr r2, [r6]
ldr r3, [r11]
ldr r4, [r10]
add r1, r1, r2
add r1, r1, r3
add r1, r1, r4
ldr r2, [r8]
ldr r3, [lr]
ldr r4, [r12]
add r1, r1, r2
add r1, r1, r3
add r1, r1, r4
ldr r2, [r9]
add r1, r1, r2
str r1, [r0]
@ InlineAsm End
add sp, #32
pop.w {r8, r10, r11}
pop {r4, r5, r6, r7, pc}
gcc-4.2, by contrast, generates:
_foo:
@ args = 16, pretend = 0, frame = 16
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
push {r4}
sub sp, sp, #16
@ lr needed for prologue
str r0, [sp, #12]
str r1, [sp, #8]
str r2, [sp, #4]
str r3, [sp]
ldr r0, [sp, #12]
ldr r1, [r0]
ldr r2, [sp, #8]
ldr r3, [sp, #4]
ldr r4, [sp]
add r1, r1, r2
add r1, r1, r3
add r1, r1, r4
ldr r2, [sp, #20]
ldr r3, [sp, #24]
ldr r4, [sp, #28]
add r1, r1, r2
add r1, r1, r3
add r1, r1, r4
ldr r2, [sp, #32]
add r1, r1, r2
str r1, [r0]
add sp, sp, #16
pop {r4}
bx lr
If we change the inline assembly to add one more register, as in
reg-overload-large.c, LLVM fails to compile the code entirely:
$ clang -O3 -c -arch armv7 -save-temps reg-overload-large.c
reg-overload-large.c:5:4: error: ran out of registers during register
allocation
"ldr r0, %[val]\n\t"
^
1 error generated.
gcc-4.2 also compiles this code perfectly well.
This is clang tip:
clang -v
clang version 3.4 (trunk 183951) (llvm/trunk 183950)
Target: x86_64-apple-darwin12.4.0
Thread model: posix</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>