On Wed, Sep 4, 2013 at 1:53 PM, Cong Hou <co...@google.com> wrote: > I have made a new patch according to your comments. I found several > references saying that the precision 2p+2 is OK for the sqrt > conversion (one here: > http://www.cs.berkeley.edu/~fateman/generic/algorithms.pdf). The new > patch is pasted as below. > > Thank you for all the suggestions, Joseph! > > > Cong > > > Index: gcc/testsuite/gcc.c-torture/execute/20030125-1.c > =================================================================== > --- gcc/testsuite/gcc.c-torture/execute/20030125-1.c (revision 201891) > +++ gcc/testsuite/gcc.c-torture/execute/20030125-1.c (working copy) > @@ -44,11 +44,11 @@ __attribute__ ((noinline)) > double > sin(double a) > { > - abort (); > + return a; > } > __attribute__ ((noinline)) > float > sinf(float a) > { > - return a; > + abort (); > } > Index: gcc/convert.c > =================================================================== > --- gcc/convert.c (revision 201891) > +++ gcc/convert.c (working copy) > @@ -135,16 +135,34 @@ convert_to_real (tree type, tree expr) > CASE_MATHFN (COS) > CASE_MATHFN (ERF) > CASE_MATHFN (ERFC) > - CASE_MATHFN (FABS) > CASE_MATHFN (LOG) > CASE_MATHFN (LOG10) > CASE_MATHFN (LOG2) > CASE_MATHFN (LOG1P) > - CASE_MATHFN (LOGB) > CASE_MATHFN (SIN) > - CASE_MATHFN (SQRT) > CASE_MATHFN (TAN) > CASE_MATHFN (TANH) > + CASE_MATHFN (SQRT) > + > + /* The above functions (except sqrt) are not safe to do > this conversion. */ > + if (!flag_unsafe_math_optimizations) > + { > + /* sqrtl?(T1) could be safely converted into sqrtf?(T2) only if > + * p1 >= p2*2+2, where p1 and p2 are precisions of T1 and T2. > */
Two spaces after T2. Perhaps making the comment clearer? it is safe to do the following: float f1 = sqrt ((double) f2); --> float f1 = sqrtf (f2); But conditionally safe for the following double d1 = sqrtl ((long double) d2); --> double d1 = sqrt (d2); depending on the precision of the long double type on the target. ...< Add your reference here.> David > + if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)) > + { Fix indentation. > + int p1 = REAL_MODE_FORMAT (TYPE_MODE (type))->p; > + int p2 = (fcode == BUILT_IN_SQRTL) ? > + REAL_MODE_FORMAT (TYPE_MODE (long_double_type_node))->p : > + REAL_MODE_FORMAT (TYPE_MODE (double_type_node))->p; > + if (p2 < p1 * 2 + 2) > + break; > + } > + else > + break; > + } > + CASE_MATHFN (FABS) > + CASE_MATHFN (LOGB) > #undef CASE_MATHFN > { > tree arg0 = strip_float_extensions (CALL_EXPR_ARG (expr, 0)); > > On Tue, Sep 3, 2013 at 3:38 PM, Joseph S. Myers <jos...@codesourcery.com> > wrote: >> On Tue, 3 Sep 2013, Cong Hou wrote: >> >>> Could you please tell me how to check the precision of long double in >>> GCC on different platforms? >> >> REAL_MODE_FORMAT (TYPE_MODE (long_double_type_node))->p >> >> (but you should be referring to the relevant types - "type", the type >> being converted to, "itype", the type of the function being called in the >> source code, "TREE_TYPE (arg0)", the type of the argument after extensions >> have been removed, and "newtype", computed from those - so you should have >> expressions like the above with two or more of those four types, but not >> with long_double_type_node directly). >> >> The patch submission will need to include a proper analysis to justify to >> the reader why the particular inequality with particular types from those >> four is correct in all cases where the relevant code may be executed. >> >> -- >> Joseph S. Myers >> jos...@codesourcery.com