git: c58c77246f88 - main - [libm] Avoid left shift of signed integer entities
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 14 Aug 2025 18:39:58 UTC
The branch main has been updated by dim:
URL: https://cgit.FreeBSD.org/src/commit/?id=c58c77246f88da87f309e8c449e98195d43e2c76
commit c58c77246f88da87f309e8c449e98195d43e2c76
Author: Steve Kargl <kargl@FreeBSD.org>
AuthorDate: 2025-08-14 18:38:41 +0000
Commit: Dimitry Andric <dim@FreeBSD.org>
CommitDate: 2025-08-14 18:38:41 +0000
[libm] Avoid left shift of signed integer entities
Follow-up commit d180086e6eae by fixing the left shift of signed integer
entities through the use of a helper function. Specific per file changes
are:
* lib/msun/src/e_fmodf.c:
* lib/msun/src/s_remquof.c:
. Eliminate now unused variable 'i'.
. Sort declaration statement.
. Use subnormal_ilogbf() to avoid left shift of signed integer.
* lib/msun/src/math_private.h b/lib/msun/src/math_private.h:
. Implement subnormal_ilogbf() to extract an exponent of a subnormal
float. This avoids left shifts of signed integers.
. Update nearby comment.
* lib/msun/src/s_ilogbf.c
. Fix declaration of the function statement in accordance with style(9).
. Use subnormal_ilogbf() to avoid left shift of signed integer.
PR: 288850
MFC after: 1 week
---
lib/msun/src/e_fmodf.c | 16 +++++++++-------
lib/msun/src/math_private.h | 16 +++++++++++++++-
lib/msun/src/s_ilogbf.c | 5 +++--
lib/msun/src/s_remquof.c | 16 +++++++++-------
4 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/lib/msun/src/e_fmodf.c b/lib/msun/src/e_fmodf.c
index a7d1a0c22acd..ada969db44c7 100644
--- a/lib/msun/src/e_fmodf.c
+++ b/lib/msun/src/e_fmodf.c
@@ -27,7 +27,7 @@ static const float one = 1.0, Zero[] = {0.0, -0.0,};
float
fmodf(float x, float y)
{
- int32_t n,hx,hy,hz,ix,iy,sx,i;
+ int32_t hx, hy, hz, ix, iy, n, sx;
GET_FLOAT_WORD(hx,x);
GET_FLOAT_WORD(hy,y);
@@ -44,14 +44,16 @@ fmodf(float x, float y)
return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
/* determine ix = ilogb(x) */
- if(hx<0x00800000) { /* subnormal x */
- for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
- } else ix = (hx>>23)-127;
+ if(hx<0x00800000)
+ ix = subnormal_ilogbf(hx);
+ else
+ ix = (hx>>23)-127;
/* determine iy = ilogb(y) */
- if(hy<0x00800000) { /* subnormal y */
- for (iy = -126,i=(hy<<8); i>=0; i<<=1) iy -=1;
- } else iy = (hy>>23)-127;
+ if(hy<0x00800000)
+ iy = subnormal_ilogbf(hy);
+ else
+ iy = (hy>>23)-127;
/* set up {hx,lx}, {hy,ly} and align y to x */
if(ix >= -126)
diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h
index 0711f2f33c41..fbd84e246ca7 100644
--- a/lib/msun/src/math_private.h
+++ b/lib/msun/src/math_private.h
@@ -740,7 +740,7 @@ irintl(long double x)
} while (0)
/*
- * For a double entity split into high and low parts, compute ilogb.
+ * For a subnormal double entity split into high and low parts, compute ilogb.
*/
static inline int32_t
subnormal_ilogb(int32_t hi, int32_t lo)
@@ -760,6 +760,20 @@ subnormal_ilogb(int32_t hi, int32_t lo)
return (j);
}
+/*
+ * For a subnormal float entity represented as an int32_t, compute ilogb.
+ */
+static inline int32_t
+subnormal_ilogbf(int32_t hx)
+{
+ int32_t j;
+ uint32_t i;
+ i = (uint32_t) hx << 8;
+ for (j = -126; 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_ilogbf.c b/lib/msun/src/s_ilogbf.c
index e0f8fee26ac8..5195e2331af3 100644
--- a/lib/msun/src/s_ilogbf.c
+++ b/lib/msun/src/s_ilogbf.c
@@ -18,7 +18,8 @@
#include "math.h"
#include "math_private.h"
- int ilogbf(float x)
+int
+ilogbf(float x)
{
int32_t hx,ix;
@@ -28,7 +29,7 @@
if(hx==0)
return FP_ILOGB0;
else /* subnormal x */
- for (ix = -126,hx<<=8; hx>0; hx<<=1) ix -=1;
+ ix = subnormal_ilogbf(hx);
return ix;
}
else if (hx<0x7f800000) return (hx>>23)-127;
diff --git a/lib/msun/src/s_remquof.c b/lib/msun/src/s_remquof.c
index 9cd148586796..e4adb8321559 100644
--- a/lib/msun/src/s_remquof.c
+++ b/lib/msun/src/s_remquof.c
@@ -25,7 +25,7 @@ static const float Zero[] = {0.0, -0.0,};
float
remquof(float x, float 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 q,sxy;
GET_FLOAT_WORD(hx,x);
@@ -47,14 +47,16 @@ remquof(float x, float y, int *quo)
}
/* determine ix = ilogb(x) */
- if(hx<0x00800000) { /* subnormal x */
- for (ix = -126,i=(hx<<8); i>0; i<<=1) ix -=1;
- } else ix = (hx>>23)-127;
+ if(hx<0x00800000)
+ ix = subnormal_ilogbf(hx);
+ else
+ ix = (hx>>23)-127;
/* determine iy = ilogb(y) */
- if(hy<0x00800000) { /* subnormal y */
- for (iy = -126,i=(hy<<8); i>0; i<<=1) iy -=1;
- } else iy = (hy>>23)-127;
+ if(hy<0x00800000)
+ iy = subnormal_ilogbf(hy);
+ else
+ iy = (hy>>23)-127;
/* set up {hx,lx}, {hy,ly} and align y to x */
if(ix >= -126)