[Bug math/33411] powl() raises spurious overflow

adhemerval.zanella at linaro dot org sourceware-bugzilla@sourceware.org
Thu Oct 9 18:28:14 GMT 2025


https://sourceware.org/bugzilla/show_bug.cgi?id=33411

Adhemerval Zanella <adhemerval.zanella at linaro dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |adhemerval.zanella at linaro dot o
                   |                            |rg

--- Comment #2 from Adhemerval Zanella <adhemerval.zanella at linaro dot org> ---
(In reply to Paul Zimmermann from comment #1)
> I can't reproduce. I added some instructions to print the glibc version
> (here on x86_64):
> 
> zimmerma@araignee:/tmp$ gcc e.c -lm
> zimmerma@araignee:/tmp$ ./a.out 
> GNU libc version: 2.41
> GNU libc release: stable
> 1.18973e+4932=LDBL_MAX
> 1.09075e+2466=f18a
> 0=flags
> 0x8=FE_OVERFLOW

You need to build with -fno-builtin to avoid gcc constant folding the result:

$ gcc -Wall t.c -o t -lm -fno-builtin
t.c:9: warning: ignoring ‘#pragma STDC FENV_ACCESS’ [-Wunknown-pragmas]
    9 | #pragma STDC FENV_ACCESS ON
      |
t.c:10: warning: ignoring ‘#pragma STDC FP_CONTRACT’ [-Wunknown-pragmas]
   10 | #pragma STDC FP_CONTRACT OFF
      |
t.c:11: warning: ignoring ‘#pragma STDC FENV_ROUND’ [-Wunknown-pragmas]
   11 | #pragma STDC FENV_ROUND FE_TONEAREST
      |
t.c:12: warning: ignoring ‘#pragma STDC FENV_DEC_ROUND’ [-Wunknown-pragmas]
   12 | #pragma STDC FENV_DEC_ROUND FE_DEC_TONEAREST
      |
t.c:13: warning: ignoring ‘#pragma STDC CX_LIMITED_RANGE’ [-Wunknown-pragmas]
   13 | #pragma STDC CX_LIMITED_RANGE OFF
      |

azanella@mandiga ~/Projects/glibc/build/x86_64-linux-gnu $ ./t
1.18973e+4932=LDBL_MAX
1.09075e+2466=f18a
0x28=flags
0x8=FE_OVERFLOW
t: t.c:33: main: Assertion `0 == (FE_OVERFLOW & flags)' failed.
Aborted

This is an issue with sysdeps/x86_64/fpu/e_powl.S, the _Float128 version (used
on aarch64 and for expf128) does not show this issue:

$ cat tf128.c
#include <assert.h>
#include <limits.h>
#include <errno.h>
#include <stdio.h>
#include <float.h>
#include <fenv.h>
#include <math.h>
#include <quadmath.h>

#pragma STDC FENV_ACCESS ON
#pragma STDC FP_CONTRACT OFF
#pragma STDC FENV_ROUND FE_TONEAREST
#pragma STDC FENV_DEC_ROUND FE_DEC_TONEAREST
#pragma STDC CX_LIMITED_RANGE OFF

int main(void){
  char buf[256];

  if(1){
    _Float128 f18a;
    _Float128 f18b = 1.090748135619415929463e+2466Q;
    int flags;
    feclearexcept( FE_ALL_EXCEPT );
    errno = 0;
    f18a = powf128( f18b, 1.Q );
    flags = fetestexcept( FE_ALL_EXCEPT );

    quadmath_snprintf (buf, sizeof buf, "%Qg", FLT128_MAX);
    printf ("%s=FLT128_MAX\n", buf);
    quadmath_snprintf (buf, sizeof buf, "%Qg", f18a);
    printf ("%s=f18a\n", buf);
    (void)printf("%#x=flags\n", flags);
    (void)printf("%#x=FE_OVERFLOW\n", FE_OVERFLOW);
    (void)fflush(NULL);
    assert( f18b == f18a );
    assert( 3 == math_errhandling );
    assert( 0 == errno );
    assert( 0 == (FE_OVERFLOW & flags) );       /* fails here */
  }
  return 0;
}
$ gcc -Wall tf128.c -fno-builtin -o tf128 -lm -lquadmath -D_GNU_SOURCE -O0 -g
tf128.c:10: warning: ignoring ‘#pragma STDC FENV_ACCESS’ [-Wunknown-pragmas]
   10 | #pragma STDC FENV_ACCESS ON
      |
tf128.c:11: warning: ignoring ‘#pragma STDC FP_CONTRACT’ [-Wunknown-pragmas]
   11 | #pragma STDC FP_CONTRACT OFF
      |
tf128.c:12: warning: ignoring ‘#pragma STDC FENV_ROUND’ [-Wunknown-pragmas]
   12 | #pragma STDC FENV_ROUND FE_TONEAREST
      |
tf128.c:13: warning: ignoring ‘#pragma STDC FENV_DEC_ROUND’ [-Wunknown-pragmas]
   13 | #pragma STDC FENV_DEC_ROUND FE_DEC_TONEAREST
      |
tf128.c:14: warning: ignoring ‘#pragma STDC CX_LIMITED_RANGE’
[-Wunknown-pragmas]
   14 | #pragma STDC CX_LIMITED_RANGE OFF
      |
$ ./tf128
1.18973e+4932=FLT128_MAX
1.09075e+2466=f18a
0=flags
0x8=FE_OVERFLOW

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Glibc-bugs mailing list