Date: Tue, 6 Oct 1998 13:33:20 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: Kbwms AT aol DOT com, djgpp-workers AT delorie DOT com Subject: Re: Troubles Compiling the Test Programs In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com On Sun, 4 Oct 1998, I wrote: > Can anybody see what's wrong in the latest alpha? Well, I know what's wrong ;-). It's the same GCC optimizations strike again. Here are the offending lines from s_rint.c: w = TWO52[sx]+x; t = w-TWO52[sx]; When GCC sees this, it optimizes w out of existence, and sets t = x. And that is wrong, since this trick reveals the current rounding mode of the FPU, and `rint' really needs that. The following patches correct this and several similar code snippets elsewhere in the library by declaring crucial variables `volatile'. (These changes removed several inaccuracies reported by the Cygnus test suite, so it's probably more here than meets the eye.) *** src/libm/math/s_rint.c~1 Sat Feb 7 14:13:28 1998 --- src/libm/math/s_rint.c Sun Oct 4 19:39:54 1998 *************** TWO52[2]={ *** 44,50 **** { __int32_t i0,j_0,sx; __uint32_t i,i1; ! double w,t; EXTRACT_WORDS(i0,i1,x); sx = (i0>>31)&1; j_0 = ((i0>>20)&0x7ff)-0x3ff; --- 44,55 ---- { __int32_t i0,j_0,sx; __uint32_t i,i1; ! /* w is volatile so GCC doesn't optimize it out of existence ! when it sees that w = x + 2^52 and t = w - 2^52. We need ! that computation unoptimized because it reveals the current ! rounding mode. */ ! volatile double w; ! double t; EXTRACT_WORDS(i0,i1,x); sx = (i0>>31)&1; j_0 = ((i0>>20)&0x7ff)-0x3ff; *** src/libm/math/sf_rint.c~1 Sat Feb 7 14:13:20 1998 --- src/libm/math/sf_rint.c Sun Oct 4 19:39:46 1998 *************** TWO23[2]={ *** 34,40 **** { __int32_t i0,j_0,sx; __uint32_t i,i1; ! float w,t; GET_FLOAT_WORD(i0,x); sx = (i0>>31)&1; j_0 = ((i0>>23)&0xff)-0x7f; --- 34,45 ---- { __int32_t i0,j_0,sx; __uint32_t i,i1; ! /* w is volatile so GCC doesn't optimize it out of existence ! when it sees that w = x + 2^23 and t = w - 2^23. We need ! that computation unoptimized because it reveals the current ! rounding mode. */ ! volatile float w; ! float t; GET_FLOAT_WORD(i0,x); sx = (i0>>31)&1; j_0 = ((i0>>23)&0xff)-0x7f; *** src/libm/math/e_sqrt.c~1 Sat Feb 7 13:47:36 1998 --- src/libm/math/e_sqrt.c Sun Oct 4 19:44:34 1998 *************** static double one = 1.0, tiny=1.0e-300; *** 98,104 **** double x; #endif { ! double z; __int32_t sign = (int)0x80000000U; __uint32_t r,t1,s1,ix1,q1; __int32_t ix0,s0,q,m,t,i; --- 98,104 ---- double x; #endif { ! volatile double z; /* so that GCC will never optimize it away */ __int32_t sign = (int)0x80000000U; __uint32_t r,t1,s1,ix1,q1; __int32_t ix0,s0,q,m,t,i; *** src/libm/math/ef_sqrt.c~1 Sat Feb 7 14:13:24 1998 --- src/libm/math/ef_sqrt.c Sun Oct 4 19:53:42 1998 *************** static float one = 1.0, tiny=1.0e-30; *** 28,34 **** float x; #endif { ! float z; __int32_t sign = (int)0x80000000U; __uint32_t r; __int32_t ix,s,q,m,t,i; --- 28,34 ---- float x; #endif { ! volatile float z; /* to prevent GCC from optimizing it away */ __int32_t sign = (int)0x80000000U; __uint32_t r; __int32_t ix,s,q,m,t,i; *** src/libm/math/s_log1p.c~1 Fri Sep 18 16:44:32 1998 --- src/libm/math/s_log1p.c Sun Oct 4 19:49:52 1998 *************** static double zero = 0.0; *** 153,159 **** double x; #endif { ! double hfsq,f=0.0,c=0.0,s,z,R,u; __int32_t k,hx,hu=0.0,ax; GET_HIGH_WORD(hx,x); --- 153,160 ---- double x; #endif { ! double hfsq,f=0.0,c=0.0,s,z,R; ! volatile double u; /* so GCC never optimizes it away */ __int32_t k,hx,hu=0.0,ax; GET_HIGH_WORD(hx,x); *** src/libm/math/sf_log1p.c~1 Fri Sep 18 16:52:44 1998 --- src/libm/math/sf_log1p.c Sun Oct 4 19:54:32 1998 *************** static float zero = 0.0; *** 44,50 **** float x; #endif { ! float hfsq,f=0.0,c=0.0,s,z,R,u; __int32_t k,hx,hu=0.0,ax; GET_FLOAT_WORD(hx,x); --- 44,51 ---- float x; #endif { ! float hfsq,f=0.0,c=0.0,s,z,R; ! volatile float u; /* so GCC doesn't optimize it away */ __int32_t k,hx,hu=0.0,ax; GET_FLOAT_WORD(hx,x); *** src/libm/math/e_pow.c~1 Sat Feb 7 13:47:38 1998 --- src/libm/math/e_pow.c Sun Oct 4 20:35:36 1998 *************** ivln2_l = 1.92596299112661746887e-08; *** 104,110 **** double x, y; #endif { ! double z,ax,z_h,z_l,p_h,p_l; double y_1,t1,t2,r,s,t,u,v,w; __int32_t i,j,k,yisint,n; __int32_t hx,hy,ix,iy; --- 104,111 ---- double x, y; #endif { ! volatile double z; /* prevent GCC from optimizing it away */ ! double ax,z_h,z_l,p_h,p_l; double y_1,t1,t2,r,s,t,u,v,w; __int32_t i,j,k,yisint,n; __int32_t hx,hy,ix,iy; *** src/libm/math/ef_pow.c~1 Sat Feb 7 14:13:24 1998 --- src/libm/math/ef_pow.c Sun Oct 4 20:36:56 1998 *************** ivln2_l = 7.0526075433e-06; /* 0x36eca *** 63,69 **** float x, y; #endif { ! float z,ax,z_h,z_l,p_h,p_l; float y_1,t1,t2,r,s,t,u,v,w; __int32_t i,j,k,yisint,n; __int32_t hx,hy,ix,iy,is; --- 63,70 ---- float x, y; #endif { ! volatile float z; /* prevent optimizing it out of existence */ ! float ax,z_h,z_l,p_h,p_l; float y_1,t1,t2,r,s,t,u,v,w; __int32_t i,j,k,yisint,n; __int32_t hx,hy,ix,iy,is; *** src/libm/math/e_rem_pio2.c~1 Sat Feb 7 13:47:38 1998 --- src/libm/math/e_rem_pio2.c Sun Oct 4 20:41:58 1998 *************** pio2_3t = 8.47842766036889956997e-32; / *** 89,95 **** double x,y[]; #endif { ! double z=0.0,w,t,r,fn; double tx[3]; __int32_t i,j,n,ix,hx; int e0,nx; --- 89,96 ---- double x,y[]; #endif { ! volatile double z=0.0,r; /* prevent optimizing out of existence */ ! double w,t,fn; double tx[3]; __int32_t i,j,n,ix,hx; int e0,nx; *** src/libm/math/ef_rem_pio2.c~1 Sat Jun 27 16:53:48 1998 --- src/libm/math/ef_rem_pio2.c Sun Oct 4 20:43:32 1998 *************** pio2_3t = 6.1232342629e-17; /* 0x248d31 *** 102,108 **** float x,y[]; #endif { ! float z,w,t,r,fn; float tx[3]; __int32_t i,j,n,ix,hx; int e0,nx; --- 102,109 ---- float x,y[]; #endif { ! volatile float z,r; /* prevent optimizing out of existence */ ! float w,t,fn; float tx[3]; __int32_t i,j,n,ix,hx; int e0,nx; *** src/libm/math/k_cos.c~1 Tue Apr 15 08:39:48 1997 --- src/libm/math/k_cos.c Sun Oct 4 20:57:20 1998 *************** C6 = -1.13596475577881948265e-11; /* 0x *** 70,76 **** double x,y; #endif { ! double a,hz,z,r,qx; __int32_t ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; /* ix = |x|'s high word*/ --- 70,77 ---- double x,y; #endif { ! volatile double hz; /* prevent optimizing out of existence */ ! double a,z,r,qx; __int32_t ix; GET_HIGH_WORD(ix,x); ix &= 0x7fffffff; /* ix = |x|'s high word*/ *** src/libm/math/kf_cos.c~1 Tue Apr 15 08:39:48 1997 --- src/libm/math/kf_cos.c Sun Oct 4 21:01:54 1998 *************** C6 = -1.1359647598e-11; /* 0xad47d74e * *** 35,41 **** float x,y; #endif { ! float a,hz,z,r,qx; __int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; /* ix = |x|'s high word*/ --- 35,42 ---- float x,y; #endif { ! volatile float hz; /* prevent optimizing out of existence */ ! float a,z,r,qx; __int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; /* ix = |x|'s high word*/