$ cat hello.c int main() { return 0; } $ gcc -g -ffast-math hello.c $ gdb ./a.out GNU gdb 6.3-debian Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) r Starting program: /home/ig25/Krempel/a.out Program received signal SIGSEGV, Segmentation fault. 0x08048469 in set_fast_math () at ../../gcc-4.1/gcc/config/i386/crtfastmath.c:70 70 __builtin_ia32_ldmxcsr (mxcsr); (gdb) q The program is running. Exit anyway? (y or n) y $ cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 6 model : 8 model name : AMD Athlon(TM) XP 2600+ stepping : 1 cpu MHz : 2083.203 cache size : 256 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmovpat pse36 mmx fxsr sse syscall mmxext 3dnowext 3dnow bogomips : 4128.76 $ gcc -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc-4.1/configure --prefix=/home/ig25 --enable-languages=c,f95 Thread model: posix gcc version 4.1.0 20050811 (experimental) This shows up as a regression in the gfortran testsuite: Running /home/ig25/gcc-4.1/gcc/testsuite/gfortran.dg/dg.exp ... FAIL: gfortran.dg/g77/20010216-1.f -O0 execution test FAIL: gfortran.dg/g77/20010216-1.f -O1 execution test FAIL: gfortran.dg/g77/20010216-1.f -O2 execution test FAIL: gfortran.dg/g77/20010216-1.f -O3 -fomit-frame-pointer execution test FAIL: gfortran.dg/g77/20010216-1.f -O3 -fomit-frame-pointer -funroll-loops execution test FAIL: gfortran.dg/g77/20010216-1.f -O3 -fomit-frame-pointer -funroll-all-loops-finline-functions execution test FAIL: gfortran.dg/g77/20010216-1.f -O3 -g execution test FAIL: gfortran.dg/g77/20010216-1.f -Os execution test
Someone is not testing the correct flags.
As of Tue Aug 9 23:07:05 UTC 2005, it works on my ia32 and EM64T machines. It could be a regression since then, or a hardware bug. Your machine has sse while __builtin_ia32_ldmxcsr (mxcsr) segfaults. Please report (gdb) p/x $pc (gdb) info reg (gdb) disass when it segfaults.
$ gcc -g -ffast-math hello.c $ gdb ./a.out GNU gdb 6.3-debian Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) r Starting program: /home/ig25/Krempel/a.out Program received signal SIGSEGV, Segmentation fault. 0x08048469 in set_fast_math () at ../../gcc-4.1/gcc/config/i386/crtfastmath.c:70 70 __builtin_ia32_ldmxcsr (mxcsr); (gdb) p/x $pc $1 = 0x8048469 (gdb) info reg eax 0x681 1665 ecx 0x0 0 edx 0x2000000 33554432 ebx 0x80495b4 134518196 esp 0xbffff570 0xbffff570 ebp 0xbffff578 0xbffff578 esi 0x0 0 edi 0x80483c0 134513600 eip 0x8048469 0x8048469 eflags 0x210206 2163206 cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb) disass Dump of assembler code for function set_fast_math: 0x08048420 <set_fast_math+0>: push %ebp 0x08048421 <set_fast_math+1>: mov %esp,%ebp 0x08048423 <set_fast_math+3>: push %esi 0x08048424 <set_fast_math+4>: sub $0x4,%esp 0x08048427 <set_fast_math+7>: pushf 0x08048428 <set_fast_math+8>: pushf 0x08048429 <set_fast_math+9>: pop %eax 0x0804842a <set_fast_math+10>: mov %eax,%edx 0x0804842c <set_fast_math+12>: xor $0x200000,%eax 0x08048431 <set_fast_math+17>: push %eax 0x08048432 <set_fast_math+18>: popf 0x08048433 <set_fast_math+19>: pushf 0x08048434 <set_fast_math+20>: pop %eax 0x08048435 <set_fast_math+21>: popf 0x08048436 <set_fast_math+22>: xor %edx,%eax 0x08048438 <set_fast_math+24>: test $0x200000,%eax 0x0804843d <set_fast_math+29>: je 0x8048470 <set_fast_math+80> 0x0804843f <set_fast_math+31>: xor %eax,%eax 0x08048441 <set_fast_math+33>: xchg %ebx,%esi 0x08048443 <set_fast_math+35>: cpuid 0x08048445 <set_fast_math+37>: xchg %ebx,%esi 0x08048447 <set_fast_math+39>: test %eax,%eax 0x08048449 <set_fast_math+41>: je 0x8048470 <set_fast_math+80> 0x0804844b <set_fast_math+43>: mov $0x1,%eax ---Type <return> to continue, or q <return> to quit--- 0x08048450 <set_fast_math+48>: xchg %ebx,%esi 0x08048452 <set_fast_math+50>: cpuid 0x08048454 <set_fast_math+52>: xchg %ebx,%esi 0x08048456 <set_fast_math+54>: and $0x2000000,%edx 0x0804845c <set_fast_math+60>: je 0x8048470 <set_fast_math+80> 0x0804845e <set_fast_math+62>: stmxcsr 0xfffffff8(%ebp) 0x08048462 <set_fast_math+66>: orl $0x8040,0xfffffff8(%ebp) 0x08048469 <set_fast_math+73>: ldmxcsr 0xfffffff8(%ebp) 0x0804846d <set_fast_math+77>: lea 0x0(%esi),%esi 0x08048470 <set_fast_math+80>: pop %eax 0x08048471 <set_fast_math+81>: pop %esi 0x08048472 <set_fast_math+82>: pop %ebp 0x08048473 <set_fast_math+83>: ret End of assembler dump. (gdb)
So it died at 0x08048469 <set_fast_math+73>: ldmxcsr 0xfffffff8(%ebp) What does (gdb) p/x *(int *) ($ebp - 8) say?
(gdb) r Starting program: /home/ig25/Krempel/a.out Program received signal SIGSEGV, Segmentation fault. 0x08048469 in set_fast_math () at ../../gcc-4.1/gcc/config/i386/crtfastmath.c:70 70 __builtin_ia32_ldmxcsr (mxcsr); (gdb) p/x *(int *) ($ebp - 8) $1 = 0x9fc0
For some reason, ldmxcsr doesn't work on your machine. The assembly code looks correct to me. I don't have any problems on IA32. I can only assume that you have a hardware or OS related issue. Can you verify if ldmxcsr works on your machine? [hjl@gnu-13 tmp]$ cat x.c #define MXCSR_DAZ (1 << 6) /* Enable denormals are zero mode */ #define MXCSR_FTZ (1 << 15) /* Enable flush to zero mode */ int main (void) { { unsigned int mxcsr = __builtin_ia32_stmxcsr (); mxcsr |= MXCSR_DAZ | MXCSR_FTZ; __builtin_ia32_ldmxcsr (mxcsr); } return 0; } [hjl@gnu-13 tmp]$ gcc x.c [hjl@gnu-13 tmp]$ ./a.out
This also segfaults (see below). I am also seeing the gfortran testsuite failure prompted by this problem on http://gcc.gnu.org/ml/gcc-testresults/2005-08/msg00694.html and http://gcc.gnu.org/ml/gcc-testresults/2005-08/msg00683.html , so this is not a local issue. (gdb) r Starting program: /home/ig25/Krempel/a.out Program received signal SIGSEGV, Segmentation fault. 0x08048367 in main () at x.c:10 10 __builtin_ia32_ldmxcsr (mxcsr); (gdb) disassemble Dump of assembler code for function main: 0x08048334 <main+0>: push %ebp 0x08048335 <main+1>: mov %esp,%ebp 0x08048337 <main+3>: sub $0x18,%esp 0x0804833a <main+6>: and $0xfffffff0,%esp 0x0804833d <main+9>: mov $0x0,%eax 0x08048342 <main+14>: add $0xf,%eax 0x08048345 <main+17>: add $0xf,%eax 0x08048348 <main+20>: shr $0x4,%eax 0x0804834b <main+23>: shl $0x4,%eax 0x0804834e <main+26>: sub %eax,%esp 0x08048350 <main+28>: stmxcsr 0xffffffec(%ebp) 0x08048354 <main+32>: mov 0xffffffec(%ebp),%eax 0x08048357 <main+35>: mov %eax,0xfffffffc(%ebp) 0x0804835a <main+38>: orl $0x8040,0xfffffffc(%ebp) 0x08048361 <main+45>: mov 0xfffffffc(%ebp),%eax 0x08048364 <main+48>: mov %eax,0xffffffec(%ebp) 0x08048367 <main+51>: ldmxcsr 0xffffffec(%ebp) 0x0804836b <main+55>: mov $0x0,%eax 0x08048370 <main+60>: leave 0x08048371 <main+61>: ret End of assembler dump. (gdb) p/x $pc $1 = 0x8048367
Checking the Intel IA-32 ASDM, it says that the DAZ bit was introduced in Pentium 4 and Xeon as an SSE2 extension, and that not even all Pentium 4 processors support it. See Volume 1 Section 10.2.2.4 "Denormals-Are-Zeros", paragraphs 4 and 5. See also the section it refers to, Volume 1 Section 11.6.3 "Checking for the DAZ Flag in the MXCSR Register" which explains that the only safe way to use the DAZ bit is to first use FXSAVE, and then check the MXCSR_MASK. It says nothing special about the FZ bit, so that part is apparently OK. This Intel documentation is available from the Intel web site.
A patch is posted at http://gcc.gnu.org/ml/gcc-patches/2005-08/msg00787.html
Subject: Bug 23360 CVSROOT: /cvs/gcc Module name: gcc Changes by: hjl@gcc.gnu.org 2005-08-14 14:26:51 Modified files: gcc : ChangeLog gcc/config/i386: crtfastmath.c Log message: 2005-08-14 H.J. Lu <hongjiu.lu@intel.com> PR target/23360 * config/i386/crtfastmath.c (set_fast_math): Check if DAZ is available for setting it. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.9726&r2=2.9727 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/i386/crtfastmath.c.diff?cvsroot=gcc&r1=1.1&r2=1.2
Fixed.