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

            Bug ID: 116299
           Summary: GCC optimizes away code when long double is
                    represented by the IBM double-double method.
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rmaguire314 at gmail dot com
  Target Milestone: ---

To avoid precision loss in the computation of cos(x^2) for very large x I split
x into two parts, xhi and xlo, as follows:

    /* Magic number is 3.4359738369E+10 = 2^35 + 1. */
    const double x_double = (double)x;
    const double split = x_double*3.4359738369E+10;
    const double xhi_double = split - (split - x_double);
    const long double xhi = (long double)xhi_double;
    const long double xlo = x - xhi;

GCC optimizes this away and the precision loss is visible.
On systems where long double is implemented via double, extended, or quadruple
precision, this optimization does not occur.

    /* SPLIT_VAL varies depending on how long double is represented. */
    const long double split = SPLIT_VAL * x;
    const long double xhi = split - (split - x);
    const long double xlo = x - xhi;

Changing everything to volatile cures the issue.

    /* Magic number is 3.4359738369E+10 = 2^35 + 1. */
    volatile const double x_double = (double)x;
    volatile const double split = x_double*3.4359738369E+10;
    volatile const double xhi_double = split - (split - x_double);
    const long double xhi = (long double)xhi_double;

Reply via email to