https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79207

            Bug ID: 79207
           Summary: Special trigonometric simplification for solving
                    cubics with -ffast-math
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: tkoenig at gcc dot gnu.org
  Target Milestone: ---

There is a special trigonometric identity that comes up
when solving cubic equations with three real roots
(see https://en.wikipedia.org/wiki/Cubic_function#Three_real_roots ).

The function

#include <math.h>
#define ONETHIRD (1./3.)
void c3(double alpha, double ret[3])
{
  ret[0]=cos(alpha*ONETHIRD);
  ret[1]=cos((alpha+2*M_PI)*ONETHIRD);
  ret[2]=cos((alpha-2*M_PI)*ONETHIRD);
}

could be transformed to

#include <math.h>
#define ONETHIRD (1./3.)
void c3(double alpha, double ret[3])
{
  double t_a, t_cos, t_sin, t_ss3;
  t_a = alpha * ONETHIRD;
  __builtin_sincos(t_a, &t_sin, &t_cos);
  ret[0] = t_cos;
  t_ss3 = t_sin * sqrt(3.);
  ret[1] = -0.5 * (t_ss3 + t_cos);
  ret[2] = 0.5 * (t_ss3 - t_cos);
}

replacing three calls to cos with one call to __builtin_sincos.

Of course, it could also be argued that this is an extremely
specialized case. Still, I suspect that people who calculate
solutions to cubic equations a lot (which, for example, happens
in real gas equations of state), or who calculate eigenvalues
and eigenvectors of 3*3 tensors, might be pleasantly surprised if
their codes suddenly start running much faster.

Reply via email to