Thanks for reporting that problem. I installed the attached patch into Gnulib on Savannah, which I hope fixes things for you. Please give it a try on your platform.
From 55a366a06fbd98bf13adc531579e3513cee97a32 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Sun, 6 Jul 2025 12:33:06 -0700
Subject: [PATCH] float-h-tests: port to C23 PowerPC GCC

Problem reported by C. Neidhal
<https://lists.gnu.org/r/bug-gnulib/2025-07/msg00021.html>.
* modules/float-h-tests (Depends-on): Add floorl, frexpl, ldexpl.
(test_float_h_LDADD): Link the resulting libms too.
* tests/test-float-h.c: Include math.h.
(normalize_long_double): New function.
(test_long_double): Use it.
---
 ChangeLog             | 11 +++++++++++
 modules/float-h-tests |  4 ++++
 tests/test-float-h.c  | 28 +++++++++++++++++++++++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 286d589d23..df445d4b76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2025-07-06  Paul Eggert  <egg...@cs.ucla.edu>
+
+	float-h-tests: port to C23 PowerPC GCC
+	Problem reported by C. Neidhal
+	<https://lists.gnu.org/r/bug-gnulib/2025-07/msg00021.html>.
+	* modules/float-h-tests (Depends-on): Add floorl, frexpl, ldexpl.
+	(test_float_h_LDADD): Link the resulting libms too.
+	* tests/test-float-h.c: Include math.h.
+	(normalize_long_double): New function.
+	(test_long_double): Use it.
+
 2025-07-06  Collin Funk  <collin.fu...@gmail.com>
 
 	pagealign_alloc: Don't assume pointers fit in 'unsigned long'.
diff --git a/modules/float-h-tests b/modules/float-h-tests
index 6ebf0b5f31..3ac3532501 100644
--- a/modules/float-h-tests
+++ b/modules/float-h-tests
@@ -5,6 +5,9 @@ tests/macros.h
 Depends-on:
 fpieee
 fpucw
+floorl
+frexpl
+ldexpl
 isnanf-nolibm
 isnand-nolibm
 isnanl-nolibm
@@ -15,3 +18,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-float-h
 check_PROGRAMS += test-float-h
+test_float_h_LDADD = $(LDADD) @FLOORL_LIBM@ @FREXPL_LIBM@ @LDEXPL_LIBM@
diff --git a/tests/test-float-h.c b/tests/test-float-h.c
index b1246f6193..c0440bc3f0 100644
--- a/tests/test-float-h.c
+++ b/tests/test-float-h.c
@@ -101,6 +101,8 @@ long double ls = LDBL_SNAN; /* added in ISO C 23 */
 
 /* ------------------------------------------------------------------------- */
 
+#include <math.h>
+
 #include "fpucw.h"
 #include "isnanf-nolibm.h"
 #include "isnand-nolibm.h"
@@ -396,6 +398,30 @@ test_double (void)
 
 /* -------------------- Check macros for 'long double' -------------------- */
 
+/* Return X after normalization.  This makes a difference on PowerPC
+   platforms where long double uses a "double double" format that does
+   not conform to the C23 rules for floating point.  On such a platform,
+   FLT_RADIX = 2, LDBL_MANT_DIG = 106, LDBL_EPSILON = 2**-105, and
+   1 < 1 + e < 1 + LDBL_EPSILON, where e = 2**-106 and 1 + e is a
+   representable long double value that is not normalized.
+   On such a platform, normalize_long_double (1 + e) returns 1.  */
+static long double
+normalize_long_double (long double volatile x)
+{
+  if (FLT_RADIX == 2)
+    {
+      int xexp;
+      long double volatile xfrac = frexpl (x, &xexp);
+      x = ldexpl (floorl (ldexpl (xfrac, LDBL_MANT_DIG - xexp)),
+                  xexp - LDBL_MANT_DIG);
+    }
+  else
+    {
+      /* Hope that X is already normalized.  */
+    }
+  return x;
+}
+
 static void
 test_long_double (void)
 {
@@ -455,7 +481,7 @@ test_long_double (void)
     for (n = 0; n <= 2 * LDBL_MANT_DIG; n++)
       {
         volatile long double half_n = pow2l (- n); /* 2^-n */
-        volatile long double x = me - half_n;
+        volatile long double x = normalize_long_double (me - half_n);
         if (x < me)
           ASSERT (x <= 1.0L);
       }
-- 
2.48.1

Reply via email to