Bug 42333 - complex division failure on darwin10 with -lm
Summary: complex division failure on darwin10 with -lm
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: other (show other bugs)
Version: 4.5.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 42074 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-12-08 16:25 UTC by Kaveh Ghazi
Modified: 2011-06-30 16:33 UTC (History)
7 users (show)

See Also:
Host:
Target: *-*-darwin10
Build:
Known to work: 4.5.4, 4.6.0
Known to fail: 4.5.3
Last reconfirmed: 2011-02-05 22:30:43


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kaveh Ghazi 2009-12-08 16:25:51 UTC
As noted in PR42074, linking with the math library on darwin10 allows overflow to occur during complex division.  It was originally reported as a failure in testcase gcc.dg/torture/builtin-math-7.c at all optimization levels.  However as described in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42074#c10 the error is related to using -lm on the reduced testcase below.  Without -lm it passes, with -lm a failure occurs.  As such, it isn't necessarily a bug in GCC, however this PR will help track if there is a possible workaround.


int main(void)
{
  volatile _Complex double val = (__DBL_MAX__ * 0.5 + __DBL_MAX__ * 0.5i);
  val /= (__DBL_MAX__ * 0.25 + __DBL_MAX__ * 0.25i);
  __builtin_printf ("%g %g\n", __real (val), __imag (val));
  if (val != 2) __builtin_abort();
  return 0;
}
Comment 1 Dominique d'Humieres 2009-12-08 16:33:58 UTC
> As such, it isn't necessarily a bug in GCC, however
> this PR will help track if there is a possible workaround.

As far as I understand the use of the gcc compilers on darwin, I do not see when I should use -lm.
So the simplest "workaround" could be to not use -lm in the testsuite at least for intel-darwin10.
If someone tells me how to do that I can do the testing.
Comment 2 Kaveh Ghazi 2009-12-08 16:46:37 UTC
(In reply to comment #1)
> > As such, it isn't necessarily a bug in GCC, however
> > this PR will help track if there is a possible workaround.
> As far as I understand the use of the gcc compilers on darwin, I do not see
> when I should use -lm.
> So the simplest "workaround" could be to not use -lm in the testsuite at least
> for intel-darwin10.
> If someone tells me how to do that I can do the testing.

I don't think that's the right approach, that would only mask the bug in the testsuite but leave it in userland.

IMHO, the first thing we need to understand is *why* the math library is the trigger.  In the assembler output from Jack in PR42074, the only function calls are to abort and __divdc3 which is a libgcc2 provided function that performs the complex division.  I don't see why -lm would override either one, let alone a GCC internal one.  You may be able to check via "nm" if libm defines it.

Oh wait, try running ldd (or the darwin equivalent) on the shared math library.  See if it (or any of its dependencies) link in a another darwin copy of libgcc2 from the system compiler.  Maybe there's an old definition of __divdc3 in there that is overriding the one from gcc-4.5 and yields a bogus result.

Also check if linking staticly solves the problem.  Thanks.
Comment 3 Dominique d'Humieres 2009-12-08 18:31:10 UTC
(In reply to comment #2)
> I don't think that's the right approach, that would only mask the bug in the
> testsuite but leave it in userland. ...

You are right, but from what follows I think the problem comes from the way the additional libs are passed to collect2.

First, without -lm, gcc45 uses the following collect2:

 /opt/gcc/gcc4.5w/libexec/gcc/x86_64-apple-darwin10/4.5.0/collect2 -dynamic -arch x86_64 -macosx_version_min 10.6.2 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/opt/gcc/gcc4.5w/lib/gcc/x86_64-apple-darwin10/4.5.0 -L/opt/gcc/gcc4.5w/lib/gcc/x86_64-apple-darwin10/4.5.0/../../.. pr42074.o -lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

and the test succeed.

Second, if I add -lm, I get

 /opt/gcc/gcc4.5w/libexec/gcc/x86_64-apple-darwin10/4.5.0/collect2 -dynamic -arch x86_64 -macosx_version_min 10.6.2 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/opt/gcc/gcc4.5w/lib/gcc/x86_64-apple-darwin10/4.5.0 -L/opt/gcc/gcc4.5w/lib/gcc/x86_64-apple-darwin10/4.5.0/../../.. pr42074.o -lm -lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem

and the text fails. Note that -lm is passed before "-lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind -lSystem".

Third, libm.dylib is a symlink to libSystem.dylib
lrwxr-xr-x 1 root wheel 15 Aug 14 22:47 /usr/lib/libm.dylib -> libSystem.dylib*
so -lm seems redundant.

Fourth, I see

[macbook] f90/bug% otool -L /usr/lib/libSystem.dylib
/usr/lib/libSystem.dylib:
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)
	/usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0, current version 315.0.0)
[macbook] f90/bug% nm /usr/lib/libSystem.B.dylib | grep divdc3
0019fa1e S $ld$hide$os10.4$___divdc3
0019fa1f S $ld$hide$os10.5$___divdc3
001640d0 T ___divdc3

Five, If I don't use -lm, but place -lSystem before "-lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind" as in

[macbook] f90/bug% /opt/gcc/gcc4.5w/libexec/gcc/x86_64-apple-darwin10/4.5.0/collect2 -dynamic -arch x86_64 -macosx_version_min 10.6.2 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/opt/gcc/gcc4.5w/lib/gcc/x86_64-apple-darwin10/4.5.0 -L/opt/gcc/gcc4.5w/lib/gcc/x86_64-apple-darwin10/4.5.0/../../.. pr42074.o -lSystem -lgcc_s.10.5 -lgcc_ext.10.5 -lgcc -no_compact_unwind

the test abort.

My uneducated conclusions are first, that -lm is redundant with -lSystem and probably should never be used (unless you ask for trouble), second, ___divdc3 uses a lazy complex division (a bug to be reported upstream!-), third, the way additional libs are passed to collect2 is probably right if one wants to overwrite functions in the default libs.

I have now access to intel-darwin9 and I'll see what going on for it after dinner time.

Comment 4 Jack Howarth 2009-12-08 19:30:05 UTC
Dominique,
    It would be interesting to know what happens with a build of gcc trunk under darwin10 if you regress out the r154282 and r154283 that introduced the libgcc_ext feature . I suspect this regression may have occurred at this point. I wasn't building with mpc before the libgcc_ext patch was committed.
Comment 5 Dominique d'Humieres 2009-12-08 19:34:08 UTC
Additional information:

(1) I don't see the problem on (i686|x86_64)-apple-darwin9.

(2) I also see it gcc version 4.4.2 (GCC).

(3) I don't see it with gcc version 4.2.1 (Apple Inc. build 5646) (dot 1).

(3) If I compile the test with 4.4.2 or 4.5 with -c, and link the object file with gcc version 4.2.1 (Apple Inc. build 5646) (dot 1), I get the abort with/without -lm.

(4) If I do the opposite (object with 4.2, link with 4.5), I don't get the abort even with -lm.

(5) collect2 for 4.2:

 /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch x86_64 -macosx_version_min 10.6.2 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64 -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. pr42074.o -lSystem -lgcc -lSystem

So my second conclusion in comment #3 may be wrong.

I think (2) answer the question in comment #4.
Comment 6 Jack Howarth 2009-12-08 19:59:36 UTC
Considering that builtin-math-7.c doesn't exist in gcc 4.4 branch, it is unclear what that test should do there. Try reverting out the libgcc_ext changes from gcc trunk on darwin10 instead.
Comment 7 Kaveh Ghazi 2009-12-08 20:24:10 UTC
(In reply to comment #6)
> Considering that builtin-math-7.c doesn't exist in gcc 4.4 branch, it is
> unclear what that test should do there. 

Jack - Focusing on builtin-math-7.c (which tests multiple things) misses the point.  The bug on darwin10 is exposed by a trivial runtime complex division.  See the code from the original description above.  That code should work on 4.4 branch, etc and that is what Dominique is compiling with other gcc versions.

Note I'm not commenting on your suggested patch revert, I don't know enough about Darwin to predict whether that will be fruitful.  I just want to make sure we all understand that the reduced testcase I provided should work on all GCC versions that support complex numbers.
Comment 8 IainS 2009-12-08 20:27:13 UTC
(In reply to comment #6)

A *Very* quick look following a prompt from Jack...

> Considering that builtin-math-7.c doesn't exist in gcc 4.4 branch, it is
> unclear what that test should do there. Try reverting out the libgcc_ext
> changes from gcc trunk on darwin10 instead.

removing the _ext should have no effect since -lgcc, which follows it, but precedes the -lSystem should cause the math function to be linked statically from libgcc.a (4.5 version)
[the _ext will cause it to be linked dynamically from libgcc_s (4.5 version)]

it seems on the face of it that there's different behavior from this function as supplied by the Darwin environment [libmath=>libSystem] and as supplied by gcc. 

Of course, it's also possible that the code differs between the static and dynamic builds of libgcc... 
Comment 9 IainS 2009-12-08 20:51:02 UTC
> version 125.0.0)
>         /usr/lib/system/libmathCommon.A.dylib (compatibility version 1.0.0,
> current version 315.0.0)
> [macbook] f90/bug% nm /usr/lib/libSystem.B.dylib | grep divdc3
> 0019fa1e S $ld$hide$os10.4$___divdc3
> 0019fa1f S $ld$hide$os10.5$___divdc3
> 001640d0 T ___divdc3

This will cause a difference in behavior:
 for Darwin9
___divdc3 is provided by /usr/lib/libgcc_s.1.dylib

libm.dylib => libSystem.dylib (which does not define ___divdc3) 

So, for darwin 10, -lm will cause the "system ___divdc3" to be used instead of the gcc one.

For Darwin 9 there is no "system provided ___divdc3" (AFAICT) .. it is supplied from libgcc_s.1.dylib.

if this is a reproducible effect with a short piece of code - one would expect if to manifest using Apple's  supplied 4.2 ... and a radar could be filed.

I was under the impression that -lm was not used by default for Darwin (determined in the build of the gcc driver) - is this flag being manually added by the test case?

Comment 10 Dominique d'Humieres 2009-12-08 21:29:07 UTC
> For Darwin 9 there is no "system provided ___divdc3" (AFAICT) .. it is supplied
> from libgcc_s.1.dylib.

I see:

[ibook-dhum] f90/bug% nm /usr/lib/libm.dylib | grep divdc3
00131270 t ___divdc3

> if this is a reproducible effect with a short piece of code - one would expect
> if to manifest using Apple's  supplied 4.2 ... and a radar could be filed.

It does not: see first item (3) of comment #5!-(I have forgotten to update the numbers when I have inserted it).
Comment 11 Dominique d'Humieres 2009-12-08 22:13:40 UTC
I think I understand why apple gcc42 does not show the problem: it does not call ___divdc3:

[macbook] f90/bug% diff -up pr42333_42.s pr42333_45.s
--- pr42333_42.s	2009-12-08 23:00:29.000000000 +0100
+++ pr42333_45.s	2009-12-08 23:00:07.000000000 +0100
...
@@ -15,68 +15,61 @@ LCFI2:
 	movq	%rax, -16(%rbp)
 	movabsq	$9214364837600034815, %rax
 	movq	%rax, -8(%rbp)
-	movq	-16(%rbp), %rax
-	movq	-8(%rbp), %rdx
-	movq	%rax, -24(%rbp)
-	movsd	-24(%rbp), %xmm1
+	movq	-16(%rbp), %rdx
+	movq	-8(%rbp), %rax
 	movq	%rdx, -24(%rbp)
 	movsd	-24(%rbp), %xmm0
-	movapd	%xmm0, %xmm2
-	addsd	%xmm1, %xmm2
-	movapd	%xmm0, %xmm3
-	subsd	%xmm1, %xmm3
-	movsd	LC1(%rip), %xmm0
-	movapd	%xmm2, %xmm1
-	divsd	%xmm0, %xmm1
-	movsd	LC1(%rip), %xmm0
-	movapd	%xmm3, %xmm2
-	divsd	%xmm0, %xmm2
-	movapd	%xmm2, %xmm0
-	movsd	%xmm1, -24(%rbp)
-	movq	-24(%rbp), %rax
+	movq	%rax, -24(%rbp)
+	movsd	-24(%rbp), %xmm1
+	movsd	LC2(%rip), %xmm3
+	movsd	LC2(%rip), %xmm2
+	call	___divdc3
 	movsd	%xmm0, -24(%rbp)
 	movq	-24(%rbp), %rdx
...

This also explain why the test compiled with -c and 4.5, but linked with 4.2 fails. So my guess about the lazy complex division seems right in libm. Could someone write a C code forcing the use of ___divdc3?
Comment 12 IainS 2009-12-08 23:40:37 UTC
(In reply to comment #11)
> I think I understand why apple gcc42 does not show the problem: it does not
> call ___divdc3:
> 
> [macbook] f90/bug% diff -up pr42333_42.s pr42333_45.s
> --- pr42333_42.s        2009-12-08 23:00:29.000000000 +0100
> +++ pr42333_45.s        2009-12-08 23:00:07.000000000 +0100
> ...
> @@ -15,68 +15,61 @@ LCFI2:
>         movq    %rax, -16(%rbp)
>         movabsq $9214364837600034815, %rax
>         movq    %rax, -8(%rbp)
> -       movq    -16(%rbp), %rax
> -       movq    -8(%rbp), %rdx
> -       movq    %rax, -24(%rbp)
> -       movsd   -24(%rbp), %xmm1
> +       movq    -16(%rbp), %rdx
> +       movq    -8(%rbp), %rax
>         movq    %rdx, -24(%rbp)
>         movsd   -24(%rbp), %xmm0
> -       movapd  %xmm0, %xmm2
> -       addsd   %xmm1, %xmm2
> -       movapd  %xmm0, %xmm3
> -       subsd   %xmm1, %xmm3
> -       movsd   LC1(%rip), %xmm0
> -       movapd  %xmm2, %xmm1
> -       divsd   %xmm0, %xmm1
> -       movsd   LC1(%rip), %xmm0
> -       movapd  %xmm3, %xmm2
> -       divsd   %xmm0, %xmm2
> -       movapd  %xmm2, %xmm0
> -       movsd   %xmm1, -24(%rbp)
> -       movq    -24(%rbp), %rax
> +       movq    %rax, -24(%rbp)
> +       movsd   -24(%rbp), %xmm1
> +       movsd   LC2(%rip), %xmm3
> +       movsd   LC2(%rip), %xmm2
> +       call    ___divdc3
>         movsd   %xmm0, -24(%rbp)
>         movq    -24(%rbp), %rdx
> ...
> 
> This also explain why the test compiled with -c and 4.5, but linked with 4.2
> fails. So my guess about the lazy complex division seems right in libm. Could
> someone write a C code forcing the use of ___divdc3?

hmm.. indeed and, in fact, Apple's gcc-4.0 does not call ___divdc3 either (in fact, in a quick go at manipulation of options I couldn't find a case forcing either to call it).

As far as generation of a test case is concerned - why not just use the asm generated by 4.5?

I'll crank up a mini with D10 tomorrow (if possible).. if the asm gives a fault on D10 with 4.2 then that should be a file-able radar.

.. seems likely that there are two things here: 1. we seem to be generating (probably) less efficient code than older versions of the compiler ... and 2. possibly the ___divdc3 in /usr/lib/libSystem is faulty?

has anyone tried this on PPC?

Comment 13 Kaveh Ghazi 2009-12-08 23:58:10 UTC
(In reply to comment #12)
> .. seems likely that there are two things here: 1. we seem to be generating
> (probably) less efficient code than older versions of the compiler ... and 2.
> possibly the ___divdc3 in /usr/lib/libSystem is faulty?

There are more than one way of generating a complex divide.  One way is faster, but it's naive (lazy) and leads to errors and overflow.  A second way is correct in more cases, but a little slower.

FSF GCC defaults to choosing correctness over speed, unless the user asks for extra speed with a special flag.  There are flags in FSF GCC for example that allow one to use the "lazy" complex divide algorithms, but the default is correctness.

It appears that the Apple GCC has chosen to have their ___divdc3 routine follow the lazy algoritm in the name of speed.  This must have been a concious choice on their part.  Therefore filing a bug report against it is likely to get a response of "works as intended."

You can try filing a bug report at Apple, but I think a better route would be to see if we can avoid linking in the system ___divdc3 from FSF GCC.
Comment 14 Kaveh Ghazi 2009-12-09 00:06:52 UTC
(In reply to comment #11)
> I think I understand why apple gcc42 does not show the problem: it does not
> call ___divdc3:

It is possible that some versions of GCC (Apple's and/or FSF's) inline the assembly code to do the divide.  That would explain why they don't call ___divdc3.  Then what happens only depends on what version of the algorithm they inline, not what they link against.


> ...
> This also explain why the test compiled with -c and 4.5, but linked with 4.2
> fails. So my guess about the lazy complex division seems right in libm. Could
> someone write a C code forcing the use of ___divdc3?

I don't think it makes sense to consider user code calling ___divdc3 directly.  According to the C standard, functions that begin with double underscore are reserved for the compiler and/or system libraries.  That is exactly how they are being used here.  The call should only be generated by the compiler itself as a service function to perform something like a complex divide.
Comment 15 Jack Howarth 2009-12-09 00:12:04 UTC
(In reply to comment #13)
> You can try filing a bug report at Apple, but I think a better route would be
> to see if we can avoid linking in the system ___divdc3  from FSF GCC.
> 

This may be impossible without having FSF gcc access its own ___divdc3 under
a different symbol name. The functionality of libgcc has been subsumed into
libSystem in darwin10 and the symbols from libgcc itself are supposed to be 
ignored in favor of those from libSystem...

http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-September/025898.html
Comment 16 Jack Howarth 2009-12-09 00:19:20 UTC
I can confirm that the gcc.dg/torture/builtin-math-7.c testcases still fail under darwin10 if the libgcc_ext changes are regressed out.
Comment 17 Kaveh Ghazi 2009-12-09 00:34:43 UTC
(In reply to comment #15)
> (In reply to comment #13)
> > You can try filing a bug report at Apple, but I think a better route would be
> > to see if we can avoid linking in the system ___divdc3  from FSF GCC.
> > 
> This may be impossible without having FSF gcc access its own ___divdc3 under
> a different symbol name. The functionality of libgcc has been subsumed into
> libSystem in darwin10 and the symbols from libgcc itself are supposed to be 
> ignored in favor of those from libSystem...
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2009-September/025898.html

I don't think we should get into a cat-and-mouse game of renaming functions that *are already FSF functions* just to avoid Apple's rewritten versions.  Who's to say they won't override the new name(s) in a future release with the same broken copy(ies)?  The sad thing is they changed ___divdc3 and they don't even emit it from their compiler. :-/

If you want to file a bug report at Apple using the FSF generated assembly (and C testcase for reference), please proceed.  I hope they fix their ___divdc3 routine.  Note there may be other complex math things they've rewritten.  Someone would need to audit Apple's compiler to see what else they've changed.

On what to do about builtin-math-7.c testcase, my inclination is we should just XFAIL it for darwin10 since fixing darwin's ___divdc3 won't help with distributions out in the field.
Comment 18 Jack Howarth 2009-12-09 01:11:41 UTC
Actually, I found this file which is quite interesting in the darwin10 libgcc open source release...

http://www.opensource.apple.com/source/libgcc/libgcc-13/stub.c
Comment 19 Dominique d'Humieres 2009-12-09 09:31:40 UTC
> As far as generation of a test case is concerned - why not just use the asm
> generated by 4.5?

I did that and the assembly generated on darwin10 works fine on darwin9. I can fill a bug report to Apple to know if its a bug (regression) or a feature.

> On what to do about builtin-math-7.c testcase, my inclination is we should just
> XFAIL it for darwin10 since fixing darwin's ___divdc3 won't help with
> distributions out in the field.

For the moment I'll prefer to keep the failure until the use of -lm in the testsuite is clarified:

My understanding of the testsuite is that it is supposed to check that the gcc compilers are working as expected on a given target. Does it make any sense to pass the tests with -lm when it is not used in normal use of the compilers? If yes, why? If no, what must be changed in gcc to run the testsuite (at least on Darwin) without adding -lm to the tests? (see also related questions in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41473#c87).

I am planning to ask these question in the gcc list, but I won't have much time to do it before this evening, so if someone want to beat me for it, he is welcome!
Comment 20 IainS 2009-12-09 11:37:46 UTC
(In reply to comment #17)
> (In reply to comment #15)
> > (In reply to comment #13)
> > > You can try filing a bug report at Apple, but I think a better route would be
> > > to see if we can avoid linking in the system ___divdc3  from FSF GCC.

Summary (for Dominique's test case):

working [regardless of placement of -lm]:
Darwin 9 [ppc/i686]
Apple 4.0,4.2 
FSF 4.5 

Darwin 10
Apple 4.0, 4.2
FSF 4.5 without -lm

FSF 4.5 fails with the placement of -lm  (which causes linkage of /usr/lib/libSystem version of  ___divdc3)

the latter can be emulated using Apple's 4.2 by compiling the asm output from FSF 4.5 for Dominique's test case.

So; Apple's two compilers that produce in-line code for ___divdc3 are apparently 'doing the right thing' (in spite of your concern about potential optimization issues).  We might look at porting the relevant .md sections to FSF ... 

The regression is in the library version of ___divdc3 supplied in Darwin10 (i.e. nothing to do with FSF gcc);  This could be radared (although as you say there is not much motivation to fix something that is unused). 

I repeat my earlier question:  
Why is -lm being used for this test case?  
Darwin, AFAIR, does not use -lm . { see comment in gcc/config/darwin.h #define MATH_LIBRARY "" }

(of course, one could argue that it should be harmless, in an ideal world)
 

Comment 21 Richard Biener 2009-12-09 11:42:26 UTC
As a workaround in gcc I suggest to strip -lm in the darwin specific specs
processing.  Otherwise this is not a GCC bug (again), but a darwin bug - why
do they always creep into gcc bugzilla ...
Comment 22 IainS 2009-12-09 15:21:21 UTC
(In reply to comment #21)
> As a workaround in gcc I suggest to strip -lm in the darwin specific specs

one could also suggest the following patch to unix.exp (or providing a darwin  infrastructure):

@@ -30,8 +30,8 @@
 
 #set_board_info host_library_path "[file dirname [file dirname [file dirname [file dirname [file dirname [exec [find_gcc] --print-prog-name=cc1]]]]]]/lib"
 
-# Do not use -lm on Cygwin 
-if { [istarget "*-*-cygwin*"] } {
+# Do not use -lm on Cygwin or Darwin 
+if { [istarget "*-*-cygwin*"] || [istarget "*-*-darwin*"]  } {
     set_board_info mathlib ""
 }
 
Comment 23 Jack Howarth 2009-12-09 16:47:57 UTC
Wouldn't that be limited to a subset of darwin....

@@ -30,8 +30,8 @@

 #set_board_info host_library_path "[file dirname [file dirname [file dirname
[file dirname [file dirname [exec [find_gcc] --print-prog-name=cc1]]]]]]/lib"

-# Do not use -lm on Cygwin 
-if { [istarget "*-*-cygwin*"] } {
+# Do not use -lm on Cygwin or Darwin 
+if { [istarget "*-*-cygwin*"] || [istarget "*-*-darwin[921]*"]  } {
     set_board_info mathlib ""
 }

I thought at some point in past c code on darwin did require linking in -lm, no?
Comment 24 IainS 2009-12-09 17:36:57 UTC
(In reply to comment #21)
> As a workaround in gcc I suggest to strip -lm in the darwin specific specs
> processing.  Otherwise this is not a GCC bug (again), but a darwin bug - why
> do they always creep into gcc bugzilla ...

well, the bug here is either in the gcc testsuite or dejagnu (depending on one's pov).  The compiler behaves as expected when provided with the correct linker flags.  The fact that this issue reveals an underlying Darwin10 bug is incidental (that bug should never bite us).



Comment 25 Mike Stump 2009-12-09 18:29:22 UTC
I've filed radr://7457013 for libSystem (aka libm on 10.6) to improve the accuracy of ___divdc3.  If that were fixed, then having -lm or not wouldn't matter.
Comment 26 Jack Howarth 2009-12-09 18:40:55 UTC
I am still a bit confused about this bug. When we leave -lm out of the linkage of builtin-math-7.exe, where does the ___divdc3 call get resolved from? Shouldn't it be coming libSystem since that always appears first on the command line? 

http://developer.apple.com/mac/library/documentation/Porting/Conceptual/PortingUnix/compiling/compiling.html suggests that should be the case...

The libSystem library also includes functions that you would normally expect to find in libc and libm, RPC services, and a name resolver. Because libSystem is automatically linked into your application, you do not need to explicitly add it to the compiler’s link line. For your convenience, many of these libraries exist as symbolic links to libSystem, so while explicitly linking against -lm (for example) is not needed, it will not cause an error.

So this sounds more like an darwin linker bug.
Comment 27 Mike Stump 2009-12-09 18:48:40 UTC
nm | grep ___divdc3 on all the objects and libraries on the link line, will tell you from where this symbol can be resolved.  Reading the link line, will tell you the order ld will resolve in, but you have to realize that .dylibs always resolve first, before .a files (such a libgcc.a).  This is explained in the ld man page.  See -search_paths_first for more detail.
Comment 28 Kaveh Ghazi 2009-12-09 18:55:50 UTC
(In reply to comment #26)
> I am still a bit confused about this bug. When we leave -lm out of the linkage
> of builtin-math-7.exe, where does the ___divdc3 call get resolved from?

The ___divdc3 function is defined in FSF GCC's libgcc2.so, which is what you want here.  That version correctly handles overflow scenarios in complex division.
Comment 29 Jack Howarth 2009-12-09 23:06:06 UTC
Ah, I understand now....

gcc-4 -O2 builtin-math-7-reduced.c
./a.out
otool -L ./a.out
./a.out:
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 246.0.0)
	/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)

gcc-4 -O2 -mmacosx-version-min=10.5 builtin-math-7-reduced.c
./a.out
Abort
otool -L ./a.out
./a.out:
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 246.0.0)
	/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)

So while at first glance, the same __divdc3 symbol from /usr/lib/libgcc_s.1.dylib should be resolved as from /usr/lib/libSystem.B.dylib...

nm /usr/lib/libgcc_s.1.dylib | grep ___divdc3
0019fa1e S $ld$hide$os10.4$___divdc3
0019fa1f S $ld$hide$os10.5$___divdc3
001640d0 T ___divdc3
nm /usr/lib/libSystem.B.dylib | grep ___divdc3
0019fa1e S $ld$hide$os10.4$___divdc3
0019fa1f S $ld$hide$os10.5$___divdc3
001640d0 T ___divdc3

without explicitly passing  -mmacosx-version-min=10.5 to gcc, the __dividc3 is ignored in  /usr/lib/libgcc_s.1.dylib and gotten from /sw/lib/gcc4.5/lib/libgcc_s.1.dylib instead. When
we pass -lm, the linkage of /usr/lib/libSystem.B.dylib provides ___dividc3.

gcc-4 -O2 builtin-math-7-reduced.c -lm
./a.out
Abort
otool -L ./a.out
./a.out:
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.0.0)
	/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 246.0.0)
	/sw/lib/gcc4.5/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)

This clears up my confusion about why usr/lib/libgcc_s.1.dylib wasn't providing ___dividc3
even though it appeared earlier in the linkage.

Comment 30 Chris Lattner 2009-12-10 23:44:30 UTC
FWIW, the darwin10 version of ___divdc3 comes from http://compiler-rt.llvm.org/  sounds like a bug there.
Comment 31 Kaveh Ghazi 2009-12-11 16:44:27 UTC
*** Bug 42074 has been marked as a duplicate of this bug. ***
Comment 32 Iain Sandoe 2010-04-09 20:45:21 UTC
(In reply to comment #21)
> As a workaround in gcc I suggest to strip -lm in the darwin specific specs
> processing.  

I think this is our best way forward. 
 We should not accept -lm if it could alter the behavior of the compiler depending on where it's put (and it's unnecessary).

In fact, this applies to darwin9 (and probably darwin8).

Now the problem I'm having is that I'm being beaten by the power of specs ... 
... %<lm should work...  right?

But.. I can't seem to find the right place to put it .. any hints most welcome.
Comment 33 Dominique d'Humieres 2010-04-09 20:56:46 UTC
(In reply to comment #32)

Note that when using the patch in comment #22 triggers pr43254: another side effect of -lm is to prevent the run of dsymutil even with -g.
Comment 34 Jack Howarth 2010-04-09 21:06:49 UTC
I thought we were going to wait for the vendor (Apple) to fix their complex math subroutines.
Comment 35 Iain Sandoe 2010-04-09 22:30:03 UTC
(In reply to comment #34)
> I thought we were going to wait for the vendor (Apple) to fix their complex
> math subroutines.

We shouldn't be affected by the bug - so, great if it gets fixed, but we still need to make sure that we link what we expect.

Comment 36 Iain Sandoe 2010-04-11 10:18:03 UTC
(In reply to comment #33)
> (In reply to comment #32)
> 
> Note that when using the patch in comment #22 triggers pr43254: another side
> effect of -lm is to prevent the run of dsymutil even with -g.

my 0,02 euro...

1. the whole dsymutil thing is a mess and  needs sorting out separately - it's not being run at all for Fortran at the moment - and it's inconsistent in any event (not run when only objects are present on the cl, for e.g.)  .. I'm going to take a look at that - but need to discuss with people what the 'correct' behavior should be.

2. we should test what is intended:
  (a) ergo Jack should submit his patch (at comment 23) to DejaGnu - if -lm is not needed on Darwin > x it should not be applied 
  (b) whilst it is "the User's Problem" if they put the wrong libraries on the C/L,  IMO we should try to help them .. therefore we should control the placement and/or inclusion of lm (this is already done for Fortran and we have a "" don't include for g++ - so there's a precedent).

3. maybe we need to look at how to work around the debug generation for darwin < 10 ;
 it's unlikely that dsymutil will be updated on those systems and, as of now, it's not part of the Open Source stuff so we can't fix it ourselves.

=====
assuming people agree with the philosophy of 2. --- on the "How To" side.
=====

It seems one can't use %<lm  to swallow '-lm'  because '-lm' is already declared as an "output file" and therefore unaffected by the process.

This trick is a bit dirty, but it works:  
translate the lib flag to something else ; act on it where required and then delete it .
* you must delete it after use - or it will error out as an unrecognized flag *

(darwin.h)
- not a patch - but guidance for anyone who wants to try it out ... 

   /* We want to be able to edit '-lm' out of the command line (or 
   control its positioning) so that math routines are provided from the
   source that we intend.  I put a -force_lm option to allow comparative
   testing .. it's not a serious proposition */

#define TARGET_OPTION_TRANSLATE_TABLE \
  { "-lm", "-Zlm" },  \
  { "-force_lm", "-lm" }, \


and then:

/* Machine dependent libraries.  
   Link -lm explicitly for versions of darwin that don't include the
   functions in libSystem, otherwise don't duplicate info. */

#define LIB_SPEC \
  "%{Zlm:%:version-compare(< 10.4 mmacosx-version-min= -lm) } %<Zlm \
   %{!static:-lSystem}"

===
in darwin10.h:

/* Machine dependent libraries.  
   Link -lm explicitly for versions of darwin that don't include the
   functions in libSystem, otherwise don't duplicate info. */

/* Fix PR41260 by passing -no_compact_unwind on darwin10 and later until
unwinder in libSystem is fixed to digest new epilog unwinding notes. */

#define LIB_SPEC \
  "%{Zlm:%:version-compare(< 10.4 mmacosx-version-min= -lm) } %<Zlm \
   %{!static:-no_compact_unwind -lSystem}"

Comment 37 Jack Howarth 2010-04-11 13:56:51 UTC
Actually, it has to be...

@@ -30,8 +30,8 @@

 #set_board_info host_library_path "[file dirname [file dirname [file dirname
[file dirname [file dirname [exec [find_gcc] --print-prog-name=cc1]]]]]]/lib"

-# Do not use -lm on Cygwin 
-if { [istarget "*-*-cygwin*"] } {
+# Do not use -lm on Cygwin or Darwin 
+if { [istarget "*-*-cygwin*"] || [istarget "*-*-darwin9*"]  || [istarget "*-*-darwin2*"]  || [istarget "*-*-darwin1*"] } {
     set_board_info mathlib ""
 }

as dejagnu doesn't appear to support the [921] regex syntax. Also, I wouldn't hold my breath for this showing up in a dejagnu release anytime soon since there hasn't been an update since 2004.
Comment 38 Jack Howarth 2010-04-11 14:47:33 UTC
Interestingly, while the change in Comment 37 eliminates the failures in gcc.dg/torture/builtin-math-7.c, it introduces the failures...

FAIL: gcc.c-torture/execute/20020412-1.c compilation,  -O3 -g 
FAIL: gcc.c-torture/execute/20040811-1.c compilation,  -O3 -g 
FAIL: gcc.c-torture/execute/pr43220.c compilation,  -O3 -g 
FAIL: gcc.c-torture/execute/vla-dealloc-1.c compilation,  -O3 -g 

These appear in the form...

Executing on host: /sw/src/fink.build/gcc45-4.5.0-0rc1/darwin_objdir/gcc/xgcc -B/sw/src/fink.build/gcc45-4.5.0-0rc1/darwin_objdir/gcc/ /sw/src/fink.build/gcc45-4.5.0-0rc1/gcc-4.5-20100410/gcc/testsuite/gcc.c-torture/execute/20020412-1.c  -w  -O3 -g      -o /sw/src/fink.build/gcc45-4.5.0-0rc1/darwin_objdir/gcc/testsuite/gcc/20020412-1.x6    (timeout = 300)
warning: DWARFDebugInfoEntry::AppendDependants() -- check on this item TAG_subrange_type: attr =  AT_upper_bound  form = FORM_ref4
output is:
warning: DWARFDebugInfoEntry::AppendDependants() -- check on this item TAG_subrange_type: attr =  AT_upper_bound  form = FORM_ref4

FAIL: gcc.c-torture/execute/20020412-1.c compilation,  -O3 -g 

I guess we should try to convert these into a test case for the existing dejagnu and open a new PR.
Comment 39 Iain Sandoe 2010-04-11 15:10:12 UTC
(In reply to comment #38)
> Interestingly, while the change in Comment 37 eliminates the failures in
> gcc.dg/torture/builtin-math-7.c, it introduces the failures...
> 
> FAIL: gcc.c-torture/execute/20020412-1.c compilation,  -O3 -g 
> FAIL: gcc.c-torture/execute/20040811-1.c compilation,  -O3 -g 
> FAIL: gcc.c-torture/execute/pr43220.c compilation,  -O3 -g 
> FAIL: gcc.c-torture/execute/vla-dealloc-1.c compilation,  -O3 -g 
> 
> These appear in the form...

This is what Dominque already reported [comment #33] (and the reason for my comments on dsymutil).

We will have to look at what to do about this - the cases have already been investigated and declared "dsymutil bug"

maybe we can add a prune command to the testcase in the short term.

Comment 40 Jack Howarth 2010-04-11 15:24:05 UTC
Has the issue in Comment 33/38 been reported on radar? If so, let me know the radar problem number and I'll ping the dsymutil developer at Apple.
Comment 41 Dominique d'Humieres 2010-04-11 15:36:02 UTC
> Has the issue in Comment 33/38 been reported on radar?

No. If you want to do it, be my guest!-(You got answer to my last one I did not get, not even an acknowledgement).
Comment 42 Iain Sandoe 2010-04-13 01:07:00 UTC
actually,

The logic in libgcc_s/libgcc_ext is working properly - libgcc_s.10.5 => /usr/libgcc_s.1.dylib => /usr/libSystem.dylib.   The function is named in /usr/lib/libgcc_s.10.5.

What is happening is Bad [at least IMO]; 
we have a "catch-all" -lgcc at the end of each REAL_LIBGCC_SPEC line - which I'm itching to remove (because, basically, it should not be necessary).

In the case of the 'working - by removing lm' what seems to be happening is that the function is being picked up from the the static libgcc.a from that catch-all.

in fact, the cases should fail regardless of -lm - since the function should be sourced from the system-library via the libgcc_s.10.5 stubs.  

[FWIW the libgcc_s.10.5 stubs should also be removed for D10 - since they don't add anything (except consumption of time) to the exercise.]

I dunno: 
I realize that people would prefer tests to pass - but I worry about the tortuous way in which we are layering libraries (I'd really like to get rid of the catch-all -lgcc) [although it could always be applied temporarily ahead of the -lSystem in the LIB_SPEC for D10].

I guess the Right Thing is to XFAIL that test until the system lib is fixed...

We should still control the use/placement of -lm --- I've not changed opinion on that.
And we should still file a "-lm not needed on Darwin" with Dejagnu (in spite of nothing likely to happen quickly).

A user who REALLY wants the functions from libgcc.a can always put it on the cl.

Comment 43 Jack Howarth 2010-04-13 01:54:05 UTC
Interestingly, if you examine clang/lib/Driver/Tools.cpp from the upcoming 2.7 release, you find...

    // FIXME: For some reason GCC passes -lgcc before adding
    // the default system libraries. Just mimic this for now.
    CmdArgs.push_back("-lgcc");

in both auroraux::Link::ConstructJob() and openbsd::Link::ConstructJob(). I'll ping one of the darwin linker developers about this.
Comment 44 Jack Howarth 2010-04-13 16:01:37 UTC
From a discussion with the clang programmers, I have this response...

> > The FIXME comment in the clang sources caught my eye because,
> > at first glance, it appears to be hinting that this usage
> > of -lgcc might be eliminated in the future.
>
> Yes, all uses of -lgcc are going to be eliminated in the near future. We expect libSystem to provide all the math routines. Of course, if they have bugs that is a problem.
>
> Note that the Clang code you reference in the bug isn 't the code used when targeting Darwin, so it isn't really relevant to that bug.
>
> Please file a bug with Apple, the library issue sounds like just a bug. Although it is worth noting that clang/llvm-gcc seem to get it wrong as well, without calling the library function.
Comment 45 Jack Howarth 2010-04-13 16:06:56 UTC
Did anyone ever file a radar bug report on the inaccurate complex math from http://compiler-rt.llvm.org/?
Comment 46 Dominique d'Humieres 2010-04-13 16:29:33 UTC
> Did anyone ever file a radar bug report on the inaccurate complex math from
> http://compiler-rt.llvm.org/?

I did not see anything along this line in their bugzilla. However there is comment #25

> I've filed radr://7457013 for libSystem (aka libm on 10.6) to improve the
> accuracy of ___divdc3.  If that were fixed, then having -lm or not wouldn't
> matter.
Comment 47 Jack Howarth 2010-04-13 16:48:29 UTC
Not good news...according to another Apple programmer...

----------
Mike Stump filed the radar:

<rdar://problem/7457013> ___divdc3 slightly wrong

Since fixing it did not appear to positively impact our customers I recommended that either we reduce the priority appropriately
+(e.g. Nice to have), or that we just close it.

-----------
Perhaps Mike can update his radar with a more convincing appeal.
Comment 48 Iain Sandoe 2010-04-13 16:52:04 UTC
give me a day or two guys...
 and I'll post a composite patch that 
(a) cleans up some of the nits in config{,/*}/darwin*.h
(b) gets rid of -lgcc [well, moves it to the only places it's still needed]
(c) sorts out dsymutils 
(d) temporarily patches darwin10.h to include the static lib first and therefore work around this bug until the radar is done.
.. I just need to sort out how to install the wrapper script.. 
(but I'm busy with a different problem today) :)
Comment 49 Jack Howarth 2010-04-13 16:59:50 UTC
(In reply to comment #48)
> (d) temporarily patches darwin10.h to include the static lib first and
> therefore work around this bug until the radar is done.

From what I was told (Comment 47), the radar bug may never be fixed.
Comment 50 Iain Sandoe 2010-04-14 17:38:35 UTC
see: 
http://gcc.gnu.org/ml/gcc-patches/2010-04/msg00806.html
for a proposed work-around for this.
Comment 51 Jack Howarth 2011-02-05 21:11:30 UTC
The __divdc3 in Snow Leopard come from the compiler-rt llvm project. Here are the tests they they use to validate their __divdc3...

http://llvm.org/svn/llvm-project/compiler-rt/trunk/test/Unit/divdc3_test.c

Any ideas on how to convert the failing test case here into a line for their divdc3_test.c so we can submit a bugzilla with test case upstream?
Comment 52 Jack Howarth 2011-02-05 21:49:14 UTC
Filed bug report upstream against compiler-rt with testcase...

http://llvm.org/bugs/show_bug.cgi?id=9150
Comment 53 mrs@gcc.gnu.org 2011-02-05 22:30:43 UTC
I think we should fix this by patching in a new linkage name for the routine in question with darwin_patch_builtins and creating a forwarding stub from the old name to the new name that we link against.  We could mix in _ieee into the new name.  If we compile with -fast-math we can call the old routine, no patch, and if one wants accuracy, the we call the new name.
Comment 54 Kaveh Ghazi 2011-02-06 16:43:38 UTC
(In reply to comment #53)
> I think we should fix this by patching in a new linkage name for the routine in
> question with darwin_patch_builtins and creating a forwarding stub from the old
> name to the new name that we link against.  We could mix in _ieee into the new
> name.  If we compile with -fast-math we can call the old routine, no patch, and
> if one wants accuracy, the we call the new name.

I believe GCC already does the "fast" method in some situations.  See tree-complex.c:expand_complex_division().  It switches on flag_complex_method, the difference is that the operation is done inline rather than a libcall.  I'm foget under what circumstances flag_complex_method triggers, but GCC may already do what you propose in some fashion.

--Kaveh
Comment 55 mrs@gcc.gnu.org 2011-02-07 20:52:39 UTC
Author: mrs
Date: Mon Feb  7 20:52:33 2011
New Revision: 169903

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169903
Log:
	PR target/42333
	Add __ieee_divdc3 entry point.
	* config/i386/darwin.h (DECLARE_LIBRARY_RENAMES): Retain ___divdc3
	entry point.
	(SUBTARGET_INIT_BUILTINS): Call darwin_rename_builtins.
	* config/i386/i386.c (TARGET_INIT_LIBFUNCS): Likewise.
	* config/darwin.c (darwin_rename_builtins): Add.
	* config/darwin-protos.h (darwin_rename_builtins): Add.

Modified:
    trunk/gcc/ChangeLog
Comment 56 mrs@gcc.gnu.org 2011-02-07 20:54:48 UTC
This has been fixed.  See PR47558 for the full patch.
Comment 57 mrs@gcc.gnu.org 2011-02-07 20:56:32 UTC
I'll pre-approve a backport to 4.5.x if someone really wants it, should be very safe.
Comment 58 mrs@gcc.gnu.org 2011-06-30 16:31:29 UTC
Author: mrs
Date: Thu Jun 30 16:31:23 2011
New Revision: 175711

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=175711
Log:
2011-06-30  Jack Howarth  <howarth@bromo.med.uc.edu>

        Backport from mainline
        2011-02-07 Mike Stump  <mikestump@comcast.net>

        PR target/42333
        Add __ieee_divdc3 entry point.
        * config/i386/darwin.h (DECLARE_LIBRARY_RENAMES): Retain ___divdc3
        entry point.
        (SUBTARGET_INIT_BUILTINS): Call darwin_rename_builtins.
        * config/i386/i386.c (TARGET_INIT_LIBFUNCS): Likewise.
        * config/darwin.c (darwin_rename_builtins): Add.
        * config/darwin-protos.h (darwin_rename_builtins): Add.

Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/config/darwin-protos.h
    branches/gcc-4_5-branch/gcc/config/darwin.c
    branches/gcc-4_5-branch/gcc/config/i386/darwin.h
    branches/gcc-4_5-branch/gcc/config/i386/i386.c
Comment 59 mrs@gcc.gnu.org 2011-06-30 16:33:17 UTC
Fixed in 4.5.4.