Bug 23360 - [4.1 regression] -ffast-math startup broken on i686 (maybe Athlon-xp)
Summary: [4.1 regression] -ffast-math startup broken on i686 (maybe Athlon-xp)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2005-08-12 18:41 UTC by Thomas Koenig
Modified: 2005-08-14 14:29 UTC (History)
2 users (show)

See Also:
Host:
Target: i686-pc-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-08-12 18:43:28


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2005-08-12 18:41:54 UTC
$ 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
Comment 1 Andrew Pinski 2005-08-12 18:43:28 UTC
Someone is not testing the correct flags.
Comment 2 H.J. Lu 2005-08-12 20:09:42 UTC
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.
Comment 3 Thomas Koenig 2005-08-12 20:22:18 UTC
$ 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)
Comment 4 H.J. Lu 2005-08-12 20:33:51 UTC
So it died at

0x08048469 <set_fast_math+73>:  ldmxcsr 0xfffffff8(%ebp)

What does

(gdb) p/x *(int *) ($ebp - 8)

say?
Comment 5 Thomas Koenig 2005-08-12 20:37:12 UTC
(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
Comment 6 H.J. Lu 2005-08-12 21:51:04 UTC
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
Comment 7 Thomas Koenig 2005-08-12 22:29:22 UTC
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
Comment 8 Jim Wilson 2005-08-12 23:25:18 UTC
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.
Comment 9 H.J. Lu 2005-08-13 00:34:18 UTC
A patch is posted at

http://gcc.gnu.org/ml/gcc-patches/2005-08/msg00787.html
Comment 10 GCC Commits 2005-08-14 14:27:01 UTC
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

Comment 11 Andrew Pinski 2005-08-14 14:29:28 UTC
Fixed.