[Bug c/37714] New: Sign of sin(-0.0) depends on optimization level
dickinsm at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu Oct 2 09:10:00 GMT 2008
I compiled the code below with:
/opt/local/bin/gcc-mp-4.3 -Wall -O3 -fno-inline main.i
There were no warnings or errors from the compiler. The
result of executing a.out was:
z.imag is 0.000000; expected -0.000000
If the -O3 option is dropped, or -fno-builtin is added, then the output is as
expected:
z.imag is -0.000000; expected -0.000000
It looks as though the twin calls to cos and sin are being optimized to
a single call to (the gcc builtin version of) cexp, and that cexp(-0.0)
incorrectly throws away the sign of the zero. Here's the output
of gcc -v:
Using built-in specs.
Target: i386-apple-darwin9.5.0
Configured with: ../gcc-4.3.2/configure --prefix=/opt/local
--enable-languages=c,c++,objc,obj-c++,java,fortran
--libdir=/opt/local/lib/gcc43 --includedir=/opt/local/include/gcc43
--infodir=/opt/local/share/info --mandir=/opt/local/share/man
--with-local-prefix=/opt/local --with-system-zlib --disable-nls
--program-suffix=-mp-4.3 --with-gxx-include-dir=/opt/local/include/gcc43/c++/
--with-gmp=/opt/local --with-mpfr=/opt/local
Thread model: posix
gcc version 4.3.2 (GCC)
and here are the contents of main.i:
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 64 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/_types.h" 1 3 4
# 27 "/usr/include/_types.h" 3 4
# 1 "/usr/include/sys/_types.h" 1 3 4
# 32 "/usr/include/sys/_types.h" 3 4
# 1 "/usr/include/sys/cdefs.h" 1 3 4
# 33 "/usr/include/sys/_types.h" 2 3 4
# 1 "/usr/include/machine/_types.h" 1 3 4
# 34 "/usr/include/machine/_types.h" 3 4
# 1 "/usr/include/i386/_types.h" 1 3 4
# 37 "/usr/include/i386/_types.h" 3 4
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef short __int16_t;
typedef unsigned short __uint16_t;
typedef int __int32_t;
typedef unsigned int __uint32_t;
typedef long long __int64_t;
typedef unsigned long long __uint64_t;
typedef long __darwin_intptr_t;
typedef unsigned int __darwin_natural_t;
# 70 "/usr/include/i386/_types.h" 3 4
typedef int __darwin_ct_rune_t;
typedef union {
char __mbstate8[128];
long long _mbstateL;
} __mbstate_t;
typedef __mbstate_t __darwin_mbstate_t;
typedef int __darwin_ptrdiff_t;
typedef long unsigned int __darwin_size_t;
typedef __builtin_va_list __darwin_va_list;
typedef int __darwin_wchar_t;
typedef __darwin_wchar_t __darwin_rune_t;
typedef int __darwin_wint_t;
typedef unsigned long __darwin_clock_t;
typedef __uint32_t __darwin_socklen_t;
typedef long __darwin_ssize_t;
typedef long __darwin_time_t;
# 35 "/usr/include/machine/_types.h" 2 3 4
# 34 "/usr/include/sys/_types.h" 2 3 4
# 58 "/usr/include/sys/_types.h" 3 4
struct __darwin_pthread_handler_rec
{
void (*__routine)(void *);
void *__arg;
struct __darwin_pthread_handler_rec *__next;
};
struct _opaque_pthread_attr_t { long __sig; char __opaque[36]; };
struct _opaque_pthread_cond_t { long __sig; char __opaque[24]; };
struct _opaque_pthread_condattr_t { long __sig; char __opaque[4]; };
struct _opaque_pthread_mutex_t { long __sig; char __opaque[40]; };
struct _opaque_pthread_mutexattr_t { long __sig; char __opaque[8]; };
struct _opaque_pthread_once_t { long __sig; char __opaque[4]; };
struct _opaque_pthread_rwlock_t { long __sig; char __opaque[124]; };
struct _opaque_pthread_rwlockattr_t { long __sig; char __opaque[12]; };
struct _opaque_pthread_t { long __sig; struct __darwin_pthread_handler_rec
*__cleanup_stack; char __opaque[596]; };
# 94 "/usr/include/sys/_types.h" 3 4
typedef __int64_t __darwin_blkcnt_t;
typedef __int32_t __darwin_blksize_t;
typedef __int32_t __darwin_dev_t;
typedef unsigned int __darwin_fsblkcnt_t;
typedef unsigned int __darwin_fsfilcnt_t;
typedef __uint32_t __darwin_gid_t;
typedef __uint32_t __darwin_id_t;
typedef __uint64_t __darwin_ino64_t;
typedef __uint32_t __darwin_ino_t;
typedef __darwin_natural_t __darwin_mach_port_name_t;
typedef __darwin_mach_port_name_t __darwin_mach_port_t;
typedef __uint16_t __darwin_mode_t;
typedef __int64_t __darwin_off_t;
typedef __int32_t __darwin_pid_t;
typedef struct _opaque_pthread_attr_t
__darwin_pthread_attr_t;
typedef struct _opaque_pthread_cond_t
__darwin_pthread_cond_t;
typedef struct _opaque_pthread_condattr_t
__darwin_pthread_condattr_t;
typedef unsigned long __darwin_pthread_key_t;
typedef struct _opaque_pthread_mutex_t
__darwin_pthread_mutex_t;
typedef struct _opaque_pthread_mutexattr_t
__darwin_pthread_mutexattr_t;
typedef struct _opaque_pthread_once_t
__darwin_pthread_once_t;
typedef struct _opaque_pthread_rwlock_t
__darwin_pthread_rwlock_t;
typedef struct _opaque_pthread_rwlockattr_t
__darwin_pthread_rwlockattr_t;
typedef struct _opaque_pthread_t
*__darwin_pthread_t;
typedef __uint32_t __darwin_sigset_t;
typedef __int32_t __darwin_suseconds_t;
typedef __uint32_t __darwin_uid_t;
typedef __uint32_t __darwin_useconds_t;
typedef unsigned char __darwin_uuid_t[16];
# 28 "/usr/include/_types.h" 2 3 4
typedef int __darwin_nl_item;
typedef int __darwin_wctrans_t;
typedef unsigned long __darwin_wctype_t;
# 65 "/usr/include/stdio.h" 2 3 4
typedef __darwin_va_list va_list;
typedef __darwin_off_t off_t;
typedef __darwin_size_t size_t;
typedef __darwin_off_t fpos_t;
# 98 "/usr/include/stdio.h" 3 4
struct __sbuf {
unsigned char *_base;
int _size;
};
struct __sFILEX;
# 132 "/usr/include/stdio.h" 3 4
typedef struct __sFILE {
unsigned char *_p;
int _r;
int _w;
short _flags;
short _file;
struct __sbuf _bf;
int _lbfsize;
void *_cookie;
int (*_close)(void *);
int (*_read) (void *, char *, int);
fpos_t (*_seek) (void *, fpos_t, int);
int (*_write)(void *, const char *, int);
struct __sbuf _ub;
struct __sFILEX *_extra;
int _ur;
unsigned char _ubuf[3];
unsigned char _nbuf[1];
struct __sbuf _lb;
int _blksize;
fpos_t _offset;
} FILE;
extern FILE *__stdinp;
extern FILE *__stdoutp;
extern FILE *__stderrp;
# 248 "/usr/include/stdio.h" 3 4
void clearerr(FILE *);
int fclose(FILE *);
int feof(FILE *);
int ferror(FILE *);
int fflush(FILE *);
int fgetc(FILE *);
int fgetpos(FILE * , fpos_t *);
char *fgets(char * , int, FILE *);
FILE *fopen(const char * , const char * );
int fprintf(FILE * , const char * , ...) ;
int fputc(int, FILE *);
int fputs(const char * , FILE * ) __asm("_" "fputs" "$UNIX2003");
size_t fread(void * , size_t, size_t, FILE * );
FILE *freopen(const char * , const char * ,
FILE * ) __asm("_" "freopen" "$UNIX2003");
int fscanf(FILE * , const char * , ...) ;
int fseek(FILE *, long, int);
int fsetpos(FILE *, const fpos_t *);
long ftell(FILE *);
size_t fwrite(const void * , size_t, size_t, FILE * ) __asm("_" "fwrite"
"$UNIX2003");
int getc(FILE *);
int getchar(void);
char *gets(char *);
extern const int sys_nerr;
extern const char *const sys_errlist[];
void perror(const char *);
int printf(const char * , ...) ;
int putc(int, FILE *);
int putchar(int);
int puts(const char *);
int remove(const char *);
int rename (const char *, const char *);
void rewind(FILE *);
int scanf(const char * , ...) ;
void setbuf(FILE * , char * );
int setvbuf(FILE * , char * , int, size_t);
int sprintf(char * , const char * , ...) ;
int sscanf(const char * , const char * , ...) ;
FILE *tmpfile(void);
char *tmpnam(char *);
int ungetc(int, FILE *);
int vfprintf(FILE * , const char * , va_list) ;
int vprintf(const char * , va_list) ;
int vsprintf(char * , const char * , va_list) ;
int asprintf(char **, const char *, ...) ;
int vasprintf(char **, const char *, va_list) ;
char *ctermid(char *);
char *ctermid_r(char *);
FILE *fdopen(int, const char *);
char *fgetln(FILE *, size_t *);
int fileno(FILE *);
void flockfile(FILE *);
const char
*fmtcheck(const char *, const char *);
int fpurge(FILE *);
int fseeko(FILE *, off_t, int);
off_t ftello(FILE *);
int ftrylockfile(FILE *);
void funlockfile(FILE *);
int getc_unlocked(FILE *);
int getchar_unlocked(void);
int getw(FILE *);
int pclose(FILE *);
FILE *popen(const char *, const char *);
int putc_unlocked(int, FILE *);
int putchar_unlocked(int);
int putw(int, FILE *);
void setbuffer(FILE *, char *, int);
int setlinebuf(FILE *);
int snprintf(char * , size_t, const char * , ...) ;
char *tempnam(const char *, const char *) __asm("_" "tempnam" "$UNIX2003");
int vfscanf(FILE * , const char * , va_list) ;
int vscanf(const char * , va_list) ;
int vsnprintf(char * , size_t, const char * , va_list) ;
int vsscanf(const char * , const char * , va_list) ;
FILE *zopen(const char *, const char *, int);
FILE *funopen(const void *,
int (*)(void *, char *, int),
int (*)(void *, const char *, int),
fpos_t (*)(void *, fpos_t, int),
int (*)(void *));
# 371 "/usr/include/stdio.h" 3 4
int __srget(FILE *);
int __svfscanf(FILE *, const char *, va_list) ;
int __swbuf(int, FILE *);
static __inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
# 2 "main.c" 2
# 1 "/usr/include/math.h" 1 3 4
# 28 "/usr/include/math.h" 3 4
# 1 "/usr/include/architecture/i386/math.h" 1 3 4
# 49 "/usr/include/architecture/i386/math.h" 3 4
typedef float float_t;
typedef double double_t;
# 83 "/usr/include/architecture/i386/math.h" 3 4
enum {
_FP_NAN = 1,
_FP_INFINITE = 2,
_FP_ZERO = 3,
_FP_NORMAL = 4,
_FP_SUBNORMAL = 5,
_FP_SUPERNORMAL = 6
};
# 117 "/usr/include/architecture/i386/math.h" 3 4
extern unsigned int __math_errhandling ( void );
# 137 "/usr/include/architecture/i386/math.h" 3 4
extern int __fpclassifyf(float );
extern int __fpclassifyd(double );
extern int __fpclassify (long double);
# 172 "/usr/include/architecture/i386/math.h" 3 4
static __inline__ int __inline_isfinitef (float ) __attribute__
((__always_inline__));
static __inline__ int __inline_isfinited (double ) __attribute__
((__always_inline__));
static __inline__ int __inline_isfinite (long double) __attribute__
((__always_inline__));
static __inline__ int __inline_isinff (float ) __attribute__
((__always_inline__));
static __inline__ int __inline_isinfd (double ) __attribute__
((__always_inline__));
static __inline__ int __inline_isinf (long double) __attribute__
((__always_inline__));
static __inline__ int __inline_isnanf (float ) __attribute__
((__always_inline__));
static __inline__ int __inline_isnand (double ) __attribute__
((__always_inline__));
static __inline__ int __inline_isnan (long double) __attribute__
((__always_inline__));
static __inline__ int __inline_isnormalf (float ) __attribute__
((__always_inline__));
static __inline__ int __inline_isnormald (double ) __attribute__
((__always_inline__));
static __inline__ int __inline_isnormal (long double) __attribute__
((__always_inline__));
static __inline__ int __inline_signbitf (float ) __attribute__
((__always_inline__));
static __inline__ int __inline_signbitd (double ) __attribute__
((__always_inline__));
static __inline__ int __inline_signbit (long double) __attribute__
((__always_inline__));
static __inline__ int __inline_isinff( float __x ) { return
__builtin_fabsf(__x) == __builtin_inff(); }
static __inline__ int __inline_isinfd( double __x ) { return
__builtin_fabs(__x) == __builtin_inf(); }
static __inline__ int __inline_isinf( long double __x ) { return
__builtin_fabsl(__x) == __builtin_infl(); }
static __inline__ int __inline_isfinitef( float __x ) { return __x == __x &&
__builtin_fabsf(__x) != __builtin_inff(); }
static __inline__ int __inline_isfinited( double __x ) { return __x == __x &&
__builtin_fabs(__x) != __builtin_inf(); }
static __inline__ int __inline_isfinite( long double __x ) { return __x == __x
&& __builtin_fabsl(__x) != __builtin_infl(); }
static __inline__ int __inline_isnanf( float __x ) { return __x != __x; }
static __inline__ int __inline_isnand( double __x ) { return __x != __x; }
static __inline__ int __inline_isnan( long double __x ) { return __x != __x; }
static __inline__ int __inline_signbitf( float __x ) { union{ float __f;
unsigned int __u; }__u; __u.__f = __x; return (int)(__u.__u >> 31); }
static __inline__ int __inline_signbitd( double __x ) { union{ double __f;
unsigned int __u[2]; }__u; __u.__f = __x; return (int)(__u.__u[1] >> 31); }
static __inline__ int __inline_signbit( long double __x ){ union{ long double
__ld; struct{ unsigned int __m[2]; short __sexp; }__p; }__u; __u.__ld = __x;
return (int) (((unsigned short) __u.__p.__sexp) >> 15); }
static __inline__ int __inline_isnormalf( float __x ) { float fabsf =
__builtin_fabsf(__x); if( __x != __x ) return 0; return fabsf <
__builtin_inff() && fabsf >= 1.17549435e-38F; }
static __inline__ int __inline_isnormald( double __x ) { double fabsf =
__builtin_fabs(__x); if( __x != __x ) return 0; return fabsf < __builtin_inf()
&& fabsf >= 2.2250738585072014e-308; }
static __inline__ int __inline_isnormal( long double __x ) { long double fabsf
= __builtin_fabsl(__x); if( __x != __x ) return 0; return fabsf <
__builtin_infl() && fabsf >= 3.36210314311209350626e-4932L; }
# 262 "/usr/include/architecture/i386/math.h" 3 4
extern double acos( double );
extern float acosf( float );
extern double asin( double );
extern float asinf( float );
extern double atan( double );
extern float atanf( float );
extern double atan2( double, double );
extern float atan2f( float, float );
extern double cos( double );
extern float cosf( float );
extern double sin( double );
extern float sinf( float );
extern double tan( double );
extern float tanf( float );
extern double acosh( double );
extern float acoshf( float );
extern double asinh( double );
extern float asinhf( float );
extern double atanh( double );
extern float atanhf( float );
extern double cosh( double );
extern float coshf( float );
extern double sinh( double );
extern float sinhf( float );
extern double tanh( double );
extern float tanhf( float );
extern double exp ( double );
extern float expf ( float );
extern double exp2 ( double );
extern float exp2f ( float );
extern double expm1 ( double );
extern float expm1f ( float );
extern double log ( double );
extern float logf ( float );
extern double log10 ( double );
extern float log10f ( float );
extern double log2 ( double );
extern float log2f ( float );
extern double log1p ( double );
extern float log1pf ( float );
extern double logb ( double );
extern float logbf ( float );
extern double modf ( double, double * );
extern float modff ( float, float * );
extern double ldexp ( double, int );
extern float ldexpf ( float, int );
extern double frexp ( double, int * );
extern float frexpf ( float, int * );
extern int ilogb ( double );
extern int ilogbf ( float );
extern double scalbn ( double, int );
extern float scalbnf ( float, int );
extern double scalbln ( double, long int );
extern float scalblnf ( float, long int );
extern double fabs( double );
extern float fabsf( float );
extern double cbrt( double );
extern float cbrtf( float );
extern double hypot ( double, double );
extern float hypotf ( float, float );
extern double pow ( double, double );
extern float powf ( float, float );
extern double sqrt( double );
extern float sqrtf( float );
extern double erf( double );
extern float erff( float );
extern double erfc( double );
extern float erfcf( float );
extern double lgamma( double );
extern float lgammaf( float );
extern double tgamma( double );
extern float tgammaf( float );
extern double ceil ( double );
extern float ceilf ( float );
extern double floor ( double );
extern float floorf ( float );
extern double nearbyint ( double );
extern float nearbyintf ( float );
extern double rint ( double );
extern float rintf ( float );
extern long int lrint ( double );
extern long int lrintf ( float );
extern double round ( double );
extern float roundf ( float );
extern long int lround ( double );
extern long int lroundf ( float );
extern long long int llrint ( double );
extern long long int llrintf ( float );
extern long long int llround ( double );
extern long long int llroundf ( float );
extern double trunc ( double );
extern float truncf ( float );
extern double fmod ( double, double );
extern float fmodf ( float, float );
extern double remainder ( double, double );
extern float remainderf ( float, float );
extern double remquo ( double, double, int * );
extern float remquof ( float, float, int * );
extern double copysign ( double, double );
extern float copysignf ( float, float );
extern double nan( const char * );
extern float nanf( const char * );
extern double nextafter ( double, double );
extern float nextafterf ( float, float );
extern double fdim ( double, double );
extern float fdimf ( float, float );
extern double fmax ( double, double );
extern float fmaxf ( float, float );
extern double fmin ( double, double );
extern float fminf ( float, float );
extern double fma ( double, double, double );
extern float fmaf ( float, float, float );
extern long double acosl(long double);
extern long double asinl(long double);
extern long double atanl(long double);
extern long double atan2l(long double, long double);
extern long double cosl(long double);
extern long double sinl(long double);
extern long double tanl(long double);
extern long double acoshl(long double);
extern long double asinhl(long double);
extern long double atanhl(long double);
extern long double coshl(long double);
extern long double sinhl(long double);
extern long double tanhl(long double);
extern long double expl(long double);
extern long double exp2l(long double);
extern long double expm1l(long double);
extern long double logl(long double);
extern long double log10l(long double);
extern long double log2l(long double);
extern long double log1pl(long double);
extern long double logbl(long double);
extern long double modfl(long double, long double *);
extern long double ldexpl(long double, int);
extern long double frexpl(long double, int *);
extern int ilogbl(long double);
extern long double scalbnl(long double, int);
extern long double scalblnl(long double, long int);
extern long double fabsl(long double);
extern long double cbrtl(long double);
extern long double hypotl(long double, long double);
extern long double powl(long double, long double);
extern long double sqrtl(long double);
extern long double erfl(long double);
extern long double erfcl(long double);
extern long double lgammal(long double);
extern long double tgammal(long double);
extern long double ceill(long double);
extern long double floorl(long double);
extern long double nearbyintl(long double);
extern long double rintl(long double);
extern long int lrintl(long double);
extern long double roundl(long double);
extern long int lroundl(long double);
extern long long int llrintl(long double);
extern long long int llroundl(long double);
extern long double truncl(long double);
extern long double fmodl(long double, long double);
extern long double remainderl(long double, long double);
extern long double remquol(long double, long double, int *);
extern long double copysignl(long double, long double);
extern long double nanl(const char *);
extern long double nextafterl(long double, long double);
extern double nexttoward(double, long double);
extern float nexttowardf(float, long double);
extern long double nexttowardl(long double, long double);
extern long double fdiml(long double, long double);
extern long double fmaxl(long double, long double);
extern long double fminl(long double, long double);
extern long double fmal(long double, long double, long double);
# 507 "/usr/include/architecture/i386/math.h" 3 4
extern double __inf( void );
extern float __inff( void );
extern long double __infl( void );
extern float __nan( void );
extern double j0 ( double );
extern double j1 ( double );
extern double jn ( int, double );
extern double y0 ( double );
extern double y1 ( double );
extern double yn ( int, double );
extern double scalb ( double, double );
# 543 "/usr/include/architecture/i386/math.h" 3 4
extern int signgam;
# 557 "/usr/include/architecture/i386/math.h" 3 4
extern long int rinttol ( double );
extern long int roundtol ( double );
# 568 "/usr/include/architecture/i386/math.h" 3 4
struct exception {
int type;
char *name;
double arg1;
double arg2;
double retval;
};
# 597 "/usr/include/architecture/i386/math.h" 3 4
extern int finite ( double );
extern double gamma ( double );
extern int matherr ( struct exception * );
extern double significand ( double );
extern double drem ( double, double );
# 29 "/usr/include/math.h" 2 3 4
# 3 "main.c" 2
typedef struct {
double real;
double imag;
} my_complex;
static my_complex
c_rect(double phi)
{
my_complex z;
z.real = cos(phi);
z.imag = sin(phi);
return z;
}
int main(void) {
my_complex z;
z = c_rect(-0.0);
printf("z.imag is %f; expected %f\n", z.imag, -0.0);
return 0;
}
--
Summary: Sign of sin(-0.0) depends on optimization level
Product: gcc
Version: 4.3.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: dickinsm at gmail dot com
GCC host triplet: i686-apple-darwin9
GCC target triplet: i686-apple-darwin9
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37714
More information about the Gcc-bugs
mailing list