Subject: port-sparc/5855: [dM] sparc code-gen bug
To: None <gnats-bugs@gnats.netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: netbsd-bugs
Date: 07/26/1998 12:06:36
>Number:         5855
>Category:       port-sparc
>Synopsis:       [dM] sparc code-gen bug
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 26 09:20:01 1998
>Last-Modified:
>Originator:     der Mouse
>Organization:
	Dis-
>Release:        1.3E
>Environment:
NetBSD Sparkle.Rodents.Montreal.QC.CA 1.3E NetBSD 1.3E (GENERIC) #0: Sun May  3 20:28:50 EDT 1998     mouse@Sparkle.Rodents.Montreal.QC.CA:/big/sources/working-usr-src/sys/arch/sparc/compile/GENERIC sparc
>Description:
	When a function that returns a struct is called twice in the
	same expression, under at least some circumstances the same
	anonymous area is used for both return values.  gcc --version
	reports "2.7.2.2+myc1".
>How-To-Repeat:
	Given the following in z.i, do "gcc -save-temps -g -c -o z.o z.i"
	and examine z.s.  (I actually discovered this when tracking
	down an observed bug; this is a stripped-down version of the .i
	file for the actual code.)  The z.s I get is included below,
	after an excerpt highlighting the problem.

typedef long long int inttype;

typedef struct mufval MUFVAL;
typedef struct string STRING;
typedef struct plist PLIST;
typedef struct word WORD;
typedef struct code CODE;
typedef struct package PACKAGE;
typedef struct thread THREAD;
typedef struct var VAR;
typedef struct fd FD;
typedef struct vec VEC;
typedef struct set SET;
typedef struct mutex MUTEX;
typedef struct intern INTERN;
typedef struct codeptr CODEPTR;
typedef struct regex REGEX;
typedef struct rematch REMATCH;
typedef struct db DB;
typedef struct dbref DBREF;

struct mufval {
  char type;
  union {
    unsigned int b;
    inttype i;
    double f;
    STRING *s;
    PLIST *pl;
    WORD *w;
    CODE *code;
    PACKAGE *p;
    THREAD *t;
    VAR *var;
    FD *fd;
    VEC *vec;
    SET *set;
    MUTEX *m;
    INTERN *in;
    CODEPTR *cp;
    REGEX *re;
    REMATCH *rm;
    DB *db;
    DBREF *dbr;
    } u;
  } ;

extern void chkargs(const char *);
extern const char *db_setsize(DB *, int);
extern MUFVAL dget(int);
extern void ierr(const char *, ...)
	__attribute__((__noreturn__,__format__(__printf__,1,2)));
extern void ddrop(int);
extern void C_db_setsize(void);

void C_db_setsize(void)
{
 const char *err;

 chkargs("Di");
 err = db_setsize(dget(2).u.db,dget(1).u.i);
 if (err) ierr("db-setsize: %s",err);
 ddrop(2);
}

	The problem is with the calls to dget().  Note that the same
	scratch area is used for both calls to dget, without extracting
	the value needed from the first call before making the second.

	add %fp,-32,%o0
	st %o0,[%sp+64]
	mov 2,%o0
	call _dget,0
	nop
	unimp 16
	add %fp,-32,%o0
	st %o0,[%sp+64]
	mov 1,%o0
	call _dget,0
	nop
	unimp 16
	ld [%fp-24],%o0
	ld [%fp-20],%o1
	call _db_setsize,0
	nop

	(On a sun3 machine, the same area is used for both calls, but
	the result of the first call is read before the second call is
	made.  That port has a different bug, though, in that the
	mechanism appears to be non-thread-safe - but the machine in
	question is using an older compiler version.)

	The whole z.s file I get is:

gcc2_compiled.:
___gnu_compiled_c:
.stabs "/big/home/mouse/muck.new/",100,0,0,Ltext0
.stabs "z.i",100,0,0,Ltext0
.text
Ltext0:
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "long long int:t6=r1;01000000000000000000000;0777777777777777777777;",128,0,0,0
.stabs "long long unsigned int:t7=r1;0000000000000;01777777777777777777777;",128,0,0,0
.stabs "short int:t8=r1;-32768;32767;",128,0,0,0
.stabs "short unsigned int:t9=r1;0;65535;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;8;0;",128,0,0,0
.stabs "complex int:t15=s8real:1,0,32;imag:1,32,32;;",128,0,0,0
.stabs "complex float:t16=r16;4;0;",128,0,0,0
.stabs "complex double:t17=r17;8;0;",128,0,0,0
.stabs "complex long double:t18=r18;8;0;",128,0,0,0
.stabs "void:t19=19",128,0,0,0
.stabs "inttype:t6",128,0,1,0
.stabs "MUFVAL:t20=xsmufval:",128,0,3,0
.stabs "STRING:t21=xsstring:",128,0,4,0
.stabs "PLIST:t22=xsplist:",128,0,5,0
.stabs "WORD:t23=xsword:",128,0,6,0
.stabs "CODE:t24=xscode:",128,0,7,0
.stabs "PACKAGE:t25=xspackage:",128,0,8,0
.stabs "THREAD:t26=xsthread:",128,0,9,0
.stabs "VAR:t27=xsvar:",128,0,10,0
.stabs "FD:t28=xsfd:",128,0,11,0
.stabs "VEC:t29=xsvec:",128,0,12,0
.stabs "SET:t30=xsset:",128,0,13,0
.stabs "MUTEX:t31=xsmutex:",128,0,14,0
.stabs "INTERN:t32=xsintern:",128,0,15,0
.stabs "CODEPTR:t33=xscodeptr:",128,0,16,0
.stabs "REGEX:t34=xsregex:",128,0,17,0
.stabs "REMATCH:t35=xsrematch:",128,0,18,0
.stabs "DB:t36=xsdb:",128,0,19,0
.stabs "DBREF:t37=xsdbref:",128,0,20,0
.stabs "mufval:T20=s16type:2,0,8;u:38=u8b:4,0,32;i:6,0,64;f:13,0,64;s:39=*21,0,32;pl:40=*22,0,32;w:41=*23,0,32;code:42=*24,0,32;p:43=*25,0,32;t:44=*26,0,32;var:45=*27,0,32;fd:46=*28,0,32;vec:47=*29,0,32;set:48=*30,0,32;m:49=*31,0,32;in:50=*32,0,32;cp:51=*33,0,32;re:52=*34,0,32;rm:53=*35,0,32;db:54=*36,0,32;dbr:55=*37,0,32;;,64,64;;",128,0,0,0
	.align 8
LC0:
	.ascii "Di\0"
	.align 8
LC1:
	.ascii "db-setsize: %s\0"
	.align 4
	.global _C_db_setsize
	.type	 _C_db_setsize,@function
	.proc	020
_C_db_setsize:
.stabn 68,0,57,LM1
LM1:
	!#PROLOGUE# 0
	save %sp,-128,%sp
	!#PROLOGUE# 1
.stabn 68,0,58,LM2
LM2:
LBB2:
.stabn 68,0,60,LM3
LM3:
	sethi %hi(LC0),%o1
	or %o1,%lo(LC0),%o0
	call _chkargs,0
	nop
.stabn 68,0,61,LM4
LM4:
	add %fp,-32,%o0
	st %o0,[%sp+64]
	mov 2,%o0
	call _dget,0
	nop
	unimp 16
	add %fp,-32,%o0
	st %o0,[%sp+64]
	mov 1,%o0
	call _dget,0
	nop
	unimp 16
	ld [%fp-24],%o0
	ld [%fp-20],%o1
	call _db_setsize,0
	nop
	st %o0,[%fp-12]
.stabn 68,0,62,LM5
LM5:
	ld [%fp-12],%o0
	cmp %o0,0
	be L2
	nop
	sethi %hi(LC1),%o1
	or %o1,%lo(LC1),%o0
	ld [%fp-12],%o1
	call _ierr,0
	nop
L2:
.stabn 68,0,63,LM6
LM6:
	mov 2,%o0
	call _ddrop,0
	nop
.stabn 68,0,64,LM7
LM7:
LBE2:
.stabn 68,0,64,LM8
LM8:
L1:
	ret
	restore
Lfe1:
	.size	 _C_db_setsize,Lfe1-_C_db_setsize
.stabs "C_db_setsize:F19",36,0,57,_C_db_setsize
.stabs "err:56=*2",128,0,58,-12
.stabn 192,0,0,LBB2
.stabn 224,0,0,LBE2

>Fix:
	Check if it's introduced by the myc1 patches, and either fix
	them or push it back to the FSF, depending.
>Audit-Trail:
>Unformatted: