Bug 37581 - IEEE inexact-flag not working on the Alpha
Summary: IEEE inexact-flag not working on the Alpha
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-09-19 07:03 UTC by bagnara
Modified: 2009-02-03 11:10 UTC (History)
2 users (show)

See Also:
Host: alphaev56-unknown-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Assembly code generated with g++ -S -mieee-with-inexact sf.cc (887 bytes, text/plain)
2008-09-19 07:04 UTC, bagnara
Details

Note You need to log in before you can comment on or make changes to this bug.
Description bagnara 2008-09-19 07:03:20 UTC
The following shows a problem on the Alpha whereby
the division 2/3 made on floats is flagged as exact.
Here are the details:

$ cat sf.cc
#include <fenv.h>
#include <cstdio>


int main() {
  float x = 2;
  float y = 3;
  feclearexcept(FE_INEXACT);
  x = x / y;
  printf("%d %.1000g\n", fetestexcept(FE_INEXACT) != 0, x);
}
$ g++ -v
Using built-in specs.
Target: alpha-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --disable-libssp --with-long-double-128 --enable-checking=release --build=alpha-linux-gnu --host=alpha-linux-gnu --target=alpha-linux-gnu
Thread model: posix
gcc version 4.2.4 (Debian 4.2.4-3)
$ g++ -mieee-with-inexact sf.cc
$ ./a.out
0 0.666666686534881591796875
$ cat /proc/cpuinfo
cpu                     : Alpha
cpu model               : EV56
cpu variation           : 7
cpu revision            : 0
cpu serial number       :
system type             : Rawhide
system variation        : Tincup
system revision         : 0
system serial number    : AY74642662
cycle frequency [Hz]    : 399642346 est.
timer frequency [Hz]    : 1200.00
page size [bytes]       : 8192
phys. address bits      : 40
max. addr. space #      : 127
BogoMIPS                : 705.16
kernel unaligned acc    : 0 (pc=0,va=0)
user unaligned acc      : 31 (pc=20000074c18,va=87)
platform string         : AlphaServer 1200 5/400 4MB
cpus detected           : 1
cpus active             : 1
cpu active mask         : 0000000000000001
L1 Icache               : 8K, 1-way, 32b line
L1 Dcache               : 8K, 1-way, 32b line
L2 cache                : 96K, 3-way, 64b line
L3 cache                : 4096K, 1-way, 64b line
$

I attach the generated assembly code, which shows this is not a constant propagation issue.
Comment 1 bagnara 2008-09-19 07:04:36 UTC
Created attachment 16359 [details]
Assembly code generated with g++ -S -mieee-with-inexact sf.cc
Comment 2 Uroš Bizjak 2009-01-23 08:47:10 UTC
Works for me with:

--cut here--
#define _GNU_SOURCE
#include <fenv.h>
#include <signal.h>
#include <stdlib.h>

static void foo (int sig)
{
  exit (0);
}

float __attribute__((noinline)) test (float x) { return 2.0f / x; };
  
int main()
{
  volatile float x;

  signal (SIGFPE, foo);

  feclearexcept (FE_ALL_EXCEPT);
  feenableexcept (FE_INEXACT);

  x = test (3.0f);

  abort ();
}
--cut here--

$ gcc -O2 -lm -mieee-with-inexact sf.c
$ ./a.out
$
Comment 3 Abramo Bagnara 2009-01-24 05:43:00 UTC
The test case you have used it's different from the original that showed the bug.

Nevertheless it's useful to understand the possible nature of the bug.

It seems that if feenableexcept(FE_INEXACT) is not called fetestexcept(FE_INEXACT) doesn't work as expected (and as C99 standard provides).

Please note that according to documentation GNU extension feenableexcept/fedisablexcept does not enable/disable inexact detection, but does enable/disable inexact *trapping* via SIGFPE signal.

Here below there is a new test case that shows the wrong behaviour.

$ cat sf2.c 
#define _GNU_SOURCE
#include <fenv.h>
#include <signal.h>
#include <stdio.h>

static void foo (int sig)
{
  printf("inexact\n");
}


float __attribute__((noinline)) test (float x) {
	printf("%f / %f\n", 2.0f, x);
	return 2.0f / x;
}

void t()
{
  volatile float x;
  feclearexcept (FE_ALL_EXCEPT);
  x = test (3.0f);
  printf("fetestexcept(FE_INEXACT) = %d\n", fetestexcept(FE_INEXACT));
  feclearexcept (FE_ALL_EXCEPT);
  x = test (2.0f);
  printf("fetestexcept(FE_INEXACT) = %d\n", fetestexcept(FE_INEXACT));
}

int main() {
  printf("\nWith FE_INEXACT SIGFPE disabled\n");
  t();

  printf("\nWith FE_INEXACT SIGFPE enabled\n");
  signal (SIGFPE, foo);
  feenableexcept (FE_INEXACT);
  t();
}
$ gcc -O2 -lm -mieee-with-inexact sf2.c
$ ./a.out

With FE_INEXACT SIGFPE disabled
2.000000 / 3.000000
fetestexcept(FE_INEXACT) = 0
2.000000 / 2.000000
fetestexcept(FE_INEXACT) = 0

With FE_INEXACT SIGFPE enabled
2.000000 / 3.000000
inexact
fetestexcept(FE_INEXACT) = 2097152
2.000000 / 2.000000
fetestexcept(FE_INEXACT) = 0
$
Comment 4 bagnara 2009-01-24 08:08:52 UTC
I don't know why the bug was closed: I can confirm the erroneous behavior is present also in GCC 4.3.2.
Comment 5 Uroš Bizjak 2009-01-24 10:17:15 UTC
(In reply to comment #4)
> I don't know why the bug was closed: I can confirm the erroneous behavior is
> present also in GCC 4.3.2.

Because it looks to me that this is libc problem with fetestexcept. As far as the compiler is concerned, GCC correctly decorates trapping instructions with /sui and puts trap barrier to expected place:

	...
	jsr $26,($27),__nldbl_printf		!lituse_jsr!5
	ldah $29,0($26)		!gpdisp!6
	divs/sui $f3,$f2,$f0
	trapb
	...
Comment 6 Abramo Bagnara 2009-01-24 15:41:22 UTC
(In reply to comment #5)

> Because it looks to me that this is libc problem with fetestexcept. As far as
> the compiler is concerned, GCC correctly decorates trapping instructions with
> /sui and puts trap barrier to expected place:
> 
>         ...
>         jsr $26,($27),__nldbl_printf            !lituse_jsr!5
>         ldah $29,0($26)         !gpdisp!6
>         divs/sui $f3,$f2,$f0
>         trapb
>         ...

I've reported a bug according to the valuable info you provide.

http://sourceware.org/bugzilla/show_bug.cgi?id=9783
Comment 7 Uroš Bizjak 2009-02-03 11:10:17 UTC
Not a GCC bug.