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