delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/11/03/12:23:00

From: Kbwms AT aol DOT com
Message-ID: <abd34bd8.363f3b8d@aol.com>
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
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 <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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019