>From one of the examples from http://embed.cs.utah.edu/embarrassing/dec_09/harvest/gcc-head_llvm-gcc-head/
struct _fat_ptr { unsigned char *curr; unsigned char *base; unsigned char *last_plus_one; }; int Cyc_string_ungetc (int ignore, struct _fat_ptr *sptr); int Cyc_string_ungetc (int ignore, struct _fat_ptr *sptr) { struct _fat_ptr *_T0; struct _fat_ptr *_T1; struct _fat_ptr _T2; int _T3; struct _fat_ptr _ans; int _change; { _T0 = sptr; _T1 = sptr; _T2 = *sptr; _T3 = -1; _ans = _T2; _change = -1; _ans.curr += 4294967295U; *sptr = _ans; return (0); } } Testing on GCC: (GNU) 4.5.0 20091219 With -O2 this generates only midly inefficient code (although still a bit larger than llvm's very neat 8b 44 24 08 mov 0x8(%esp),%eax 4: ff 08 decl (%eax) 6: 31 c0 xor %eax,%eax 8: c3 ret ) -O2 code: subl $32, %esp movl 40(%esp), %eax movl (%eax), %edx subl $1, %edx movl %edx, (%eax) xorl %eax, %eax addl $32, %esp ret That's a bit dumb because it allocates stack without using it and also does not use a subl $1,(eax), but explicit load-modify-store, but not overly bad (I'll open a separate bug for the load/modify/store) But with -Os the code is really bad: pushl %edi movl $3, %ecx pushl %esi subl $32, %esp movl 48(%esp), %eax leal 20(%esp), %edi movl %eax, %esi rep movsl leal 8(%esp), %edi leal 20(%esp), %esi movl (%eax), %edx movb $3, %cl rep movsl leal 8(%esp), %esi movl %eax, %edi decl %edx movb $3, %cl rep movsl movl %edx, (%eax) addl $32, %esp xorl %eax, %eax popl %esi popl %edi ret It doesn't modify the object in place, but instead copies it around. Unsurprisingly that generates that much larger (and slower code) -- Summary: -Os not modifying memory object in place Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: andi-gcc at firstfloor dot org GCC host triplet: x86_64-linux GCC target triplet: x86_64-linux -m32 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42585