[Bug tree-optimization/42585] New: -Os not modifying memory object in place

andi-gcc at firstfloor dot org gcc-bugzilla@gcc.gnu.org
Sun Jan 3 05:57:00 GMT 2010


>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



More information about the Gcc-bugs mailing list