[LLVMbugs] [Bug 16326] New: Bad register allocation compiling GCC inline assembly (ARM)

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Thu Jun 13 17:46:39 PDT 2013


http://llvm.org/bugs/show_bug.cgi?id=16326

            Bug ID: 16326
           Summary: Bad register allocation compiling GCC inline assembly
                    (ARM)
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: Backend: ARM
          Assignee: unassignedbugs at nondot.org
          Reporter: lennox at cs.columbia.edu
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Created attachment 10677
  --> http://llvm.org/bugs/attachment.cgi?id=10677&action=edit
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

-- 
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/20130614/a456b8a1/attachment.html>


More information about the llvm-bugs mailing list