This is a general m68k code generation regression. Starting with revision
150588 GCC for m68k generates "surprising" code for auto increments, eg.
for a strlcpy implementation. Compiling this code with the 4.5.0 snapshot
from 20100107 yields:

-- 4.5.0 --
_strlcpy:
        movel d3,s...@-
        movel d2,s...@-
        movel sp@(16),d0
        movel sp@(20),d1
        jeq L7
        movel d0,a0
        movel sp@(12),a1
L3:
        movel a0,d2
        subql #1,d1
        jeq L11
        moveb a...@+,d2
        moveb d2,a...@+
        movel a0,d3 | <--
        tstb d2     | <--
        jne L3
L4:
        subl d3,d0
        notl d0
        movel s...@+,d2
        movel s...@+,d3
        rts
L7:
        movel d0,d2
        movel d2,a0
L6:
        moveb a...@+,d1
        movel a0,d3 | <--
        tstb d1     | <--
        jeq L4
        moveb a...@+,d1
        movel a0,d3 | <--
        tstb d1     | <--
        jne L6
        jra L4
L11:
        clrb a1@
        movel d2,a0
        jra L6
-- cut --

Suddenly GCC inserts "useless" moves and because of these moves has also
to generate explicit tst instructions. Older GCC versions generated better
code by using tst.b incrementing an address register without extra move
instructions, i.e. 4.4.0:

-- 4.4.0 (release) --
_strlcpy:
        movel d2,s...@-
        movel sp@(8),a1
        movel sp@(12),d0
        movel sp@(16),d1
        jne L2
        movel d0,a0
L8:
        tstb a...@+
        jne L8
L5:
        subl a0,d0
        notl d0
        movel s...@+,d2
        rts
L2:
        movel d0,a0
        subql #1,d1
        jeq L11
L6:
        moveb a...@+,d2
        moveb d2,a1@
        jeq L5
        addql #1,a1
        subql #1,d1
        jne L6
L11:
        clrb a1@
        tstb a...@+
        jne L8
        jra L5
-- cut --

Environment:
System: FreeBSD 6.3-STABLE #0: Sat Mar 1 11:12:32 CET 2008
r...@sirius:/usr/obj/usr/src/sys/SIRIUS i386

host: i386-unknown-freebsd6.3
build: i386-unknown-freebsd6.3
target: m68k-unknown-amigaos
configured with: ../gcc-4.5-gg/configure --disable-nls --disable-libssp
--enable-languages=c --with-gmp=/usr/local --disable-tls --target=m68k-amigaos

How-To-Repeat:
Compiling the following code with

  gcc-4.5.0 -O2 -fomit-frame-pointer strlcpy.c -o -

demonstrates the problem. FWIW, m68k-elf exhibits the very same problem!

-- cut --
typedef unsigned long size_t;
size_t
strlcpy(char *dst, const char *src, size_t n)
{ const char *s = src;
  if (n) {
    while (--n)
      if ((*dst++ = *s++) == '\0')
        goto out;
    *dst = '\0';
  }
  while (*s++ != '\0')
    continue;
out:
   return ~(src - s);
}
-- cut --


------- Comment #1 from gnikl at users dot sourceforge dot net  2010-01-25 
19:34 -------
Fix:
Reverting rev 150588 restores the previous behaviour.


-- 
           Summary: [4.5] Regression whith auto increments
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: gnikl at users dot sourceforge dot net
 GCC build triplet: i386-unknown-freebsd6.3
  GCC host triplet: i386-unknown-freebsd6.3
GCC target triplet: m68k-unknown-amigaos


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

Reply via email to