Bug 44448 - 32-bit gfortran.dg/atan2_1.f90 fails on Solaris 1[01]/x86 at -O0
Summary: 32-bit gfortran.dg/atan2_1.f90 fails on Solaris 1[01]/x86 at -O0
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: 4.5.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-06-07 16:42 UTC by Rainer Orth
Modified: 2010-06-25 18:36 UTC (History)
2 users (show)

See Also:
Host: i386-pc-solaris2.1[01]
Target: i386-pc-solaris2.1[01]
Build: i386-pc-solaris2.1[01]
Known to work: 4.5.1 4.6.0
Known to fail:
Last reconfirmed:


Attachments
gfortran -fdump-tree-original output (523 bytes, text/plain)
2010-06-16 16:16 UTC, Rainer Orth
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Orth 2010-06-07 16:42:19 UTC
The last remaining gfortran testsuite failure on Solaris 10/11 x86 is

FAIL: gfortran.dg/atan2_1.f90  -O0  execution test

(only for 32-bit).  The test aborts at l.12:

do i = 1, 10
  if(atan(1.0,  i/10.0)  -atan2(1.0,  i/10.)    /= 0.0)   call abort()
  if(atan(1.0d0,i/10.0d0)-atan2(1.0d0,i/10.0d0) /= 0.0d0) call abort()
end do

at the first if for i=1.  This is very strange, since I've verified that
atan2f is called both times with identical args.  I'm uncertain how to proceed
from here and don't know how to investigate the i387 floating point registers
in gdb.
Comment 1 Francois-Xavier Coudert 2010-06-11 13:51:00 UTC
>   if(atan(1.0,  i/10.0)  -atan2(1.0,  i/10.)    /= 0.0)   call abort()

Try to change that into a "print *, atan(1.0,  i/10.0)  -atan2(1.0,  i/10.)" and see what it outputs.
Comment 2 ro@CeBiTec.Uni-Bielefeld.DE 2010-06-15 14:09:52 UTC
Subject: Re:  32-bit gfortran.dg/atan2_1.f90 fails on Solaris 1[01]/x86 at -O0

> ------- Comment #1 from fxcoudert at gcc dot gnu dot org  2010-06-11 13:51 -------
>>   if(atan(1.0,  i/10.0)  -atan2(1.0,  i/10.)    /= 0.0)   call abort()
>
> Try to change that into a "print *, atan(1.0,  i/10.0)  -atan2(1.0,  i/10.)"
> and see what it outputs.

Only changing the first line, I get

 -4.35482832E-08
Abort

Changing the second line, too, gives

 -4.35482832E-08
 -1.08094956596804792E-016
  4.33012666E-08
  4.38017677684143791E-017
  3.05452623E-08
  3.33934269125535366E-017
  2.96684455E-08
 -5.76795555762288359E-017
  4.87235496E-08
 -9.40003283544932344E-017
 -1.70394934E-08
  2.55871712706579046E-017
  1.22149613E-09
 -3.88144377749810587E-017
  2.30690667E-08
 -2.16840434497100887E-018
 -1.41206291E-08
 -8.18572640226555848E-018
  2.18556941E-08
 -3.06287113727155003E-017

	Rainer
Comment 3 Francois-Xavier Coudert 2010-06-15 20:10:17 UTC
(In reply to comment #2)
>> Try to change that into a "print *, atan(1.0,  i/10.0)  -atan2(1.0,  i/10.)"
>> and see what it outputs.
> 
> Only changing the first line, I get
> 
>  -4.35482832E-08
> Abort

Changing only the first line, could you compile with -fdump-tree-original and attach the *.f90.003t.original file that gets generated?
Comment 4 Rainer Orth 2010-06-16 16:16:13 UTC
Created attachment 20929 [details]
gfortran -fdump-tree-original output
Comment 5 Francois-Xavier Coudert 2010-06-16 21:30:35 UTC
This makes no sense at all. Rainer, I'm really sorry if it seems that I'm shooting questions a bit at random, but I have a hard time imagining how to narrow it down.

Can you try the following equivalent C code (at -O0):


#include <math.h>
#include <stdio.h>

int main (void)
{
  int i;
  float x;
  double y;

  for (i = 1; i <= 10; i++)
  {
    x = __builtin_atan2f (1.f, (float) i / 10.f)
	- __builtin_atan2f (1.f, (float) i / 10.f);
    printf ("%g\n", x);

    x = atan2f (1.f, (float) i / 10.f)
	- atan2f (1.f, (float) i / 10.f);
    printf ("%g\n", x);

    y = __builtin_atan2 (1., (double) i / 10.)
	- __builtin_atan2 (1., (double) i / 10.);
    printf ("%lg\n", y);

    y = atan2 (1., (double) i / 10.)
	- atan2 (1., (double) i / 10.);
    printf ("%lg\n", y);
  }

  return 0;
}


Right now, the only thing I can see make sense is numerically instability in the libm. Also, how are atan2f and atan2 defined in the system's math.h header? Do they have simple prototypes? Are they actually macros?
Comment 6 kargls 2010-06-16 21:51:51 UTC
(In reply to comment #5)
> This makes no sense at all. Rainer, I'm really sorry if it seems that I'm
> shooting questions a bit at random, but I have a hard time imagining how to
> narrow it down.
> 
> Can you try the following equivalent C code (at -O0):
> 
>

(Code)

> 
> 
> Right now, the only thing I can see make sense is numerically instability in
> the libm. Also, how are atan2f and atan2 defined in the system's math.h header?
> Do they have simple prototypes? Are they actually macros?
> 

Does -ffloat-store change the outcome?  This looks to possibly
be an excess precision problem and the difference between something
in a register and main memory.

Comment 7 ro@CeBiTec.Uni-Bielefeld.DE 2010-06-21 12:47:16 UTC
Subject: Re:  32-bit gfortran.dg/atan2_1.f90 fails on Solaris 1[01]/x86 at -O0

> ------- Comment #6 from kargl at gcc dot gnu dot org  2010-06-16 21:51 -------
> (In reply to comment #5)
>> This makes no sense at all. Rainer, I'm really sorry if it seems that I'm
>> shooting questions a bit at random, but I have a hard time imagining how to
>> narrow it down.
>> 
>> Can you try the following equivalent C code (at -O0):

Sure: same differences as in the Fortran case:

-4.35483e-08
-4.35483e-08
-1.08095e-16
-1.08095e-16
4.33013e-08
4.33013e-08
4.38018e-17
4.38018e-17
3.05453e-08
3.05453e-08
3.33934e-17
3.33934e-17
2.96684e-08
2.96684e-08
-5.76796e-17
-5.76796e-17
4.87235e-08
4.87235e-08
-9.40003e-17
-9.40003e-17
-1.70395e-08
-1.70395e-08
2.55872e-17
2.55872e-17
1.2215e-09
1.2215e-09
-3.88144e-17
-3.88144e-17
2.30691e-08
2.30691e-08
-2.1684e-18
-2.1684e-18
-1.41206e-08
-1.41206e-08
-8.18573e-18
-8.18573e-18
2.18557e-08
2.18557e-08
-3.06287e-17
-3.06287e-17

>> Right now, the only thing I can see make sense is numerically instability in
>> the libm. Also, how are atan2f and atan2 defined in the system's math.h header?
>> Do they have simple prototypes? Are they actually macros?

The declarations are in <iso/math_c99.h>:

<iso/math_c99.h>:

extern float atanf __P((float));
extern float atan2f __P((float, float));

#if !defined(__cplusplus)
#pragma does_not_read_global_data(acosf, asinf, atanf, atan2f)
#pragma does_not_write_global_data(acosf, asinf, atanf, atan2f)

#if defined(__MATHERR_ERRNO_DONTCARE)
#pragma no_side_effect(acosf, asinf, atanf, atan2f)

> Does -ffloat-store change the outcome?  This looks to possibly
> be an excess precision problem and the difference between something
> in a register and main memory.

Indeed: with -ffloat-store, the test program only prints 0s.

	Rainer
Comment 8 Jerry DeLisle 2010-06-22 01:24:20 UTC
atan2_1.f90 has failed on other platforms before too.  I think we just need:

 ! { dg-options "-ffloat-store" }

or maybe this

 ! { dg-options "-O0 -ffloat-store" }

in the test file.  Can you try that and see if it clears your problem. Add it right after the line that says ! { dg-do run }
Comment 9 ro@CeBiTec.Uni-Bielefeld.DE 2010-06-22 15:42:32 UTC
Subject: Re:  32-bit gfortran.dg/atan2_1.f90 fails on Solaris 1[01]/x86 at -O0

> ------- Comment #8 from jvdelisle at gcc dot gnu dot org  2010-06-22 01:24 -------
> atan2_1.f90 has failed on other platforms before too.  I think we just need:
>
>  ! { dg-options "-ffloat-store" }
>
> or maybe this
>
>  ! { dg-options "-O0 -ffloat-store" }
>
> in the test file.  Can you try that and see if it clears your problem. Add it
> right after the line that says ! { dg-do run }

The first variant works like a charm: this way, we still iterate over
several optimization levels, which would be defeated by the second one.

	Rainer
Comment 10 ro@CeBiTec.Uni-Bielefeld.DE 2010-06-25 16:49:27 UTC
Subject: Re:  32-bit gfortran.dg/atan2_1.f90 fails on Solaris 1[01]/x86 at -O0

>> ------- Comment #8 from jvdelisle at gcc dot gnu dot org  2010-06-22 01:24 -------
>> atan2_1.f90 has failed on other platforms before too.  I think we just need:
>>
>>  ! { dg-options "-ffloat-store" }
>>
>> or maybe this
>>
>>  ! { dg-options "-O0 -ffloat-store" }
>>
>> in the test file.  Can you try that and see if it clears your problem. Add it
>> right after the line that says ! { dg-do run }
>
> The first variant works like a charm: this way, we still iterate over
> several optimization levels, which would be defeated by the second one.

How should we proceed from here?  Should I formally propose the patch
above?

	Rainer
Comment 11 Jerry DeLisle 2010-06-25 18:22:37 UTC
Please go ahead and commit, OK by me.
Comment 12 Rainer Orth 2010-06-25 18:32:11 UTC
Subject: Bug 44448

Author: ro
Date: Fri Jun 25 18:31:33 2010
New Revision: 161392

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161392
Log:
2010-06-25  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR fortran/44448
	* gfortran.dg/atan2_1.f90: Add -ffloat-store.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/atan2_1.f90

Comment 13 Rainer Orth 2010-06-25 18:33:37 UTC
Subject: Bug 44448

Author: ro
Date: Fri Jun 25 18:33:01 2010
New Revision: 161393

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161393
Log:
2010-06-25  Jerry DeLisle  <jvdelisle@gcc.gnu.org>

	PR fortran/44448
	* gfortran.dg/atan2_1.f90: Add -ffloat-store.

Modified:
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_5-branch/gcc/testsuite/gfortran.dg/atan2_1.f90

Comment 14 Rainer Orth 2010-06-25 18:36:39 UTC
Thanks, installed on mainline and 4.5 branch.