From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2134) id 3FFE73858D20; Thu, 13 Apr 2023 17:36:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3FFE73858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1681407416; bh=YR6R0CeP32ROGEmsfhJpG7+Oij+Df5ICn6Zey3A2xBA=; h=From:To:Subject:Date:From; b=gtpZX9BI8iwNoNEX/+msSPSjbwOyjZ8MIa97GQM85/UiPLxT2t9gctbVh8TxuOeYL 2OwwCuJ87rY8sEIrMuz9bflm5XLvXlaMcS/knDtS9XNB4XgHNDILGNLC3+ENZRlEOk hxQVPM4kkBBmE+bbZZiECgqRTuHKhM0zb02RLRZw= Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Jeff Johnston To: newlib-cvs@sourceware.org Subject: [newlib-cygwin] Fix missing sign for overflow/underflow where x is negative and y is large odd integer X-Act-Checkin: newlib-cygwin X-Git-Author: Andoni Arregi X-Git-Refname: refs/heads/master X-Git-Oldrev: be2749cd4eb6e7ea1b70eaf7cd78f683db21c8ec X-Git-Newrev: 5a961061de7d70bd3568270185c3189e20958e68 Message-Id: <20230413173656.3FFE73858D20@sourceware.org> Date: Thu, 13 Apr 2023 17:36:56 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D5a961061de7= d70bd3568270185c3189e20958e68 commit 5a961061de7d70bd3568270185c3189e20958e68 Author: Andoni Arregi Date: Wed Apr 12 17:34:42 2023 +0200 Fix missing sign for overflow/underflow where x is negative and y is la= rge odd integer Diff: --- newlib/libm/math/e_pow.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/newlib/libm/math/e_pow.c b/newlib/libm/math/e_pow.c index 258cca8dd..f02f76dc0 100644 --- a/newlib/libm/math/e_pow.c +++ b/newlib/libm/math/e_pow.c @@ -107,7 +107,7 @@ ivln2_l =3D 1.92596299112661746887e-08; /* 0x3E54AE0B= , 0xF85DDF44 =3D1/ln2 tail*/ #endif { double z,ax,z_h,z_l,p_h,p_l; - double y1,t1,t2,r,s,t,u,v,w; + double y1,t1,t2,r,s,sign,t,u,v,w; __int32_t i,j,k,yisint,n; __int32_t hx,hy,ix,iy; __uint32_t lx,ly; @@ -184,23 +184,26 @@ ivln2_l =3D 1.92596299112661746887e-08; /* 0x3E54AE= 0B, 0xF85DDF44 =3D1/ln2 tail*/ return z; } } - =20 + /* (x<0)**(non-int) is NaN */ - /* REDHAT LOCAL: This used to be - if((((hx>>31)+1)|yisint)=3D=3D0) return (x-x)/(x-x); - but ANSI C says a right shift of a signed negative quantity is - implementation defined. */ - if(((((__uint32_t)hx>>31)-1)|yisint)=3D=3D0) return (x-x)/(x-x); + + n =3D ((uint32_t)hx >> 31U) - 1U; + if ((n | yisint) =3D=3D 0) return (x-x)/(x-x); + + sign =3D one; /* (sign of result -ve**odd) =3D -1 else =3D 1 */ + if ((n | (yisint - 1)) =3D=3D 0) { + sign =3D -one; /* (-ve)**(odd int) */ + } =20 /* |y| is huge */ if(iy>0x41e00000) { /* if |y| > 2**31 */ - if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow and y is an even i= nteger */ if(ix<=3D0x3fefffff) return (hy<0)? __math_oflow(0):__math_uflow(0); if(ix>=3D0x3ff00000) return (hy>0)? __math_oflow(0):__math_uflow(0); } /* over/underflow if x is not close to one */ - if(ix<0x3fefffff) return (hy<0)? __math_oflow(0):__math_uflow(0); - if(ix>0x3ff00000) return (hy>0)? __math_oflow(0):__math_uflow(0); + if(ix<0x3fefffff) return (hy<0)? __math_oflow(sign<0):__math_uflow(si= gn<0); + if(ix>0x3ff00000) return (hy>0)? __math_oflow(sign<0):__math_uflow(si= gn<0); /* now |1-x| is tiny <=3D 2**-20, suffice to compute=20 log(x) by x-x^2/2+x^3/3-x^4/4 */ t =3D ax-1; /* t has 20 trailing zeros */ @@ -260,10 +263,6 @@ ivln2_l =3D 1.92596299112661746887e-08; /* 0x3E54AE0= B, 0xF85DDF44 =3D1/ln2 tail*/ t2 =3D z_l-(((t1-t)-dp_h[k])-z_h); } =20 - s =3D one; /* s (sign of result -ve**odd) =3D -1 else =3D 1 */ - if(((((__uint32_t)hx>>31)-1)|(yisint-1))=3D=3D0) - s =3D -one;/* (-ve)**(odd int) */ - /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ y1 =3D y; SET_LOW_WORD(y1,0); @@ -273,15 +272,15 @@ ivln2_l =3D 1.92596299112661746887e-08; /* 0x3E54AE= 0B, 0xF85DDF44 =3D1/ln2 tail*/ EXTRACT_WORDS(j,i,z); if (j>=3D0x40900000) { /* z >=3D 1024 */ if(((j-0x40900000)|i)!=3D0) /* if z > 1024 */ - return __math_oflow(s<0); /* overflow */ + return __math_oflow(sign<0); /* overflow */ else { - if(p_l+ovt>z-p_h) return __math_oflow(s<0); /* overflow */ + if(p_l+ovt>z-p_h) return __math_oflow(sign<0); /* overflow */ } } else if((j&0x7fffffff)>=3D0x4090cc00 ) { /* z <=3D -1075 */ if(((j-0xc090cc00)|i)!=3D0) /* z < -1075 */ - return __math_uflow(s<0); /* underflow */ + return __math_uflow(sign<0); /* underflow */ else { - if(p_l<=3Dz-p_h) return __math_uflow(s<0); /* underflow */ + if(p_l<=3Dz-p_h) return __math_uflow(sign<0); /* underflow */ } } /* @@ -313,7 +312,7 @@ ivln2_l =3D 1.92596299112661746887e-08; /* 0x3E54AE0B= , 0xF85DDF44 =3D1/ln2 tail*/ j +=3D (n<<20); if((j>>20)<=3D0) z =3D scalbn(z,(int)n); /* subnormal output */ else SET_HIGH_WORD(z,j); - return s*z; + return sign*z; } =20 #endif /* defined(_DOUBLE_IS_32BITS) */