Package: gcc-4.3 Version: 4.3-20080127-1 Severity: important The attached code, coming from the GNU libc (test-ifloat.c and s_cacoshf.c) gives wrong results when compiled with gcc-4.3 and -O3. The results are correct with gcc-4.3 and lower optimisation or with gcc-4.2.
-- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: i386 Kernel: Linux 2.6.18-5-amd64 (SMP w/2 CPU cores) Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages gcc-4.3 depends on: ii binutils 2.18.1~cvs20080103-1 The GNU assembler, linker and bina ii cpp-4.3 4.3-20080127-1 The GNU C preprocessor ii gcc-4.3-base 4.3-20080127-1 The GNU Compiler Collection (base ii libc6 2.7-6 GNU C Library: Shared libraries ii libgcc1 1:4.3-20080127-1 GCC support library ii libgmp3c2 2:4.2.2+dfsg-1 Multiprecision arithmetic library ii libgomp1 4.3-20080127-1 GCC OpenMP (GOMP) support library ii libmpfr1ldbl 2.3.0.dfsg.1-2 multiple precision floating-point Versions of packages gcc-4.3 recommends: ii libc6-dev 2.7-6 GNU C Library: Development Librari -- no debconf information
/* gcc-4.3 -Wall -std=gnu99 -O3 -o test-cacoshf test-cacoshf.c */ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include <complex.h> #include <math.h> #include <float.h> #include <limits.h> #include <stdlib.h> #include <stdio.h> __complex__ float mycacoshf (__complex__ float x) { __complex__ float res; int rcls = fpclassify (__real__ x); int icls = fpclassify (__imag__ x); if (rcls <= FP_INFINITE || icls <= FP_INFINITE) { if (icls == FP_INFINITE) { __real__ res = HUGE_VALF; if (rcls == FP_NAN) __imag__ res = nanf (""); else __imag__ res = copysignf ((rcls == FP_INFINITE ? (__real__ x < 0.0 ? M_PI - M_PI_4 : M_PI_4) : M_PI_2), __imag__ x); } else if (rcls == FP_INFINITE) { __real__ res = HUGE_VALF; if (icls >= FP_ZERO) __imag__ res = copysignf (signbit (__real__ x) ? M_PI : 0.0, __imag__ x); else __imag__ res = nanf (""); } else { __real__ res = nanf (""); __imag__ res = nanf (""); } } else if (rcls == FP_ZERO && icls == FP_ZERO) { __real__ res = 0.0; __imag__ res = copysignf (M_PI_2, __imag__ x); } else { __complex__ float y; __real__ y = (__real__ x - __imag__ x) * (__real__ x + __imag__ x) - 1.0; __imag__ y = 2.0 * __real__ x * __imag__ x; y = csqrtf (y); if (__real__ x < 0.0) y = -y; __real__ y += __real__ x; __imag__ y += __imag__ x; res = clogf (y); /* We have to use the positive branch. */ if (__real__ res < 0.0) res = -res; } return res; } /* Various constants (we must supply them precalculated for accuracy). */ #define M_PI_34l (M_PIl - M_PI_4l) /* 3*pi/4 */ static float minus_zero, plus_zero, nan_value; #define BUILD_COMPLEX(real, imag) \ ({ __complex__ float __retval; \ __real__ __retval = (real); \ __imag__ __retval = (imag); \ __retval; }) #define MANT_DIG (FLT_MANT_DIG-1) static void check_float_internal (const char *test_name, float computed, float expected, float max_ulp, int xfail) { int ok = 0; float diff = 0; float ulp = 0; if (isnan (computed) && isnan (expected)) ok = 1; else if (isinf (computed) && isinf (expected)) { /* Test for sign of infinities. */ if (signbit (computed) != signbit (expected)) { ok = 0; printf ("infinity has wrong sign.\n"); } else ok = 1; } /* Don't calc ulp for NaNs or infinities. */ else if (isinf (computed) || isnan (computed) || isinf (expected) || isnan (expected)) ok = 0; else { diff = fabsf (computed - expected); /* ilogb (0) isn't allowed. */ if (expected == 0.0) ulp = diff / ldexpf (1.0, - MANT_DIG); else ulp = diff / ldexpf (1.0, ilogbf (expected) - MANT_DIG); if (computed == 0.0 && expected == 0.0 && signbit(computed) != signbit (expected)) ok = 0; else if (ulp <= 0.5 || (ulp <= max_ulp)) ok = 1; else ok = 0; } if (ok == xfail) { if (!ok) printf ("Failure: "); printf ("Test: %s\n", test_name); printf ("Result:\n"); printf (" is: % .20e % .20a\n", computed, computed); printf (" should be: % .20e % .20a\n", expected, expected); } } static void check_complex (const char *test_name, __complex__ float computed, __complex__ float expected, __complex__ float max_ulp, __complex__ int xfail) { float part_comp, part_exp, part_max_ulp; int part_xfail; char str[200]; sprintf (str, "Real part of: %s", test_name); part_comp = __real__ computed; part_exp = __real__ expected; part_max_ulp = __real__ max_ulp; part_xfail = __real__ xfail; check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail); sprintf (str, "Imaginary part of: %s", test_name); part_comp = __imag__ computed; part_exp = __imag__ expected; part_max_ulp = __imag__ max_ulp; part_xfail = __imag__ xfail; check_float_internal (str, part_comp, part_exp, part_max_ulp, part_xfail); } int main (int argc, char **argv) { plus_zero = 0.0; nan_value = plus_zero / plus_zero; minus_zero = copysignf (0.0, -1.0); check_complex ("cacosh (0 + 0 i) == 0.0 + pi/2 i", mycacoshf (BUILD_COMPLEX (0, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0); check_complex ("cacosh (-0 + 0 i) == 0.0 + pi/2 i", mycacoshf (BUILD_COMPLEX (minus_zero, 0)), BUILD_COMPLEX (0.0, M_PI_2l), 0, 0); check_complex ("cacosh (0 - 0 i) == 0.0 - pi/2 i", mycacoshf (BUILD_COMPLEX (0, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0); check_complex ("cacosh (-0 - 0 i) == 0.0 - pi/2 i", mycacoshf (BUILD_COMPLEX (minus_zero, minus_zero)), BUILD_COMPLEX (0.0, -M_PI_2l), 0, 0); check_complex ("cacosh (-inf + inf i) == inf + 3/4 pi i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, M_PI_34l), 0, 0); check_complex ("cacosh (-inf - inf i) == inf - 3/4 pi i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, -HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, -M_PI_34l), 0, 0); check_complex ("cacosh (inf + inf i) == inf + pi/4 i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, M_PI_4l), 0, 0); check_complex ("cacosh (inf - inf i) == inf - pi/4 i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, -HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, -M_PI_4l), 0, 0); check_complex ("cacosh (-10.0 + inf i) == inf + pi/2 i", mycacoshf (BUILD_COMPLEX (-10.0, HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, M_PI_2l), 0, 0); check_complex ("cacosh (-10.0 - inf i) == inf - pi/2 i", mycacoshf (BUILD_COMPLEX (-10.0, -HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, -M_PI_2l), 0, 0); check_complex ("cacosh (0 + inf i) == inf + pi/2 i", mycacoshf (BUILD_COMPLEX (0, HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, M_PI_2l), 0, 0); check_complex ("cacosh (0 - inf i) == inf - pi/2 i", mycacoshf (BUILD_COMPLEX (0, -HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, -M_PI_2l), 0, 0); check_complex ("cacosh (0.1 + inf i) == inf + pi/2 i", mycacoshf (BUILD_COMPLEX (0.1L, HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, M_PI_2l), 0, 0); check_complex ("cacosh (0.1 - inf i) == inf - pi/2 i", mycacoshf (BUILD_COMPLEX (0.1L, -HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, -M_PI_2l), 0, 0); check_complex ("cacosh (-inf + 0 i) == inf + pi i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, 0)), BUILD_COMPLEX (HUGE_VALF, M_PIl), 0, 0); check_complex ("cacosh (-inf - 0 i) == inf - pi i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, minus_zero)), BUILD_COMPLEX (HUGE_VALF, -M_PIl), 0, 0); check_complex ("cacosh (-inf + 100 i) == inf + pi i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, 100)), BUILD_COMPLEX (HUGE_VALF, M_PIl), 0, 0); check_complex ("cacosh (-inf - 100 i) == inf - pi i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, -100)), BUILD_COMPLEX (HUGE_VALF, -M_PIl), 0, 0); check_complex ("cacosh (inf + 0 i) == inf + 0.0 i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, 0)), BUILD_COMPLEX (HUGE_VALF, 0.0), 0, 0); check_complex ("cacosh (inf - 0 i) == inf - 0 i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, minus_zero)), BUILD_COMPLEX (HUGE_VALF, minus_zero), 0, 0); check_complex ("cacosh (inf + 0.5 i) == inf + 0.0 i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, 0.5)), BUILD_COMPLEX (HUGE_VALF, 0.0), 0, 0); check_complex ("cacosh (inf - 0.5 i) == inf - 0 i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, -0.5)), BUILD_COMPLEX (HUGE_VALF, minus_zero), 0, 0); check_complex ("cacosh (inf + NaN i) == inf + NaN i", mycacoshf (BUILD_COMPLEX (HUGE_VALF, nan_value)), BUILD_COMPLEX (HUGE_VALF, nan_value), 0, 0); check_complex ("cacosh (-inf + NaN i) == inf + NaN i", mycacoshf (BUILD_COMPLEX (-HUGE_VALF, nan_value)), BUILD_COMPLEX (HUGE_VALF, nan_value), 0, 0); check_complex ("cacosh (0 + NaN i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (0, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); check_complex ("cacosh (-0 + NaN i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (minus_zero, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); check_complex ("cacosh (NaN + inf i) == inf + NaN i", mycacoshf (BUILD_COMPLEX (nan_value, HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, nan_value), 0, 0); check_complex ("cacosh (NaN - inf i) == inf + NaN i", mycacoshf (BUILD_COMPLEX (nan_value, -HUGE_VALF)), BUILD_COMPLEX (HUGE_VALF, nan_value), 0, 0); check_complex ("cacosh (10.5 + NaN i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); check_complex ("cacosh (-10.5 + NaN i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (-10.5, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); check_complex ("cacosh (NaN + 0.75 i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (nan_value, 0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); check_complex ("cacosh (NaN - 0.75 i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (nan_value, -0.75)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); check_complex ("cacosh (NaN + NaN i) == NaN + NaN i", mycacoshf (BUILD_COMPLEX (nan_value, nan_value)), BUILD_COMPLEX (nan_value, nan_value), 0, 0); return 0; }