$ cat test.c int var;
void foo(int enable) { if (enable) var |= 1; else var &= ~1; } $ arm-elf-gcc.exe -O6 -S test.c $ cat test.s .file "test.c" .text .align 2 .global foo .type foo, %function foo: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. cmp r0, #0 ldrne r3, .L4 ldreq r3, .L4 ldrne r2, [r3, #0] ldreq r2, [r3, #0] orrne r2, r2, #1 biceq r2, r2, #1 strne r2, [r3, #0] streq r2, [r3, #0] bx lr .L5: .align 2 .L4: .word var .size foo, .-foo .comm var,4,4 .ident "GCC: (GNU) 4.5.0 20091114 (experimental)" This should be: cmp r0, #0 ldr r3, .L4 ldr r2, [r3, #0] orrne r2, r2, #1 biceq r2, r2, #1 str r2, [r3, #0] bx lr Interestingly -Os eliminates two of the three duplicates: ldr r3, .L5 cmp r0, #0 ldrne r2, [r3, #0] ldreq r2, [r3, #0] orrne r2, r2, #1 biceq r2, r2, #1 str r2, [r3, #0] bx lr Due to inefficient cache use the -Os version will probably execute faster than -O6. This is built with svn revision 154184 -- Summary: missed optimization on ARM Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bruck dot michael at googlemail dot com GCC build triplet: i686-pc-cygwin GCC host triplet: i686-pc-cygwin GCC target triplet: arm-unknown-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42046