Bug 33561 - Wrong code for single precision math functions on x86_64-pc-mingw32
Summary: Wrong code for single precision math functions on x86_64-pc-mingw32
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2007-09-26 11:33 UTC by Francois-Xavier Coudert
Modified: 2007-09-26 14:47 UTC (History)
2 users (show)

See Also:
Host: i386-pc-mingw32
Target: x86_64-pc-mingw32
Build: i386-pc-mingw32
Known to work:
Known to fail:
Last reconfirmed: 2007-09-26 11:45:30


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2007-09-26 11:33:40 UTC
I have had a bug report from people who tested my gfortran binaries for mingw-w64 that the float variants of math functions aren't working properly. The proper report that was sent to me has this example:

C:\gfortran\test\single_bug>type table.f90
program table
  real x
  integer i
  write(*,*) '   x     sin(x)    cos(x)   tan(x)'
  do i = 0, 10
     x = i
     write(*,*) x, sin(x), cos(x), tan(x)
  end do
end program table

C:\gfortran\test\single_bug>c:\gfortran\win64\bin\x86_64-pc-mingw32-gfortran table.f90 -o table

C:\gfortran\test\single_bug>table
   x     sin(x)    cos(x)   tan(x)
  0.000000       0.000000       0.000000       0.000000
  1.000000       1.000000       1.000000       1.000000
  2.000000         2.0000         2.0000         2.0000
  3.000000         3.0000         3.0000         3.0000
  4.000000         4.0000         4.0000         4.0000
  5.000000         5.0000         5.0000         5.0000
  6.000000         6.0000         6.0000         6.0000
  7.000000         7.0000         7.0000         7.0000
  8.000000         8.0000         8.0000         8.0000
  9.000000         9.0000         9.0000         9.0000
  10.00000        10.0000        10.0000        10.0000


Indeed, there is a difference between a C function that calls sinf():

#include <math.h>
float foo(float *x) { return sinf(*x); }

which is compiled into:

_foo:
LFB47:
        pushq   %rbp
LCFI0:
        movq    %rsp, %rbp
LCFI1:
        subq    $32, %rsp
LCFI2:
        movq    %rcx, 16(%rbp)
        movq    16(%rbp), %rax
        movss   (%rax), %xmm0
        call    _sinf
        leave
        ret

and the equivalent Fortran function:

  real function foo(x)
    real x
    foo = sin(x)
  end function foo

that is compiled into:


_foo_:
LFB2:
        pushq   %rbp
LCFI0:
        movq    %rsp, %rbp
LCFI1:
        subq    $64, %rsp
LCFI2:
        movq    %rcx, 16(%rbp)
        movq    16(%rbp), %rax
        movss   (%rax), %xmm0
        call    _sinf
        movss   %xmm0, -4(%rbp)
        movl    -4(%rbp), %eax
        movl    %eax, -20(%rbp)
        movss   -20(%rbp), %xmm0
        leave
        ret

(Notice the extra lines between the call to _sinf and the leave.)
Comment 1 Uroš Bizjak 2007-09-26 12:00:47 UTC
(In reply to comment #0)

> (Notice the extra lines between the call to _sinf and the leave.)

-O2 will remove these lines (as well as the lines above _sinf):

BTW: Could you check if _sinf returns values in %xmm0 reg?
Comment 2 Richard Biener 2007-09-26 12:03:02 UTC
There is nothing wrong with the extra asm instructions.
Comment 3 Kai Tietz 2007-09-26 12:52:22 UTC
This doesn't seems to be an error in gcc. The w64 crt currently does not implement some math functions proper. May somebody can assist to port the assemble coded function for this target.
Comment 4 Francois-Xavier Coudert 2007-09-26 14:47:27 UTC
Sorry for the wrong report, and thanks.