[LLVMbugs] [Bug 22848] New: ARM irq handlers unnecessarily realigns stack

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun Mar 8 18:43:05 PDT 2015


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

            Bug ID: 22848
           Summary: ARM irq handlers unnecessarily realigns stack
           Product: new-bugs
           Version: 3.6
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: sven.koehler at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

Consider the following C-code:

int* global;
void normal() { *global++ = 1; }
__attribute__((interrupt("IRQ")))
void irq() { *global++ = 1; }
__attribute__((interrupt("FIQ")))
void fiq() { *global++ = 1; }

and take a look at the assembler code obtained via
clang --target=arm-softfloat-eabi -mcpu=arm1136j-s -O2 -S

While LLVM 3.5.0 was generating broken assembler code for the FIQ handler (the
code for the IRQ handler was correct), LLVM 3.6.0 now seems to generate correct
code, but it has a lot of instructions that mess with the fp register and
realigns the stack, even though the stack is never used. Specifically, the code
generated for the FIQ handler looks like this:

fiq:
    push    {r11}
    mov    r11, sp
    sub    sp, sp, #4
    bic    sp, sp, #7
    ldr    r8, .LCPI2_0
    ldr    r9, [r8]
    add    r10, r9, #4
    str    r10, [r8]
    mov    r8, #1
    str    r8, [r9]
    mov    sp, r11
    pop    {r11}
    subs    pc, lr, #4
.LCPI2_0:
    .long    global


The biggest issue here is that all the code around r11 (fp) and sp is
unnecessary as the stack is never used. The optimizer doesn't seem to get rid
of it for some reason. Why decrease sp by #4 and then realign it, using the bic
instruction, if the stack is never used.

I also think that the code does not really need to to push and pop r11, as the
register is a banked register anyway. Like r8, r9, and r10, the FIQ handler
doesn't need to save the value of r11.

For comparison, here's the code generated by gcc:

fiq:
    stmfd    sp!, {r1, r2, r3}
    ldr    r3, .L11
    ldr    r2, [r3, #0]
    mov    r1, #1
    str    r1, [r2], #4
    str    r2, [r3, #0]
    ldmfd    sp!, {r1, r2, r3}
    subs    pc, lr, #4
.L11:
    .word    global

While gcc tends to the wrong registers (r1, r2, and r3 need to be saved while
r8 and above would be banked registers), the code is still more compact than
what llvm generates.

-- 
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/20150309/a95f49e6/attachment.html>


More information about the llvm-bugs mailing list