From: Kbwms AT aol DOT com Message-ID: Date: Tue, 3 Nov 1998 12:21:17 EST To: eliz AT is DOT elta DOT co DOT ilEli, Zaretski AT delorie DOT com Cc: djgpp-workers AT delorie DOT com Mime-Version: 1.0 Subject: Re: Inlining math functions and ANSI/Posix Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7bit X-Mailer: AOL 3.0 16-bit for Windows sub 38 Reply-To: djgpp-workers AT delorie DOT com Dear Eli Zaretskii, On 11-03-98 at 04:05:59 EST you wrote: > > I understand that GCC 2.8.x inlines some math functions under -O2 (`sqrt' > is one of them). > > If this is so, how does this influence the ANSI requirements that some > values of arguments should set errno? Is GCC's inlining smart enough to > not break this? If not, should we do something about this? > > (I cannot test this myself since I still don't have 2.8.1 installed.) I wrote some simple code to do a `sqrt' a million times (see appended). The code purposely commits a blunder by calling `sqrt' with a negative argument. Below listed are two versions of the assembler output. The first is without optimization, the second is with -O2. No optimization --------------- L9: pushl -16(%ebp) pushl -20(%ebp) call _sqrt addl $8,%esp fstpl -12(%ebp) fldl LC0 fstp %st(0) fldl LC0 fldl -20(%ebp) fsubp %st,%st(1) fstpl -20(%ebp) -O2 optimization ---------------- L10: fldl -8(%ebp) fsqrt fucom %st(0) fnstsw %ax andb $69,%ah cmpb $64,%ah je L11 fstp %st(0) pushl -4(%ebp) pushl -8(%ebp) fstpt -32(%ebp) call _sqrt addl $8,%esp fldt -32(%ebp) fxch %st(1) I am not familiar with this brand of assembler code but, in the version of the assembler code that was optimized, it appears that the compiler checks the output of `fsqrt' and calls the library version of `sqrt' if something looks amiss. Under the circumstances of this new code, the fact that it calls `sqrt' with a `bad' argument explains why the code seems to run at about the same speed regardless of optimization. Under both new libraries (libm and Rudd's libc) errno is correctly set to 1 when `sqrt' is given a negative argument. Under the old versions of the libraries, errno was not set. K.B. Williams +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #include #include #include #include #include static double ElapsedTime; static clock_t First, Start, Stop; int main () { int k; double Ans, Arg; Arg = -1.0; /* ---------------------------------------------- */ /* Get First Reading of Next Tick to Start Timing */ /* ---------------------------------------------- */ for (First = clock (), Start = clock (); First == Start; Start = clock ()) ; for (k = 1; k <= 1000000; ++k) { Ans = sqrt(Arg); Arg -= (1.0000001e-6); } /* ---------------------- */ /* Get Last Tick of Clock */ /* ---------------------- */ Stop = clock (); ElapsedTime = (double) (Stop - Start); printf ("\nElapsed time: %.0f clocks\n", ElapsedTime); printf ("Arg = %f, Ans = sqrt(Arg) = %f, errno = %d\n", Arg, Ans, errno); return 0; }