Consider:

char buf[128];

extern void bar (int a, const char *p);
extern char *strcpy (char *, const char *);

void
foo (int a)
{
  if (a)
    bar (0, buf);
  strcpy (buf, "0123456789abcdefghijklmnopqrstuvwxyz");
  bar (0, buf);
}

Compile this testcase with arm-none-linux-gnueabi-4.4.

strcpy above is inlined and unrolled like so:

        ldmia   r4!, {r0, r1, r2, r3}
        stmia   ip!, {r0, r1, r2, r3}
        ldmia   r4!, {r0, r1, r2, r3}
        stmia   ip!, {r0, r1, r2, r3}
        ldmia   r4, {r0, r1}
        str     r0, [ip], #4
        mov     r1, ip
        strb    r1, [r1], #-36

Notice that the last instruction looks strange.  R1 immediately after
the last ldmia contains the last character, namely the null
terminator, but that gets destroyed in "mov r1, ip".  Then strb
attempts to write r1 to the memory location pointed to by r1, which
doesn't make sense.

The last instruction comes from auto-inc-dec.c.

I've got a patch in testing.


-- 
           Summary: auto-inc-dec generates an invalid assembly instruction
           Product: gcc
           Version: 4.4.4
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: kazu at gcc dot gnu dot org
        ReportedBy: kazu at gcc dot gnu dot org
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: arm-none-linux-gnueabi


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

Reply via email to