git: 7c4565e3e75e - stable/14 - [libm] Fix undefined behavior of a left shifted of a signed integer
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 19 Aug 2025 03:18:56 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=7c4565e3e75e110b167f04efbe9d9d6355fcf2de
commit 7c4565e3e75e110b167f04efbe9d9d6355fcf2de
Author: Steve Kargl <kargl@FreeBSD.org>
AuthorDate: 2025-08-12 04:26:29 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-08-18 19:23:29 +0000
[libm] Fix undefined behavior of a left shifted of a signed integer
PR: 288778
(cherry picked from commit d180086e6eae2e152e803ed6cf13775a7c006dc7)
---
lib/msun/src/e_fmod.c | 30 ++++++++++++------------------
lib/msun/src/math_private.h | 21 +++++++++++++++++++++
lib/msun/src/s_ilogb.c | 13 +++++--------
lib/msun/src/s_remquo.c | 30 ++++++++++++------------------
4 files changed, 50 insertions(+), 44 deletions(-)
diff --git a/lib/msun/src/e_fmod.c b/lib/msun/src/e_fmod.c
index dd96f6bcd7cb..f8f1bcd88c6d 100644
--- a/lib/msun/src/e_fmod.c
+++ b/lib/msun/src/e_fmod.c
@@ -27,14 +27,14 @@ static const double one = 1.0, Zero[] = {0.0, -0.0,};
double
fmod(double x, double y)
{
- int32_t n,hx,hy,hz,ix,iy,sx,i;
- u_int32_t lx,ly,lz;
+ int32_t hx, hy, hz, ix, iy, n, sx;
+ u_int32_t lx, ly, lz;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
sx = hx&0x80000000; /* sign of x */
- hx ^=sx; /* |x| */
- hy &= 0x7fffffff; /* |y| */
+ hx ^= sx; /* |x| */
+ hy &= 0x7fffffff; /* |y| */
/* purge off exception values */
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
@@ -47,22 +47,16 @@ fmod(double x, double y)
}
/* determine ix = ilogb(x) */
- if(hx<0x00100000) { /* subnormal x */
- if(hx==0) {
- for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
- } else {
- for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
- }
- } else ix = (hx>>20)-1023;
+ if(hx<0x00100000)
+ ix = subnormal_ilogb(hx, lx);
+ else
+ ix = (hx>>20)-1023;
/* determine iy = ilogb(y) */
- if(hy<0x00100000) { /* subnormal y */
- if(hy==0) {
- for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
- } else {
- for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
- }
- } else iy = (hy>>20)-1023;
+ if(hy<0x00100000)
+ iy = subnormal_ilogb(hy, ly);
+ else
+ iy = (hy>>20)-1023;
/* set up {hx,lx}, {hy,ly} and align y to x */
if(ix >= -1022)
diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h
index bdf45a9035bc..1f5878445a8c 100644
--- a/lib/msun/src/math_private.h
+++ b/lib/msun/src/math_private.h
@@ -740,6 +740,27 @@ irintl(long double x)
(ar) = (x) - (ai); \
} while (0)
+/*
+ * For a double entity split into high and low parts, compute ilogb.
+ */
+static inline int32_t
+subnormal_ilogb(int32_t hi, int32_t lo)
+{
+ int32_t j;
+ uint32_t i;
+
+ j = -1022;
+ if (hi == 0) {
+ j -= 21;
+ i = (uint32_t)lo;
+ } else
+ i = (uint32_t)hi << 11;
+
+ for (; i < 0x7fffffff; i <<= 1) j -= 1;
+
+ return (j);
+}
+
#ifdef DEBUG
#if defined(__amd64__) || defined(__i386__)
#define breakpoint() asm("int $3")
diff --git a/lib/msun/src/s_ilogb.c b/lib/msun/src/s_ilogb.c
index ac9feceaf14e..c85c689024a3 100644
--- a/lib/msun/src/s_ilogb.c
+++ b/lib/msun/src/s_ilogb.c
@@ -22,21 +22,18 @@
#include "math.h"
#include "math_private.h"
- int ilogb(double x)
+int
+ilogb(double x)
{
- int32_t hx,lx,ix;
+ int32_t hx, ix, lx;
EXTRACT_WORDS(hx,lx,x);
hx &= 0x7fffffff;
if(hx<0x00100000) {
if((hx|lx)==0)
return FP_ILOGB0;
- else /* subnormal x */
- if(hx==0) {
- for (ix = -1043; lx>0; lx<<=1) ix -=1;
- } else {
- for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
- }
+ else
+ ix = subnormal_ilogb(hx, lx);
return ix;
}
else if (hx<0x7ff00000) return (hx>>20)-1023;
diff --git a/lib/msun/src/s_remquo.c b/lib/msun/src/s_remquo.c
index a3f73f779c1b..5630838fe3b4 100644
--- a/lib/msun/src/s_remquo.c
+++ b/lib/msun/src/s_remquo.c
@@ -5,7 +5,7 @@
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
+ * software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
@@ -28,7 +28,7 @@ static const double Zero[] = {0.0, -0.0,};
double
remquo(double x, double y, int *quo)
{
- int32_t n,hx,hy,hz,ix,iy,sx,i;
+ int32_t hx,hy,hz,ix,iy,n,sx;
u_int32_t lx,ly,lz,q,sxy;
EXTRACT_WORDS(hx,lx,x);
@@ -54,25 +54,19 @@ remquo(double x, double y, int *quo)
}
/* determine ix = ilogb(x) */
- if(hx<0x00100000) { /* subnormal x */
- if(hx==0) {
- for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
- } else {
- for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
- }
- } else ix = (hx>>20)-1023;
+ if(hx<0x00100000)
+ ix = subnormal_ilogb(hx, lx);
+ else
+ ix = (hx>>20)-1023;
/* determine iy = ilogb(y) */
- if(hy<0x00100000) { /* subnormal y */
- if(hy==0) {
- for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
- } else {
- for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
- }
- } else iy = (hy>>20)-1023;
+ if(hy<0x00100000)
+ iy = subnormal_ilogb(hy, ly);
+ else
+ iy = (hy>>20)-1023;
/* set up {hx,lx}, {hy,ly} and align y to x */
- if(ix >= -1022)
+ if(ix >= -1022)
hx = 0x00100000|(0x000fffff&hx);
else { /* subnormal x, shift x to normal */
n = -1022-ix;
@@ -84,7 +78,7 @@ remquo(double x, double y, int *quo)
lx = 0;
}
}
- if(iy >= -1022)
+ if(iy >= -1022)
hy = 0x00100000|(0x000fffff&hy);
else { /* subnormal y, shift y to normal */
n = -1022-iy;