A simple function to store a small struct ends up writing the struct to
memory twice unnecessarily (plus writing it for real the third time).

The function's args are passed in r0-r3 (with r1-r3 being the struct).
It compiles to a sequence containing the following loads and stores,
among others:

 [1] stmfd   sp!, {r0, r1, r2, r4, r5}
 [2] stmia   r0, {r1, r2, r3}
 [3] ldmia   r0, {r0, r1, r2}
 [4] stmia   r3, {r0, r1, r2}
 [5] ldmfd   sp!, {r1, r2, r3, r4, r5}

[2] and [3] seem the most egregious. (r0 points to stack space.)
However, [1] and [5] are odd too; I don't know why it's taking the time
to preserve r1-r3. Line [4] is the line that's actually necessary.

Adjusting the optimization level can eliminate the extra saves in [1],[5],
but all optimization levels seem to perform the extra save in [2],[3].

Environment:
System: OpenBSD underhill.hhhh.org 4.4 UNDERHILL#1 i386



host: i386-unknown-openbsd4.4
build: i386-unknown-openbsd4.4
target: arm-none-elf
configured with: ../gcc-4.4.1/configure --with-system-zlib --disable-nls
--target=arm-none-elf --prefix=/usr/local/cross/arm-elf --enable-languages=c
--with-cpu=arm7tdmi --with-newlib --with-gmp=/usr/local --with-mpfr=/usr/local
--with-gnu-as --with-gnu-ld --disable-libssp
--enable-version-specific-runtime-libs

How-To-Repeat:

$ arm-none-elf-gcc -mcpu=arm7tdmi -mthumb-interwork  -Os  -Wa,-alhd  -c 
rstore.c

struct queue {
    unsigned short used;
    struct queue_entry {
        unsigned short aux;
        void (*func)(int);
        int arg;
    } entries[16];
};

void enqueue(struct queue *q, struct queue_entry ent)
{
    q->entries[q->used++] = ent;
}


-- 
           Summary: [ARM] Suboptimal code generated to store a struct
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: wiml at hhhh dot org
 GCC build triplet: i386-unknown-openbsd4.4
  GCC host triplet: i386-unknown-openbsd4.4
GCC target triplet: arm-none-elf


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41021

Reply via email to