Hi Richard,

> Note that I'm curious what
> the actual bug is - is it that (double) sNaN creates a sNaN?  Then the fix
> should be elsewhere, in constant folding itself
> (fold_convert_const_real_from_real
> or real_convert).
>
> If that isn't the bug you have very many other passes to fix for the
> same problem.
>
> So - can you please explain?

In this test case, the floating point operation for converting the
float to double is what should convert the sNaN to qNaN. I tried to
cover more floating point operations than just the conversion
operations exposed by this test case. For example, if we consider the
following program -

#define _GNU_SOURCE
#include <stdio.h>
#include <math.h>

int main (void)
{
  float x;
  float sNaN = __builtin_nansf ("");
  x = sNaN + .0;
  return issignaling(x);
}

The operation (sNaN + .0) should also result in qNaN after folding.
Hence, I thought of doing the sNaN to qNaN conversion in various
places under tree-ssa-ccp, where the result upon a folding is
available. I do agree that this approach may mean many more such
places should also be covered in other passes, but thought of sending
the fix for the ccp pass to start with.

Let me know if you suggest alternate approach.

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