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;