[gnu.gcc.bug] Bug in SPARC's structure copying

nfschlen@IDUNNO.PRINCETON.EDU (Norbert Fred Schlenker) (02/16/89)

Environment:  Sun 4/??? running SunOS 4.0

The buggy program (severely excerpted):

  struct hnode {
    int	key;		
    int ip;
  } h[50];

  static
  int entries = 20; 

  void
  copy(void)
  {
    h[1] = h[entries];		/* <--- Note this is an 8 byte structure copy */
  }


GCC's invocation:

  idunno% gcc -v -S bug.c
  gcc version 1.32
   /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ bug.c /tmp/cca08445.cpp
  GNU CPP version 1.32
   /usr/local/lib/gcc-cc1 /tmp/cca08445.cpp -quiet -dumpbase bug.c -version -o bug.s
  GNU C version 1.32 (sparc) compiled by GNU C version 1.32.
  idunno% 


The assembly output:

gcc_compiled.:
.data
	.align 4
_entries:
	.word 20
.text
	.align 4
.global _copy
	.proc 1
_copy:
	!#PROLOGUE# 0
	save %sp,-80,%sp
	!#PROLOGUE# 1
	set _h+8,%o0
	sethi %hi(_entries),%g1
	ld	[%g1+%lo(_entries)],%o1
	set _h,%o2
	sll %o1,3,%o1
	ld [%o2+%o1],%o4		<-- Note that the first word of the structure 
	ld [%o2+%o1],%o5		<-- is copied into two registers and then
	st %o4,[%o0]			<-- summarily stuffed into both words of
	st %o5,[%o0+4]			<-- the target.
L1:
	ret
	restore
.global _h
.common _h,400,"bss"


A couple of further notes:
  - Replacing the variable 'entries' with its constant value results
    in correct code.  Unfortunately, the real program can't afford
    such a luxury.
  - The code for:
	struct hnode { ... } h1, h2; ... h1 = h2;
    is also correct.  Additionally, the two loads and stores are
    replaced by a single ldd/std combination.