public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: optimization/6065: gcc seems to reorder IEEE fpsetsticky and sqrt functions
@ 2002-03-27 9:56 Daniel Villeneuve
0 siblings, 0 replies; 2+ messages in thread
From: Daniel Villeneuve @ 2002-03-27 9:56 UTC (permalink / raw)
To: nobody; +Cc: gcc-prs
The following reply was made to PR optimization/6065; it has been noted by GNATS.
From: Daniel Villeneuve <Daniel.Villeneuve@gerad.ca>
To: gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org,
nobody@gcc.gnu.org, Daniel.Villeneuve@gerad.ca
Cc:
Subject: Re: optimization/6065: gcc seems to reorder IEEE fpsetsticky and sqrt
functions
Date: Wed, 27 Mar 2002 12:47:38 -0500
This is a multi-part message in MIME format.
--------------3B0C834164807D03C8631D29
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Here is a trimmed down version of the bug report optimization/6065.
The compilation command is shorter, the C code is simpler.
>Submitter-Id: net
>Originator: Daniel Villeneuve
>Organization:
>Confidential: no
>Synopsis: gcc seems to reorder IEEE fpsetsticky and sqrt functions
>Severity: serious
>Priority: medium
>Category: optimization
>Class: wrong-code
>Release: 3.0.3
>Environment:
System: SunOS mckinley 5.7 Generic_106541-05 sun4u sparc
SUNW,Ultra-5_10
Architecture: sun4
host: sparc-sun-solaris2.7
build: sparc-sun-solaris2.7
target: sparc-sun-solaris2.7
configured with: ./configure --disable-shared
--prefix=/home/sparc-sun-solaris2/gcc-3.0.3
>Description:
When compiling with -O2 or higher, gcc seems to move the call to
sqrt()
outside the bracketing function pair fpsetsticky()/fpgetsticky(),
making
the result of fpgetsticky incorrect.
>How-To-Repeat:
Compile the file t_sqrt.c into an executable named t_sqrt, then try:
./t_sqrt 2
whose output ought to be
res = 1.41421, inexact flag = 1
but is
res = 1.41421, inexact flag = 0
.
When compiling with -DVOLATILE, the local double variable is declared
as
volatile and the code works correctly, even with -O2 or -O3.
>Fix:
Declare as volatile all floating-point variables used in computations
that
might affect IEEE status flags (when we want to access those flags, of
course). I am not sure this is always correct: it happened to work on
my
restricted test case.
I am aware that C99 provides the FENV_ACCESS pragma and
the fe(clear|test)except functions, but they are still
not widely available and I would like a portable solution
if possible.
Is there a better way (compiler options, pragmas, attributes) than
using
`volatile' to tell gcc not to `over'-optimize the code in such
specific
circumstances?
--
Daniel Villeneuve
GERAD/University of Montreal
--------------3B0C834164807D03C8631D29
Content-Type: text/plain; charset=us-ascii;
name="t_sqrt.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="t_sqrt.c"
#include <ieeefp.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
typedef struct S
{
double d;
int i;
} S;
static void Sqrt(S *ps)
{
#ifdef VOLATILE
double volatile d;
#else
double d;
#endif
int i;
d = ps->d, i = ps->i;
fpsetsticky(0);
d = sqrt(d);
if( fpgetsticky() & FP_X_IMP ) i = 1;
ps->d = d, ps->i = i;
}
int main(int argc, char **argv)
{
S ps[1];
ps->d = atof(argv[1]);
ps->i = 0;
Sqrt(ps);
printf("res = %g, inexact flag = %d\n", ps->d, ps->i);
return 0;
}
--------------3B0C834164807D03C8631D29
Content-Type: text/plain; charset=us-ascii;
name="t_sqrt.i"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="t_sqrt.i"
# 1 "t_sqrt.c"
# 1 "/usr/include/ieeefp.h" 1 3
# 19 "/usr/include/ieeefp.h" 3
#pragma ident "@(#)ieeefp.h 1.15 97/11/22 SMI"
# 64 "/usr/include/ieeefp.h" 3
typedef enum fpclass_t {
FP_SNAN = 0,
FP_QNAN = 1,
FP_NINF = 2,
FP_PINF = 3,
FP_NDENORM = 4,
FP_PDENORM = 5,
FP_NZERO = 6,
FP_PZERO = 7,
FP_NNORM = 8,
FP_PNORM = 9
} fpclass_t;
extern fpclass_t fpclass(double);
extern int finite(double);
extern int unordered(double, double);
# 113 "/usr/include/ieeefp.h" 3
typedef enum fp_rnd {
FP_RN = 0,
FP_RZ = 1,
FP_RP = 2,
FP_RM = 3
} fp_rnd;
extern fp_rnd fpsetround(fp_rnd);
extern fp_rnd fpgetround(void);
# 191 "/usr/include/ieeefp.h" 3
extern int fpgetmask(void);
extern int fpsetmask(int);
extern int fpgetsticky(void);
extern int fpsetsticky(int);
# 209 "/usr/include/ieeefp.h" 3
extern int isnanf(float);
extern int isnand(double);
# 2 "t_sqrt.c" 2
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 1 3
# 27 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 3
#pragma ident "@(#)math.h 2.7 98/01/27"
# 46 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 3
typedef union _h_val {
unsigned long _i[sizeof(double) / sizeof(unsigned long)];
double _d;
} _h_val;
extern const _h_val __huge_val;
# 134 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 3
extern double acos (double);
extern double asin (double);
extern double atan (double);
extern double atan2 (double, double);
extern double cos (double);
extern double sin (double);
extern double tan (double);
extern double cosh (double);
extern double sinh (double);
extern double tanh (double);
extern double exp (double);
extern double frexp (double, int *);
extern double ldexp (double, int);
extern double log (double);
extern double log10 (double);
extern double modf (double, double *);
extern double pow (double, double);
extern double sqrt (double);
extern double ceil (double);
extern double fabs (double);
extern double floor (double);
extern double fmod (double, double);
# 3 "t_sqrt.c" 2
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 1 3
# 25 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
#pragma ident "@(#)stdlib.h 1.44 98/01/22 SMI"
# 1 "/usr/include/sys/feature_tests.h" 1 3
# 13 "/usr/include/sys/feature_tests.h" 3
#pragma ident "@(#)feature_tests.h 1.17 97/12/04 SMI"
# 1 "/usr/include/sys/isa_defs.h" 1 3
# 9 "/usr/include/sys/isa_defs.h" 3
#pragma ident "@(#)isa_defs.h 1.15 97/11/22 SMI"
# 16 "/usr/include/sys/feature_tests.h" 2 3
# 28 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 2 3
# 38 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef struct {
int quot;
int rem;
} div_t;
typedef struct {
long quot;
long rem;
} ldiv_t;
# 66 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef unsigned int size_t;
# 77 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef long uid_t;
# 107 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef long int wchar_t;
# 148 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
extern unsigned char __ctype[];
extern double atof(const char *);
extern int atoi(const char *);
extern long int atol(const char *);
extern double strtod(const char *, char **);
extern long int strtol(const char *, char **, int);
extern unsigned long int strtoul(const char *, char **, int);
extern int rand(void);
extern void srand(unsigned int);
extern void *calloc(size_t, size_t);
extern void free(void *);
extern void *malloc(size_t);
extern void *realloc(void *, size_t);
extern void abort(void);
extern int atexit(void (*)(void));
extern void exit(int);
extern void _exithandle(void);
extern char *getenv(const char *);
extern int system(const char *);
extern void *bsearch(const void *, const void *, size_t, size_t,
int (*)(const void *, const void *));
extern void qsort(void *, size_t, size_t,
int (*)(const void *, const void *));
extern int abs(int);
extern div_t div(int, int);
extern long int labs(long);
extern ldiv_t ldiv(long, long);
extern int mbtowc(wchar_t *, const char *, size_t);
extern int mblen(const char *, size_t);
extern int wctomb(char *, wchar_t);
extern size_t mbstowcs(wchar_t *, const char *, size_t);
extern size_t wcstombs(char *, const wchar_t *, size_t);
# 219 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
extern int mkstemp(char *);
# 4 "t_sqrt.c" 2
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 1 3
# 14 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdarg.h" 1 3
# 43 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdarg.h" 3
typedef __builtin_va_list __gnuc_va_list;
# 15 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 34 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
#pragma ident "@(#)stdio.h 1.69 98/07/13 SMI"
# 1 "/usr/include/sys/feature_tests.h" 1 3
# 37 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 1 "/usr/include/sys/va_list.h" 1 3
# 9 "/usr/include/sys/va_list.h" 3
#pragma ident "@(#)va_list.h 1.11 97/11/22 SMI"
# 26 "/usr/include/sys/va_list.h" 3
typedef void *__va_list;
# 38 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 1 "/usr/include/stdio_tag.h" 1 3
# 9 "/usr/include/stdio_tag.h" 3
#pragma ident "@(#)stdio_tag.h 1.3 98/04/20 SMI"
# 21 "/usr/include/stdio_tag.h" 3
typedef struct __FILE __FILE;
# 39 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 1 "/usr/include/stdio_impl.h" 1 3
# 9 "/usr/include/stdio_impl.h" 3
#pragma ident "@(#)stdio_impl.h 1.7 98/04/17 SMI"
# 1 "/usr/include/sys/isa_defs.h" 1 3
# 12 "/usr/include/stdio_impl.h" 2 3
# 22 "/usr/include/stdio_impl.h" 3
typedef int ssize_t;
# 38 "/usr/include/stdio_impl.h" 3
struct __FILE
{
ssize_t _cnt;
unsigned char *_ptr;
unsigned char *_base;
unsigned char _flag;
unsigned char _file;
unsigned __orientation:2;
unsigned __filler:6;
};
# 40 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 55 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
typedef __FILE FILE;
# 103 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
typedef long fpos_t;
# 203 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern FILE __iob[20];
# 215 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern unsigned char _sibuf[], _sobuf[];
# 244 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern unsigned char *_bufendtab[];
extern FILE *_lastbuf;
# 275 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern int remove(const char *);
extern int rename(const char *, const char *);
extern FILE *tmpfile(void);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern void setbuf(FILE *, char *);
extern int setvbuf(FILE *, char *, int, size_t);
extern int fprintf(FILE *, const char *, ...);
extern int fscanf(FILE *, const char *, ...);
extern int printf(const char *, ...);
extern int scanf(const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int sscanf(const char *, const char *, ...);
extern int vfprintf(FILE *, const char *, __gnuc_va_list);
extern int vprintf(const char *, __gnuc_va_list);
extern int vsprintf(char *, const char *, __gnuc_va_list);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(FILE *, long, int);
extern int fsetpos(FILE *, const fpos_t *);
extern long ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);
extern int __filbuf(FILE *);
extern int __flsbuf(int, FILE *);
# 5 "t_sqrt.c" 2
typedef struct S
{
double d;
int i;
} S;
static void Sqrt(S *ps)
{
double d;
int i;
d = ps->d, i = ps->i;
fpsetsticky(0);
d = sqrt(d);
if( fpgetsticky() & 0x01 ) i = 1;
ps->d = d, ps->i = i;
}
int main(int argc, char **argv)
{
S ps[1];
ps->d = atof(argv[1]);
ps->i = 0;
Sqrt(ps);
printf("res = %g, inexact flag = %d\n", ps->d, ps->i);
return 0;
}
--------------3B0C834164807D03C8631D29
Content-Type: text/plain; charset=us-ascii;
name="Makefile"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="Makefile"
t_sqrt: t_sqrt.c
gcc -v -save-temps -ansi -O2 -o t_sqrt t_sqrt.c -lm
# gcc -DVOLATILE -v -save-temps -ansi -O2 -o t_sqrt t_sqrt.c -lm
clean:
rm -f t_sqrt t_sqrt.[ois]
--------------3B0C834164807D03C8631D29
Content-Type: text/plain; charset=us-ascii;
name="t_sqrt.s"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="t_sqrt.s"
.file "t_sqrt.i"
.section ".text"
.align 4
.type Sqrt,#function
.proc 020
Sqrt:
!#PROLOGUE# 0
save %sp, -128, %sp
!#PROLOGUE# 1
ldd [%i0], %o0
std %o0, [%fp-24]
ldd [%fp-24], %f2
mov 0, %o0
fsqrtd %f2, %f2
ld [%i0+8], %l0
call fpsetsticky, 0
std %f2, [%fp-32]
ldd [%fp-32], %f4
fmovs %f4, %f2
fmovs %f5, %f3
fcmpd %f4, %f2
nop
fbe .LL2
ldd [%fp-24], %o0
call sqrt, 0
nop
std %f0, [%fp-32]
.LL2:
call fpgetsticky, 0
nop
andcc %o0, 1, %g0
bne,a .LL3
mov 1, %l0
.LL3:
ldd [%fp-32], %o0
st %l0, [%i0+8]
std %o0, [%i0]
ret
restore
.LLfe1:
.size Sqrt,.LLfe1-Sqrt
.section ".rodata"
.align 8
.LLC0:
.asciz "res = %g, inexact flag = %d\n"
.section ".text"
.align 4
.global main
.type main,#function
.proc 04
main:
!#PROLOGUE# 0
save %sp, -128, %sp
!#PROLOGUE# 1
ld [%i1+4], %o0
call atof, 0
mov 0, %i0
add %fp, -32, %o0
std %f0, [%fp-32]
call Sqrt, 0
st %g0, [%fp-24]
sethi %hi(.LLC0), %o0
ld [%fp-32], %o1
or %o0, %lo(.LLC0), %o0
ld [%fp-28], %o2
call printf, 0
ld [%fp-24], %o3
ret
restore
.LLfe2:
.size main,.LLfe2-main
.ident "GCC: (GNU) 3.0.3"
--------------3B0C834164807D03C8631D29--
^ permalink raw reply [flat|nested] 2+ messages in thread
* optimization/6065: gcc seems to reorder IEEE fpsetsticky and sqrt functions
@ 2002-03-26 9:46 Daniel Villeneuve
0 siblings, 0 replies; 2+ messages in thread
From: Daniel Villeneuve @ 2002-03-26 9:46 UTC (permalink / raw)
To: gcc-gnats; +Cc: Daniel.Villeneuve
>Number: 6065
>Category: optimization
>Synopsis: gcc seems to reorder IEEE fpsetsticky and sqrt functions
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: wrong-code
>Submitter-Id: net
>Arrival-Date: Tue Mar 26 09:46:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Daniel Villeneuve
>Release: 3.0.3
>Organization:
>Environment:
System: SunOS mckinley 5.7 Generic_106541-05 sun4u sparc SUNW,Ultra-5_10
Architecture: sun4
host: sparc-sun-solaris2.7
build: sparc-sun-solaris2.7
target: sparc-sun-solaris2.7
configured with: ./configure --disable-shared --prefix=/home/sparc-sun-solaris2/gcc-3.0.3
>Description:
I try to access the ``inexact'' status flag after performing a call to
sqrt(), and the result is wrong for sqrt(2.0) (i.e., the inexact flags is
not set) when compiling with gcc -O3.
The program needs two arguments: a double whose square root is to be
computed, and an initial value for the inexact flag (which can be seen
to complete the floating-point value).
Test that fails:
t_sqrt 2 0
which outputs
res = 1.41421, inexact flag = 0
instead of
res = 1.41421, inexact flag = 1
>How-To-Repeat:
======================================== <Makefile>
t_sqrt: t_sqrt.o
gcc -v -save-temps -ansi -Wall -pedantic -Wshadow -Wbad-function-cast -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wpointer-arith -W -Wwrite-strings -O3 -finline-functions -funroll-loops -Wl,-s -Wl,-R/usr/openwin/lib:/usr/dt/lib:/home/ultra-sun-solaris2/gcc-3.0.3/lib -o t_sqrt t_sqrt.o -lm
t_sqrt.o: t_sqrt.c
gcc -v -save-temps -ansi -Wall -pedantic -Wshadow -Wbad-function-cast -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wpointer-arith -W -Wwrite-strings -O3 -finline-functions -funroll-loops -o t_sqrt.o -c t_sqrt.c
======================================== </Makefile>
======================================== <CODE>
#include <ieeefp.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#undef NDEBUG
#include <assert.h>
typedef struct S
{
double d;
int i;
} S;
static S *psSqrt(S *ps)
{
#ifdef VOLATILE
double volatile d;
#else
double d;
#endif
int i;
d = ps->d;
if( !d ) return ps;
assert( d > 0 );
i = ps->i;
fpsetsticky(0);
d = sqrt(d);
if( fpgetsticky() & FP_X_IMP ) i = 1;
ps = malloc(sizeof(S));
ps->d = d;
ps->i = i;
return ps;
}
int main(int argc, char **argv)
{
S psArg[1], *psRes;
assert(argc == 3);
psArg->d = atof(argv[1]);
psArg->i = atoi(argv[2]);
psRes = psSqrt(psArg);
printf("res = %g, inexact flag = %d\n", psRes->d, psRes->i);
return 0;
}
======================================== </CODE>
======================================== <Makefile OUTPUT>
gcc -v -save-temps -ansi -Wall -pedantic -Wshadow -Wbad-function-cast -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wpointer-arith -W -Wwrite-strings -O3 -finline-functions -funroll-loops -o t_sqrt.o -c t_sqrt.c
Reading specs from /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/specs
Configured with: ./configure --disable-shared --prefix=/home/sparc-sun-solaris2/gcc-3.0.3
Thread model: posix
gcc version 3.0.3
/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/cpp0 -lang-c -std=c89 -v -iprefix /home/gencol/ref/gcm-3.0/bin/ultra-sun-solaris2/../lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/ -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=3 -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix -Asystem=unix -Asystem=svr4 -D__OPTIMIZE__ -D__STDC_HOSTED__=1 -Wall -Wshadow -Wbad-function-cast -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wpointer-arith -W -Wwrite-strings -pedantic -D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc t_sqrt.c t_sqrt.i
GNU CPP version 3.0.3 (cpplib) (sparc)
ignoring nonexistent directory "/home/gencol/ref/gcm-3.0/bin/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include"
ignoring nonexistent directory "/home/gencol/ref/gcm-3.0/bin/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/../../../../sparc-sun-solaris2.7/include"
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/home/sparc-sun-solaris2/gcc-3.0.3/sparc-sun-solaris2.7/include"
#include "..." search starts here:
#include <...> search starts here:
/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include
/usr/include
End of search list.
/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/cc1 -fpreprocessed t_sqrt.i -quiet -dumpbase t_sqrt.c -ansi -O3 -Wall -Wshadow -Wbad-function-cast -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wpointer-arith -W -Wwrite-strings -pedantic -ansi -version -finline-functions -funroll-loops -o t_sqrt.s
GNU CPP version 3.0.3 (cpplib) (sparc)
GNU C version 3.0.3 (sparc-sun-solaris2.7)
compiled by GNU C version 3.0.3.
/usr/ccs/bin/as -V -Qy -s -o t_sqrt.o t_sqrt.s
/usr/ccs/bin/as: WorkShop Compilers 5.0 98/12/21
gcc -v -save-temps -ansi -Wall -pedantic -Wshadow -Wbad-function-cast -Wsign-compare -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wpointer-arith -W -Wwrite-strings -O3 -finline-functions -funroll-loops -Wl,-s -Wl,-R/usr/openwin/lib:/usr/dt/lib:/home/ultra-sun-solaris2/gcc-3.0.3/lib -o t_sqrt t_sqrt.o -lm
Reading specs from /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/specs
Configured with: ./configure --disable-shared --prefix=/home/sparc-sun-solaris2/gcc-3.0.3
Thread model: posix
gcc version 3.0.3
/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/collect2 -V -Y P,/usr/ccs/lib:/usr/lib -Qy -o t_sqrt /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/crt1.o /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/crti.o /usr/ccs/lib/values-Xc.o /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/crtbegin.o -L/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3 -L/usr/ccs/bin -L/usr/ccs/lib -L/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/../../.. -s -R/usr/openwin/lib:/usr/dt/lib:/home/ultra-sun-solaris2/gcc-3.0.3/lib t_sqrt.o -lm -lgcc -lc -lgcc /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/crtend.o /home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/crtn.o
ld: Software Generation Utilities - Solaris/ELF (3.0)
======================================== </Makefile OUTPUT>
======================================== <CPP>
# 1 "t_sqrt.c"
# 1 "/usr/include/ieeefp.h" 1 3
# 19 "/usr/include/ieeefp.h" 3
#pragma ident "@(#)ieeefp.h 1.15 97/11/22 SMI"
# 64 "/usr/include/ieeefp.h" 3
typedef enum fpclass_t {
FP_SNAN = 0,
FP_QNAN = 1,
FP_NINF = 2,
FP_PINF = 3,
FP_NDENORM = 4,
FP_PDENORM = 5,
FP_NZERO = 6,
FP_PZERO = 7,
FP_NNORM = 8,
FP_PNORM = 9
} fpclass_t;
extern fpclass_t fpclass(double);
extern int finite(double);
extern int unordered(double, double);
# 113 "/usr/include/ieeefp.h" 3
typedef enum fp_rnd {
FP_RN = 0,
FP_RZ = 1,
FP_RP = 2,
FP_RM = 3
} fp_rnd;
extern fp_rnd fpsetround(fp_rnd);
extern fp_rnd fpgetround(void);
# 191 "/usr/include/ieeefp.h" 3
extern int fpgetmask(void);
extern int fpsetmask(int);
extern int fpgetsticky(void);
extern int fpsetsticky(int);
# 209 "/usr/include/ieeefp.h" 3
extern int isnanf(float);
extern int isnand(double);
# 2 "t_sqrt.c" 2
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 1 3
# 27 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 3
#pragma ident "@(#)math.h 2.7 98/01/27"
# 46 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 3
typedef union _h_val {
unsigned long _i[sizeof(double) / sizeof(unsigned long)];
double _d;
} _h_val;
extern const _h_val __huge_val;
# 134 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/math.h" 3
extern double acos (double);
extern double asin (double);
extern double atan (double);
extern double atan2 (double, double);
extern double cos (double);
extern double sin (double);
extern double tan (double);
extern double cosh (double);
extern double sinh (double);
extern double tanh (double);
extern double exp (double);
extern double frexp (double, int *);
extern double ldexp (double, int);
extern double log (double);
extern double log10 (double);
extern double modf (double, double *);
extern double pow (double, double);
extern double sqrt (double);
extern double ceil (double);
extern double fabs (double);
extern double floor (double);
extern double fmod (double, double);
# 3 "t_sqrt.c" 2
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 1 3
# 14 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdarg.h" 1 3
# 43 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdarg.h" 3
typedef __builtin_va_list __gnuc_va_list;
# 15 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 34 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
#pragma ident "@(#)stdio.h 1.69 98/07/13 SMI"
# 1 "/usr/include/sys/feature_tests.h" 1 3
# 13 "/usr/include/sys/feature_tests.h" 3
#pragma ident "@(#)feature_tests.h 1.17 97/12/04 SMI"
# 1 "/usr/include/sys/isa_defs.h" 1 3
# 9 "/usr/include/sys/isa_defs.h" 3
#pragma ident "@(#)isa_defs.h 1.15 97/11/22 SMI"
# 16 "/usr/include/sys/feature_tests.h" 2 3
# 37 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 1 "/usr/include/sys/va_list.h" 1 3
# 9 "/usr/include/sys/va_list.h" 3
#pragma ident "@(#)va_list.h 1.11 97/11/22 SMI"
# 26 "/usr/include/sys/va_list.h" 3
typedef void *__va_list;
# 38 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 1 "/usr/include/stdio_tag.h" 1 3
# 9 "/usr/include/stdio_tag.h" 3
#pragma ident "@(#)stdio_tag.h 1.3 98/04/20 SMI"
# 21 "/usr/include/stdio_tag.h" 3
typedef struct __FILE __FILE;
# 39 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 1 "/usr/include/stdio_impl.h" 1 3
# 9 "/usr/include/stdio_impl.h" 3
#pragma ident "@(#)stdio_impl.h 1.7 98/04/17 SMI"
# 1 "/usr/include/sys/isa_defs.h" 1 3
# 12 "/usr/include/stdio_impl.h" 2 3
# 22 "/usr/include/stdio_impl.h" 3
typedef int ssize_t;
# 38 "/usr/include/stdio_impl.h" 3
struct __FILE
{
ssize_t _cnt;
unsigned char *_ptr;
unsigned char *_base;
unsigned char _flag;
unsigned char _file;
unsigned __orientation:2;
unsigned __filler:6;
};
# 40 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 2 3
# 55 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
typedef __FILE FILE;
typedef unsigned int size_t;
# 103 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
typedef long fpos_t;
# 203 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern FILE __iob[20];
# 215 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern unsigned char _sibuf[], _sobuf[];
# 244 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern unsigned char *_bufendtab[];
extern FILE *_lastbuf;
# 275 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdio.h" 3
extern int remove(const char *);
extern int rename(const char *, const char *);
extern FILE *tmpfile(void);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern void setbuf(FILE *, char *);
extern int setvbuf(FILE *, char *, int, size_t);
extern int fprintf(FILE *, const char *, ...);
extern int fscanf(FILE *, const char *, ...);
extern int printf(const char *, ...);
extern int scanf(const char *, ...);
extern int sprintf(char *, const char *, ...);
extern int sscanf(const char *, const char *, ...);
extern int vfprintf(FILE *, const char *, __gnuc_va_list);
extern int vprintf(const char *, __gnuc_va_list);
extern int vsprintf(char *, const char *, __gnuc_va_list);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
extern int fgetpos(FILE *, fpos_t *);
extern int fseek(FILE *, long, int);
extern int fsetpos(FILE *, const fpos_t *);
extern long ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);
extern int __filbuf(FILE *);
extern int __flsbuf(int, FILE *);
# 4 "t_sqrt.c" 2
# 1 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 1 3
# 25 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
#pragma ident "@(#)stdlib.h 1.44 98/01/22 SMI"
# 1 "/usr/include/sys/feature_tests.h" 1 3
# 28 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 2 3
# 38 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef struct {
int quot;
int rem;
} div_t;
typedef struct {
long quot;
long rem;
} ldiv_t;
# 77 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef long uid_t;
# 107 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
typedef long int wchar_t;
# 148 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
extern unsigned char __ctype[];
extern double atof(const char *);
extern int atoi(const char *);
extern long int atol(const char *);
extern double strtod(const char *, char **);
extern long int strtol(const char *, char **, int);
extern unsigned long int strtoul(const char *, char **, int);
extern int rand(void);
extern void srand(unsigned int);
extern void *calloc(size_t, size_t);
extern void free(void *);
extern void *malloc(size_t);
extern void *realloc(void *, size_t);
extern void abort(void);
extern int atexit(void (*)(void));
extern void exit(int);
extern void _exithandle(void);
extern char *getenv(const char *);
extern int system(const char *);
extern void *bsearch(const void *, const void *, size_t, size_t,
int (*)(const void *, const void *));
extern void qsort(void *, size_t, size_t,
int (*)(const void *, const void *));
extern int abs(int);
extern div_t div(int, int);
extern long int labs(long);
extern ldiv_t ldiv(long, long);
extern int mbtowc(wchar_t *, const char *, size_t);
extern int mblen(const char *, size_t);
extern int wctomb(char *, wchar_t);
extern size_t mbstowcs(wchar_t *, const char *, size_t);
extern size_t wcstombs(char *, const wchar_t *, size_t);
# 219 "/home/sparc-sun-solaris2/gcc-3.0.3/lib/gcc-lib/sparc-sun-solaris2.7/3.0.3/include/stdlib.h" 3
extern int mkstemp(char *);
# 5 "t_sqrt.c" 2
# 1 "/usr/include/assert.h" 1 3
# 11 "/usr/include/assert.h" 3
#pragma ident "@(#)assert.h 1.9 92/07/14 SMI"
extern void __assert(const char *, const char *, int);
# 8 "t_sqrt.c" 2
typedef struct S
{
double d;
int i;
} S;
static S *psSqrt(S *ps)
{
double d;
int i;
d = ps->d;
if( !d ) return ps;
(void)((d > 0) || (__assert("d > 0", "t_sqrt.c", 26), 0));
i = ps->i;
fpsetsticky(0);
d = sqrt(d);
if( fpgetsticky() & 0x01 ) i = 1;
ps = malloc(sizeof(S));
ps->d = d;
ps->i = i;
return ps;
}
int main(int argc, char **argv)
{
S psArg[1], *psRes;
(void)((argc == 3) || (__assert("argc == 3", "t_sqrt.c", 41), 0));
psArg->d = atof(argv[1]);
psArg->i = atoi(argv[2]);
psRes = psSqrt(psArg);
printf("res = %g, inexact flag = %d\n", psRes->d, psRes->i);
return 0;
}
======================================== </CPP>
>Fix:
Declare as volatile all ``double'' variables used in computations that
might affect IEEE status flags (when we want to access those flags, of
course). I am not sure this is always correct: it happened to work on my
restricted test case.
I am aware that C99 provides the FENV_ACCESS pragma and
the fe(clear|test)except functions, but they are still
not widely available.
Is there a better way (compiler options, pragmas, attributes) than using
`volatile' to tell gcc not to `over'-optimize the code in such specific
circumstances?
>Release-Note:
>Audit-Trail:
>Unformatted:
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2002-03-27 17:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-03-27 9:56 optimization/6065: gcc seems to reorder IEEE fpsetsticky and sqrt functions Daniel Villeneuve
-- strict thread matches above, loose matches on Subject: below --
2002-03-26 9:46 Daniel Villeneuve
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).