Bug 24313 - complex sqrt function does not return principal value
Summary: complex sqrt function does not return principal value
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 25017 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-10-11 17:27 UTC by Mick Pont
Modified: 2006-10-29 11:58 UTC (History)
2 users (show)

See Also:
Host:
Target: x86_64-*-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Mick Pont 2005-10-11 17:27:28 UTC
This program demonstrates a bug in the complex sqrt function
in gfortran. When complex number x = (0.0,-1.0), the result comes
back as the negative of the expected result. Of course, the negative
of the expected result is still a square root of the original
number, but the f95 standard says that the principal square root
should be returned, i.e. the real part of the result should be positive.

      complex x, y
      x = cmplx(0.0,-1.0)
      y = sqrt(x)
      write (*,*) x, y
      x = cmplx(0.0+1.0e-38,-1.0)
      y = sqrt(x)
      write (*,*) x, y
      x = cmplx(0.0-1.0e-38,-1.0)
      y = sqrt(x)
      write (*,*) x, y
      end

The results I get are

% gfortran -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/var/tmp/gfortran-20051007/irun --enable-languages=c,f95
Thread model: posix
gcc version 4.1.0 20051007 (experimental)

% gfortran sqrt.f
% ./a.out
 (  0.000000    , -1.000000    ) (-0.7071068    , 0.7071068    )
 ( 9.9999994E-39, -1.000000    ) ( 0.7071068    ,-0.7071068    )
 (-9.9999994E-39, -1.000000    ) ( 0.7071068    ,-0.7071068    )

Using a tiny number in place of the zero real part shows the
correct results.

This also affects the double complex version of sqrt.
Comment 1 Andrew Pinski 2005-10-11 17:31:54 UTC
Hmm, I think this is a bug in glibc's csqrt. as I get the following on powerpc-darwin:
 (  0.000000    , -1.000000    ) ( 0.7071068    ,-0.7071068    )
 ( 9.9999994E-39, -1.000000    ) ( 0.7071068    ,-0.7071068    )
 (-9.9999994E-39, -1.000000    ) ( 0.7071068    ,-0.7071068    )
Comment 2 Andrew Pinski 2005-10-11 17:33:25 UTC
This is a bug in glibc's csqrt as gfortran just calls it.  Please report it to them.
Comment 3 kargls 2005-10-11 18:48:45 UTC
I don't think this is a glibc problem.  gfortran will use a GCC
builtin function.  See gcc/fortran/mathbuiltins.def  To confirm 
this, I get

troutmask:kargl[210] ./z
 (  0.000000    , -1.000000    ) (-0.7071068    , 0.7071068    )
 ( 1.1754944E-38, -1.000000    ) ( 0.7071068    ,-0.7071068    )
 (-1.1754944E-38, -1.000000    ) ( 0.7071068    ,-0.7071068    )

on amd64-*-freebsd, which does not have a csqrtf in libm.

Note, I've replaced Mick's subnormal number with TINY(1.).
Comment 4 kargls 2005-10-11 19:56:08 UTC
This is definitely a gcc bug.

gfortran -fdump-tree-original csqrt.f 

yields (with removal of IO crap and shorting of long constants)

MAIN__ ()
{
  complex4 y;
  complex4 x;

  x = __complex__ (0.0, -1.0e+0);
  y = __builtin_csqrtf (x);

 x = __complex__ (1.17549435082228750796873653722224e-38, -1.0e+0);
  y = __builtin_csqrtf (x);
 
  x = __complex__ (-1.175494350822287507968736537222e-38, -1.0e+0);
  y = __builtin_csqrtf (x);

}


Note the use of __builtin_csqrtf().
Comment 5 Andrew Pinski 2005-10-11 19:58:09 UTC
(In reply to comment #4)
> Note the use of __builtin_csqrtf().

But that just calls into csqrt which is part of libm.  Look at the asm output.
Comment 6 kargls 2005-10-11 20:11:00 UTC
FreeBSD *does not* have a csqrt or csqrtf in libm!  The problem is
in intrinsics/c99_functions.c.  I'm testing a patch.
Comment 7 Andrew Pinski 2005-10-11 20:18:55 UTC
(In reply to comment #6)
> FreeBSD *does not* have a csqrt or csqrtf in libm!  The problem is
> in intrinsics/c99_functions.c.  I'm testing a patch.

But if csqrtf in c99_functions.c was pulled from glibc, then there is still a bug in glibc as this was reported with the target being x86_64-linux-gnu.
Comment 8 kargls 2005-10-11 20:21:44 UTC
Yes, I agree glibc has the bug.  But, libgfortran also has the bug
and will be present on every OS that does not have a libm with csqrt
and csqrtf.  I have a patch for libgfortran.
Comment 9 kargls 2005-10-11 20:46:35 UTC
Patch for libgfortran 

http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00626.html
Comment 10 GCC Commits 2005-10-11 23:35:30 UTC
Subject: Bug 24313

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	kargl@gcc.gnu.org	2005-10-11 23:35:27

Modified files:
	libgfortran    : ChangeLog 
	libgfortran/intrinsics: c99_functions.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/gfortran.dg: csqrt_2.f 

Log message:
	PR libgfortran/24313
	* c99_functions.c (csqrtf, csqrt): Fix choice of branch cut.  Note
	csqrt{f} were imported from glibc, and this bug is still present
	there. glibc PR is 1146.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/ChangeLog.diff?cvsroot=gcc&r1=1.320&r2=1.321
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/c99_functions.c.diff?cvsroot=gcc&r1=1.16&r2=1.17
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gfortran.dg/csqrt_2.f.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.6170&r2=1.6171

Comment 11 Andrew Pinski 2005-11-24 16:41:56 UTC
*** Bug 25017 has been marked as a duplicate of this bug. ***
Comment 12 Harald Vogt 2006-01-25 21:07:45 UTC
(In reply to comment #9)
> Patch for libgfortran 
> 
> http://gcc.gnu.org/ml/gcc-patches/2005-10/msg00626.html
> 
It is a useful strategy to use libm but...

It seems that glibc has still problems with csqrt. See also
http://sources.redhat.com/bugzilla/show_bug.cgi?id=2181
http://sources.redhat.com/bugzilla/show_bug.cgi?id=2182 .
Therefore it may be useful to check in intrinsics/configure if libm is broken in the architecture used, and if so use the code in intrinsics/c99_functions.c .
A possible solution for csqrt is shown in
http://www-zeuthen.desy.de/~hvogt/gfortran/acinclude.m4.diff .
It is better to be independend from glibc coming with the OS. This enables to install gcc4(gfortran) without patching libm if it has bugs.
Comment 13 Tobias Burnus 2006-10-29 11:57:06 UTC
Subject: Bug 24313

Author: burnus
Date: Sun Oct 29 11:56:56 2006
New Revision: 118142

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=118142
Log:
2006-10-28  Tobias Burnus  <burnus@net-b.de>

       PR libgfortran/24313
       * gfortran.dg/csqrt_2.f: Remove xfail *-*-linux-gnu.


Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/csqrt_2.f

Comment 14 Tobias Burnus 2006-10-29 11:58:12 UTC
For completeness, the two problems are in the meanwhile fixed in glibc:

- csqrt bug, fixed 2005-10-13,
http://sources.redhat.com/bugzilla/show_bug.cgi?id=1466

- cacosh bug, fixed 2006-08-03,
http://sources.redhat.com/bugzilla/show_bug.cgi?id=2182