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

Reply via email to