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. */ + if ((fcode == BUILT_IN_SQRT || fcode == BUILT_IN_SQRTL)) + { + 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