Mail Archives: djgpp-workers/1998/11/03/12:23:00
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 <errno.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
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;
}
- Raw text -