[Bug c/46926] New: Paired sin() cos() calls optimized to sincos() call.

jameskuyper at verizon dot net gcc-bugzilla@gcc.gnu.org
Mon Dec 13 17:11:00 GMT 2010


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46926

           Summary: Paired sin() cos() calls optimized to sincos() call.
           Product: gcc
           Version: 4.4.4
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: jameskuyper@verizon.net


I discovered this problem when porting from a mandriva Linux system using gcc
4.2.2 to a centos linux system using gcc 4.4.4. After much simplification, I
can now demonstrate the problem with an extremely short example program:

#include <math.h>
#include <stdlib.h>
void sincos(double val, double *sin_val, double *cos_val)
{
    *sin_val = sin(val);
    *cos_val = cos(val);

    return;
}

int func(
    double * pd
){
    double cosine, sine;

    /* must use value accessed through pointer; bug disappears
     * without the pointer access.
     */
    cosine = cos(*pd);
    sine = sin(*pd);

    /* Need to use cosine[] and sine[], or optimizer drops them. */
    return cosine < 0.0 && sine > 0.0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

int main (void)
{
   double d=0.0;
   return func(&d) ;
}

In the original program, the sincos() function defined above occurred in a
third-party library designed for use with a fully conforming implementation of
C90. Such implementations cannot provide a sincos() function in their standard
C library in any way that would conflict with a user-defined function of the
same name. I compiled and linked this program using the following command:

    gcc -ansi -pedantic -O1 -g sincos_prob.c -lm -o sincos_prob

When I execute the program, it produces a bus error. gdb indicates that the bus
error occurs inside a recursive (!?) call to sincos(). The problem does not
come up if I lower the optimization level to -O0.

The reason appears to be that, at optimization levels of 1 or higher, paired
calls to sin() and cos(), like those that occur in two seperate locations
above, are replaced with a single call to sincos() - in itself, a seemingly
reasonable thing to do. The sincos() definition provided by the third party
library is used in place of the one provided as an extension in the C standard
library, which also seems reasonable. Where this all goes wrong is inside the
body of the third-party library's definition of sincos(). The sin()/cos()
optimization turns that function into an infinitely recursive call to itself.

Because sincos() is not a C standard library routine, the code given above does
not violate any constraint, and has well defined behavior - behavior which does
not include generating a bus error.

When invoked in a mode that's supposed to be fully conforming to either C90 or
C99, the compiler should not generate spurious calls to functions whose names
are not reserved to the implementation. Use of a reserved name, such as
__sincos(), seems to me like it would be the simplest fix for this problem.



More information about the Gcc-bugs mailing list