> CCP and other passes ultimatively end up using fold-const.c:const_{unop,binop}
> for constant folding so that is where the fix should go to (or to real.c).  
> That
> will automatically handle other passes doing similar transforms.

Thanks for the tip. I will modify my fix and post it.

Regards,
Sujoy

>
> Richard.
>
>> Regards,
>> Sujoy
>>
>>> Thanks,
>>> Richard.
>>>
>>>> Regards,
>>>> Sujoy
>>>>
>>>> 2015-09-01  Sujoy Saraswati <ssarasw...@gmail.com>
>>>>
>>>>         PR tree-optimization/61441
>>>>         * tree-ssa-ccp.c (convert_snan_to_qnan): Convert sNaN to qNaN when
>>>>         flag_signaling_nans is off.
>>>>         (ccp_fold_stmt, visit_assignment, visit_cond_stmt): call
>>>>         convert_snan_to_qnan to convert sNaN to qNaN on constant folding.
>>>>
>>>>         PR tree-optimization/61441
>>>>         * gcc.dg/pr61441.c: New testcase.
>>>>
>>>> Index: gcc/tree-ssa-ccp.c
>>>> ===================================================================
>>>> --- gcc/tree-ssa-ccp.c  (revision 226965)
>>>> +++ gcc/tree-ssa-ccp.c  (working copy)
>>>> @@ -560,6 +560,24 @@ value_to_wide_int (ccp_prop_value_t val)
>>>>    return 0;
>>>>  }
>>>>
>>>> +/* Convert sNaN to qNaN when flag_signaling_nans is off */
>>>> +
>>>> +static void
>>>> +convert_snan_to_qnan (tree expr)
>>>> +{
>>>> +  if (expr
>>>> +      && (TREE_CODE (expr) == REAL_CST)
>>>> +      && !flag_signaling_nans)
>>>> +  {
>>>> +    REAL_VALUE_TYPE *d = TREE_REAL_CST_PTR (expr);
>>>> +
>>>> +    if (HONOR_NANS (TYPE_MODE (TREE_TYPE (expr)))
>>>> +        && REAL_VALUE_ISNAN (*d)
>>>> +        && d->signalling)
>>>> +      d->signalling = 0;
>>>> +  }
>>>> +}
>>>> +
>>>>  /* Return the value for the address expression EXPR based on alignment
>>>>     information.  */
>>>>
>>>> @@ -2156,6 +2174,7 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
>>>>         if (val.lattice_val != CONSTANT
>>>>             || val.mask != 0)
>>>>           return false;
>>>> +        convert_snan_to_qnan (val.value);
>>>>
>>>>         if (dump_file)
>>>>           {
>>>> @@ -2197,7 +2216,10 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
>>>>             bool res;
>>>>             if (!useless_type_conversion_p (TREE_TYPE (lhs),
>>>>                                             TREE_TYPE (new_rhs)))
>>>> +            {
>>>>               new_rhs = fold_convert (TREE_TYPE (lhs), new_rhs);
>>>> +              convert_snan_to_qnan (new_rhs);
>>>> +            }
>>>>             res = update_call_from_tree (gsi, new_rhs);
>>>>             gcc_assert (res);
>>>>             return true;
>>>> @@ -2216,6 +2238,7 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
>>>>              tree new_rhs = fold_builtin_alloca_with_align (stmt);
>>>>              if (new_rhs)
>>>>               {
>>>> +                convert_snan_to_qnan (new_rhs);
>>>>                 bool res = update_call_from_tree (gsi, new_rhs);
>>>>                 tree var = TREE_OPERAND (TREE_OPERAND (new_rhs, 0),0);
>>>>                 gcc_assert (res);
>>>> @@ -2260,7 +2283,10 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
>>>>           {
>>>>             tree rhs = unshare_expr (val);
>>>>             if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE 
>>>> (rhs)))
>>>> +            {
>>>>               rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
>>>> +              convert_snan_to_qnan (rhs);
>>>> +            }
>>>>             gimple_assign_set_rhs_from_tree (gsi, rhs);
>>>>             return true;
>>>>           }
>>>> @@ -2292,6 +2318,7 @@ visit_assignment (gimple stmt, tree *output_p)
>>>>        /* Evaluate the statement, which could be
>>>>          either a GIMPLE_ASSIGN or a GIMPLE_CALL.  */
>>>>        val = evaluate_stmt (stmt);
>>>> +      convert_snan_to_qnan (val.value);
>>>>
>>>>        /* If STMT is an assignment to an SSA_NAME, we only have one
>>>>          value to set.  */
>>>> @@ -2324,6 +2351,7 @@ visit_cond_stmt (gimple stmt, edge *taken_edge_p)
>>>>    if (val.lattice_val != CONSTANT
>>>>        || val.mask != 0)
>>>>      return SSA_PROP_VARYING;
>>>> +  convert_snan_to_qnan (val.value);
>>>>
>>>>    /* Find which edge out of the conditional block will be taken and add it
>>>>       to the worklist.  If no single edge can be determined statically,
>>>>
>>>> Index: gcc/testsuite/gcc.dg/pr61441.c
>>>> ===================================================================
>>>> --- gcc/testsuite/gcc.dg/pr61441.c      (revision 0)
>>>> +++ gcc/testsuite/gcc.dg/pr61441.c      (working copy)
>>>> @@ -0,0 +1,17 @@
>>>> +/* { dg-do run } */
>>>> +/* { dg-options "-O1 -lm" } */
>>>> +
>>>> +#define _GNU_SOURCE
>>>> +#include <stdio.h>
>>>> +#include <math.h>
>>>> +
>>>> +int main (void)
>>>> +{
>>>> +  float sNaN = __builtin_nansf ("");
>>>> +  double x = (double) sNaN;
>>>> +  if (issignaling(x))
>>>> +  {
>>>> +    __builtin_abort();
>>>> +  }
>>>> +  return 0;
>>>> +}

Reply via email to