gcc/config/rs6000/aix51.h and gcc/config/rs6000/aix52.h both define
TARGET_C99_FUNCTIONS. This seems to be wrong for AIX 5.1: it has xxxl
functions, but not xxxf ones.
Source code:
=== CUT ===
extern double sqrt(double);
float f(float x)
{
return sqrt(x);
}
int main()
{
return f(1.0f) != 1.0f;
}
=== CUT ===
"gcc -v" output:
=== CUT ===
Reading specs from /bmc/moe/lib/gcc/powerpc-ibm-aix5.1.0.0/3.4.3/specs
Configured with: /depot/gnu/gcc-3.4.3/configure --prefix=/bmc/moe
--srcdir=/depot/gnu/gcc-3.4.3 --exec-prefix=/bmc/moe
--with-local-prefix=/bmc/moe --enable-shared --with-as=/usr/bin/as
--with-ld=/usr/bin/ld --enable-threads=posix --with-x --enable-java-awt=xlib
--disable-nls
Thread model: aix
gcc version 3.4.3
=== CUT ===
"oslevel -r" output:
5100-04
"lslpp -l bos.adt.libm" output:
=== CUT ===
Fileset Level State Description
----------------------------------------------------------------------------
Path: /usr/lib/objrepos
bos.adt.libm 5.1.0.25 COMMITTED Base Application Development
Math Library
=== CUT ===
"gcc <file> -O -lm" output:
ld: 0711-317 ERROR: Undefined symbol: .sqrtf
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
collect2: ld returned 8 exit status
The problem becomes even worse for C++ code:
libstdc++ correctly detects that (e.g.) sqrtf() is missing, and generates a stub
that calls sqrt(). But the compiler converts that sqrt() call back into
sqrtf(), resulting in infinite recursion! The following example triggers this:
=== CUT ===
#include <cmath>
int main()
{
return std::sqrt(1.0f) != 1.0f;
}
=== CUT ===
The macro was defined for AIX 5.1 by Roger Sayle:
2003-07-04 Roger Sayle <roger@eyesopen.com>
* config/rs6000/aix51.h (TARGET_C99_FUNCTIONS): Define.
* config/rs6000/aix52.h (TARGET_C99_FUNCTIONS): Likewise.
Unfortunately, the AIX 5.1 machine that was loaned to OpenEye by IBM has had to
be returned since this patch was submitted/applied in 2003. So my only guess is
that this may have been a patch level issue with bos.adt.libm as I'm fairly
confident that our 5.1 machine had sqrtf and friends when the patch was
developed. We do still have a 5.2 machine, and that certainly has sqrtf.
Could this be related to the version(s) of IBM's Visual Age C/C++, that was
installed on the machine?
Unfortunately, without access to a 5.1 box I'm unable to properly test the
obvious trivial change to config/rs6000/aix51.h. Clearly, if there are flavors
of AIX 5.1 out there without sqrtf, it unsafe to define TARGET_C99_FUNCTIONS in
aix51.h. Fortunately, such a change won't negatively affect users of AIX 5.2 or
later.
Dave, I'm happy to post an untested patch to gcc-patches if that's appropriate.
Alternatively, Lev could you try removing the five lines I added to aix51.h and
confirm that that resolves the issues you're seeing.
Many thanks in advance. Sorry for any inconvenience.
It might be an issue with the patch level of libm -- I was testing on 5.1 ML04,
which was released in 2002 -- but I've found another machine at ML05 (released
in Oct 2003), and it still doesn't have sqrtf and friends in libm. I don't have
access to anything newer than that right now.
I doubt it's related to Visual Age. VAC's implementation of the standard C++
library, /usr/lib/libC.a, does have sqrtf and friends -- but I'm not linking
with it when using GCC.
Before submitting the bug report, I tried removing the macro definition in
aix51.h, and it does solve the problem. There is a related C++-specific problem
that still isn't solved, but maybe that merits a separate PR. The problem is:
If you have C++ code that uses std::sqrt(float) and build a dynamically linked
executable on AIX 5.1, then bring it over to AIX 5.2, it won't run, because
sqrtf() is now in libm, but not in libstdc++. This doesn't seem to be a problem
on other platforms (for example, a program compiled on Solaris 8, against
sqrtf() in libstdc++, runs fine on Solaris 10, with sqrtf() in libm), but on AIX
the dynamic loader looks for a symbol only in a specific library. I am guessing
it's a difference between COFF and ELF?
As a side point, TARGET_C99_FUNCTION isn't defined on any Solaris platforms. I
think it's okay to define it on Solaris 9 and up?
(In reply to comment #4)
> If you have C++ code that uses std::sqrt(float) and build a dynamically linked
> executable on AIX 5.1, then bring it over to AIX 5.2, it won't run, because
> sqrtf() is now in libm, but not in libstdc++. This doesn't seem to be a problem
> on other platforms (for example, a program compiled on Solaris 8, against
> sqrtf() in libstdc++, runs fine on Solaris 10, with sqrtf() in libm), but on AIX
> the dynamic loader looks for a symbol only in a specific library. I am guessing
> it's a difference between COFF and ELF?
That is not a bug, you cannot do that as libstdc++ is not forward compatiable, this is also happens on
Darwin (Mac OS X).
> As a side point, TARGET_C99_FUNCTION isn't defined on any Solaris platforms. I
> think it's okay to define it on Solaris 9 and up?
Only Solaris 10 has full C99 math support out of the box (and after a bit of
tweaking to make it usable for GCC).
Andrew: I am trying to run older (5.1) programs on a newer (5.2) system, not
vice versa -- why would that require forward (rather than backward) compatibility?
Reset target milestone to 4.0.2.
(Gaby and I have a standing agreement that the more current release branch gets
the target milestone.)
Patch OK for 4.0.2.
Description Lev Makhlis 2005-06-15 20:56:09 UTC
gcc/config/rs6000/aix51.h and gcc/config/rs6000/aix52.h both define TARGET_C99_FUNCTIONS. This seems to be wrong for AIX 5.1: it has xxxl functions, but not xxxf ones. Source code: === CUT === extern double sqrt(double); float f(float x) { return sqrt(x); } int main() { return f(1.0f) != 1.0f; } === CUT === "gcc -v" output: === CUT === Reading specs from /bmc/moe/lib/gcc/powerpc-ibm-aix5.1.0.0/3.4.3/specs Configured with: /depot/gnu/gcc-3.4.3/configure --prefix=/bmc/moe --srcdir=/depot/gnu/gcc-3.4.3 --exec-prefix=/bmc/moe --with-local-prefix=/bmc/moe --enable-shared --with-as=/usr/bin/as --with-ld=/usr/bin/ld --enable-threads=posix --with-x --enable-java-awt=xlib --disable-nls Thread model: aix gcc version 3.4.3 === CUT === "oslevel -r" output: 5100-04 "lslpp -l bos.adt.libm" output: === CUT === Fileset Level State Description ---------------------------------------------------------------------------- Path: /usr/lib/objrepos bos.adt.libm 5.1.0.25 COMMITTED Base Application Development Math Library === CUT === "gcc <file> -O -lm" output: ld: 0711-317 ERROR: Undefined symbol: .sqrtf ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information. collect2: ld returned 8 exit status The problem becomes even worse for C++ code: libstdc++ correctly detects that (e.g.) sqrtf() is missing, and generates a stub that calls sqrt(). But the compiler converts that sqrt() call back into sqrtf(), resulting in infinite recursion! The following example triggers this: === CUT === #include <cmath> int main() { return std::sqrt(1.0f) != 1.0f; } === CUT ===Comment 1 David Edelsohn 2005-06-17 13:56:51 UTC
Comment 3 roger 2005-06-17 17:22:06 UTC
Comment 4 Lev Makhlis 2005-06-17 19:01:31 UTC
Comment 5 Andrew Pinski 2005-06-17 19:05:16 UTC
Comment 6 Eric Botcazou 2005-06-17 19:13:12 UTC
> As a side point, TARGET_C99_FUNCTION isn't defined on any Solaris platforms. I > think it's okay to define it on Solaris 9 and up? Only Solaris 10 has full C99 math support out of the box (and after a bit of tweaking to make it usable for GCC).Comment 7 Lev Makhlis 2005-06-17 19:32:25 UTC
Comment 9 Andrew Pinski 2005-06-30 21:54:43 UTC
Comment 10 Mark Mitchell 2005-07-06 16:28:34 UTC
Comment 13 David Edelsohn 2005-07-08 18:35:04 UTC