Article View: gnu.gcc.bug
Article #2662.1/SPARC -O does preincrement instead of postincrement
From: David Keppel
Date: Wed, 05 Aug 1992 20:04
Date: Wed, 05 Aug 1992 20:04
573 lines
9322 bytes
9322 bytes
Using GCC 2.1 on a SPARC, a fragment such as
switch (*foo++) { ... }
seems to be erroniously compiled in to
switch (*++foo) { ... }
I'm not totally convinced it's a bug, since I don't totally understand
the assembly (why the extra conditional jump before the jump indirect
instead of the original which folded the conditional branch with the
jump indirect?) but what's above is how I understand the code.
I've not trimmed the input.
;-D on ( Bugs? A switch from the usual ) Pardo
% gcc -v -O -S junk.c
Reading specs from /usr/local/gcc-2.1/lib/gcc-lib/sparc-sun-sunos4.1/2.1/specs
gcc version 2.1
/usr/local/gcc-2.1/lib/gcc-lib/sparc-sun-sunos4.1/2.1/cpp -lang-c -v -undef -D__GNUC__=2 -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix -D__OPTIMIZE__ junk.c /usr/tmp/cca15422.i
GNU CPP version 2.1 (sparc)
/usr/local/gcc-2.1/lib/gcc-lib/sparc-sun-sunos4.1/2.1/cc1 /usr/tmp/cca15422.i -quiet -dumpbase junk.c -O -version -o junk.s
GNU C version 2.1 (sparc) compiled by GNU C version 2.1.
TRIMMED ANNOTATED OUTPUT:
_spec_pred:
!#PROLOGUE# 0
save %sp,-112,%sp
!#PROLOGUE# 1
mov %i0,%l0
sethi %hi(_spec_g_cp),%o0
ld [%o0+%lo(_spec_g_cp)],%l1
mov 4,%l3
sethi %hi(L21),%o0
or %o0,%lo(L21),%l2
sethi %hi(LC3),%o0
add %l1,4,%l1 /* Preincrement! */
L26:
ld [%l1],%o0
L25:
cmp %l3,%o0
blu L20
sll %o0,2,%o0
ld [%o0+%l2],%o0
jmp %o0
nop
INPUT C SOURCE:
# 1 "spec.c"
char const spec_rcsid[] = "$Header: /homes/rivers/pardo/home/resch/rtcg/slow/slow/test.d/sort.d/RCS/spec.c,v 1.1 1992/08/04 02:17:38 pardo Exp pardo $";
# 1 "../../includes.d/assert.h" 1 3
void __eprintf (char const *fmt, ...);
# 32 "../../includes.d/assert.h" 3
# 8 "spec.c" 2
# 1 "../../includes.d/malloc.h" 1 3
# 1 "/usr/local/gcc-2.1/lib/gcc-lib/sparc-sun-sunos4.1/2.1/include/sys/stdtypes.h" 1 3
typedef int sigset_t;
typedef unsigned int speed_t;
typedef unsigned long tcflag_t;
typedef unsigned char cc_t;
typedef int pid_t;
typedef unsigned short mode_t;
typedef short nlink_t;
typedef long clock_t;
typedef long time_t;
typedef int size_t;
typedef int ptrdiff_t;
typedef unsigned short wchar_t;
# 7 "../../includes.d/malloc.h" 2 3
struct mallinfo {
int arena;
int ordblks;
int smblks;
int hblks;
int hblkhd;
int usmblks;
int fsmblks;
int uordblks;
int fordblks;
int keepcost;
int mxfast;
int nlblks;
int grain;
int uordbytes;
int allocated;
int treeoverhead;
};
typedef void * malloc_t;
extern malloc_t calloc(size_t nmemb, size_t size);
extern int free(malloc_t ptr);
extern malloc_t malloc(size_t size);
extern malloc_t realloc(malloc_t ptr, size_t size);
extern int mallopt(void);
extern struct mallinfo mallinfo(void);
# 9 "spec.c" 2
# 1 "../../includes.d/stdio.h" 1 3
extern struct _iobuf {
int _cnt;
unsigned char *_ptr;
unsigned char *_base;
int _bufsiz;
short _flag;
char _file;
} _iob[];
extern struct _iobuf *fopen (char const *filename, char const *type);
extern struct _iobuf *fdopen (int fd, char const *type);
extern struct _iobuf *freopen (char const *filename, char const *type, struct _iobuf *fp);
extern struct _iobuf *popen (char const *cmd, char const *type);
extern struct _iobuf *tmpfile (void);
extern long ftell (struct _iobuf const *);
extern char *fgets (char *dst, struct _iobuf *stream);
extern char *gets (char *dst);
extern char *sprintf (char *buf, char const *fmt, ...);
extern char *ctermid (char *buf);
extern char *cuserid (char *buf);
extern char *tempnam (char *dir, char *pfx);
extern char *tmpnam (char *buf);
# 10 "spec.c" 2
# 1 "../../utils.d/decl.h" 1 3
typedef enum bool {
NO=0,
YES
} bool;
typedef void (f_t)(void);
extern int _flsbuf(unsigned char c, void *fp);
extern void abort (void);
extern int atoi (char const *a);
extern void exit (int status);
extern char *mktemp (char *buf);
extern void perror (char const *msg);
extern int system (char const *cmd);
extern int fclose (void *fp);
extern int fputs (char const *str, void *out);
extern int fprintf (void *out, char const *fmt, ...);
extern int printf (char const *fmt, ...);
extern int vfprintf (void *ouit, char const *fmt, void const *args);
extern void qsort (void *base, int nel, int width,
int (*compar)(void const *r1, void const *r2));
extern long random (void);
extern void srandom (int seed);
# 12 "spec.c" 2
# 1 "sort.h" 1
typedef struct sort_t {
int i;
unsigned char uc;
float f;
char const *s;
} sort_t;
typedef enum sort_impl_t {
SORT_IMPL_ERR,
SORT_IMPL_RTCG,
SORT_IMPL_GENI,
SORT_IMPL_SPECI,
SORT_IMPL_OMNI,
SORT_IMPL_COUNT,
SORT_IMPL_N
} sort_impl_t;
typedef enum sort_order_t {
SORT_ORDER_ERR,
SORT_ORDER_INORDER,
SORT_ORDER_CHEAP,
SORT_ORDER_EXPENSIVE,
SORT_ORDER_N
} sort_order_t;
typedef int (sort_cmpf_t)(void const *vs1, void const *vs2);
extern sort_impl_t sort_impl (char const *string_name);
extern sort_order_t sort_order (char const *string_name);
# 14 "spec.c" 2
# 1 "spec.h" 1
extern sort_cmpf_t *spec_sort_pred (sort_order_t whichpred);
# 15 "spec.c" 2
typedef enum spec_field_t {
SPEC_FIELD_ERR,
SPEC_FIELD_I,
SPEC_FIELD_UC,
SPEC_FIELD_F,
SPEC_FIELD_S,
SPEC_FIELD_N
} spec_field_t;
static spec_field_t const spec_fields_cheap[] = {
SPEC_FIELD_I,
SPEC_FIELD_N
};
static spec_field_t const spec_fields_expensive[] = {
SPEC_FIELD_S,
SPEC_FIELD_N
};
static spec_field_t const spec_fields_inorder[] = {
SPEC_FIELD_I,
SPEC_FIELD_UC,
SPEC_FIELD_F,
SPEC_FIELD_S,
SPEC_FIELD_N
};
static spec_field_t const *spec_g_cp;
void spec_padding1 (void);
int spec_pred (void const *v1, void const *v2);
void spec_padding2 (void);
void
spec_padding1 (void)
{
char *t;
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
}
int
spec_pred (void const *v1, void const *v2)
{
sort_t const *f1 = v1;
sort_t const *f2 = v2;
spec_field_t const *cp;
cp = spec_g_cp;
while (1) {
switch (*cp++) {
case SPEC_FIELD_ERR:
do { (void) (((0)) ? 0 : ((__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", "(0)", 99, "spec.c"), abort ()) , 0)) ; } while (0) ;
break;
case SPEC_FIELD_I:
{
int diff;
diff = f2->i - f1->i;
if (diff != 0) {
return (diff);
}
}
break;
case SPEC_FIELD_UC:
{
int diff;
diff = ((int)f2->uc) - ((int)f1->uc);
if (diff != 0) {
return (diff);
}
}
break;
case SPEC_FIELD_F:
{
float fdiff;
fdiff = f2->f - f1->f;
if (fdiff > 0) {
return (1);
} else if (fdiff < 0) {
return (-1);
}
}
break;
case SPEC_FIELD_S:
{
int diff;
diff = strcmp (f1->s, f2->s);
if (diff != 0) {
return (diff);
}
}
break;
case SPEC_FIELD_N:
return (0);
}
}
}
void
spec_padding2 (void)
{
char *t;
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
t = malloc(1);
do { (void) (((0)) ? 0 : ((__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", "(0)", 173, "spec.c"), abort ()) , 0)) ; } while (0) ;
}
sort_cmpf_t *
spec_sort_pred (sort_order_t whichpred)
{
switch (whichpred) {
case SORT_ORDER_INORDER:
spec_g_cp = spec_fields_inorder;
break;
case SORT_ORDER_CHEAP:
spec_g_cp = spec_fields_cheap;
break;
case SORT_ORDER_EXPENSIVE:
spec_g_cp = spec_fields_expensive;
break;
default:
do { (void) (((0)) ? 0 : ((__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", "(0)", 191, "spec.c"), abort ()) , 0)) ; } while (0) ;
spec_padding1();
spec_padding2();
}
return (spec_pred);
}
Technical Details
Message-ID:
<1992Aug5.200442.19236@beaver.cs.washington.edu>Path:
arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!cs.washington.edu!pardoShow Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug Path: arc1-ca.pugleaf.net!sparky!uunet!cis.ohio-state.edu!cs.washington.edu!pardo From: pardo@cs.washington.edu (David Keppel) Subject: 2.1/SPARC -O does preincrement instead of postincrement Message-ID: <1992Aug5.200442.19236@beaver.cs.washington.edu> Sender: gnulists@ai.mit.edu Organization: Computer Science & Engineering, U. of Washington, Seattle Distribution: gnu Date: Wed, 5 Aug 1992 20:04:42 GMT Approved: bug-gcc@prep.ai.mit.edu Lines: 574