Bug 9226

Summary: GCSE breaking argument passing
Product: gcc Reporter: Andreas Schwab <schwab>
Component: rtl-optimizationAssignee: Richard Henderson <rth>
Status: RESOLVED FIXED    
Severity: critical CC: gcc-bugs
Priority: P2 Keywords: wrong-code
Version: 3.4.0   
Target Milestone: 3.4.0   
Host: ia64-unknown-linux-gnu Target: m68k-unknown-linux-gnu
Build: ia64-unknown-linux-gnu Known to work:
Known to fail: Last reconfirmed:

Description Andreas Schwab 2003-01-08 06:26:01 UTC
GCSE is replacing references to the stack pointer by a different register
during argument passing.

Before GCSE:

(insn 24 23 28 0 0x2000000002410840 (set (reg/v/f:SI 36)
        (reg/f:SI 15 %sp)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 28 24 29 0 0x2000000002410840 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
        (reg/v:SI 33)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 29 28 30 0 0x2000000002410840 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
        (reg/v/f:SI 29)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 30 29 31 0 0x2000000002410840 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
        (reg/v/f:SI 36)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 31 30 32 0 0x2000000002410840 (set (reg/f:SI 44)
        (symbol_ref:SI ("memcpy"))) 29 {*m68k.md:978} (nil)
    (expr_list:REG_EQUAL (symbol_ref:SI ("memcpy"))
        (nil)))

After GCSE:

(insn 24 23 28 0 0x2000000002410840 (set (reg/v/f:SI 36)
        (reg/f:SI 15 %sp)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 28 24 29 0 0x2000000002410840 (set (mem/f:SI (pre_dec:SI (reg/f:SI 15 %sp)) [0 S4 A16])
        (reg/v:SI 33)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 29 28 30 0 0x2000000002410840 (set (mem/f:SI (pre_dec:SI (reg/v/f:SI 36)) [0 S4 A16])
        (reg/v/f:SI 29)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 30 29 31 0 0x2000000002410840 (set (mem/f:SI (pre_dec:SI (reg/v/f:SI 36)) [0 S4 A16])
        (reg/v/f:SI 36)) 29 {*m68k.md:978} (nil)
    (nil))

(insn 31 30 32 0 0x2000000002410840 (set (reg/f:SI 44)
        (symbol_ref:SI ("memcpy"))) 29 {*m68k.md:978} (nil)
    (expr_list:REG_EQUAL (symbol_ref:SI ("memcpy"))
        (nil)))

(reg 36) is not a valid replacement for (reg 15).

Release:
3.4 20030107 (experimental)

Environment:
System: Linux sykes 2.4.19-SMP #1 SMP Wed Dec 11 22:55:37 UTC 2002 ia64 unknown unknown GNU/Linux
Architecture: ia64

	
host: ia64-unknown-linux-gnu
build: ia64-unknown-linux-gnu
target: m68k-unknown-linux-gnu
configured with: /cvs/gcc/configure --with-gcc-version-trigger=/cvs/gcc/gcc/version.c --host=ia64-unknown-linux --target=m68k-linux --prefix=/usr/local/m68k-linux --enable-languages=c++ --with-ld=/usr/local/m68k-linux/m68k-linux/bin/ld --with-as=/usr/local/m68k-linux/m68k-linux/bin/as --enable-shared

How-To-Repeat:
$ cat alloca.c
typedef unsigned int size_t;
void *memcpy (void *__restrict, const void *__restrict, size_t);
size_t strlen (const char *);
int printf (const char *, ...);
# define strdupa(s)							      \
  (__extension__							      \
    ({									      \
      __const char *__old = (s);					      \
      size_t __len = strlen (__old) + 1;				      \
      char *__new = (char *) __builtin_alloca (__len);			      \
      (char *) memcpy (__new, __old, __len);				      \
    }))

void
foo (const char *x)
{
  size_t nx;
  char *y = strdupa (x);
  nx = 1;
  while (*y)
    {
      if (*y == ':' || *y == ';')
	++nx;
      y++;
    }
  printf ("%s %zu", y, nx);
}
$ m68k-linux-gcc -S -O2 alloca.c
Comment 1 Richard Henderson 2003-02-07 23:03:04 UTC
Responsible-Changed-From-To: unassigned->rth
Responsible-Changed-Why: .
Comment 2 Richard Henderson 2003-02-07 23:03:04 UTC
State-Changed-From-To: open->closed
State-Changed-Why: http://gcc.gnu.org/ml/gcc-patches/2003-02/msg00373.html