https://gcc.gnu.org/g:2e7e4312c9273fb3a2b1a64ca635652d98f66065
commit r17-5312-g2e7e4312c9273fb3a2b1a64ca635652d98f66065 Author: Roger Sayle <[email protected]> Date: Sun Oct 18 23:36:00 2026 +0100 fold-const: tree_expr_maybe_signaling_nan_p improvements A simple patch; the result of a binary arithmetic operation can't be a signaling NaN, as signaling NaN input operands are silenced to quiet NaNs as a result. Likewise, math functions such as sqrt, sin, cos and tan may return quiet NaNs but never signaling NaNs. This patch updates fold-const.cc's tree_expr_maybe_signaling_nan_p to reflect this useful property. It would be great if ranger could track this, as signaling NaNs should rarely affect optimizations in (large) functions, and only the first use needs to be cautious. 2026-10-18 Roger Sayle <[email protected]> gcc/ChangeLog * fold-const.cc (tree_expr_maybe_signaling_nan_p): The result of an arithmetic operation or math function can't be a signaling NaN. gcc/testsuite/ChangeLog * gcc.dg/fold-signaling-nan-1.c: New test case. * gcc.dg/fold-signaling-nan-2.c: Likewise. Diff: --- gcc/fold-const.cc | 47 +++++++++++++++++++++++++---- gcc/testsuite/gcc.dg/fold-signaling-nan-1.c | 12 ++++++++ gcc/testsuite/gcc.dg/fold-signaling-nan-2.c | 11 +++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 97c083efc813..03c395fad7b5 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -14417,6 +14417,13 @@ tree_expr_maybe_signaling_nan_p (const_tree x) { case REAL_CST: return real_issignaling_nan (TREE_REAL_CST_PTR (x)); + case PLUS_EXPR: + case MINUS_EXPR: + case MULT_EXPR: + case RDIV_EXPR: + case MIN_EXPR: + case MAX_EXPR: + case FIX_TRUNC_EXPR: case FLOAT_EXPR: return false; case ABS_EXPR: @@ -14425,10 +14432,6 @@ tree_expr_maybe_signaling_nan_p (const_tree x) case NON_LVALUE_EXPR: case SAVE_EXPR: return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 0)); - case MIN_EXPR: - case MAX_EXPR: - return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 0)) - || tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 1)); case COND_EXPR: return tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 1)) || tree_expr_maybe_signaling_nan_p (TREE_OPERAND (x, 2)); @@ -14438,12 +14441,44 @@ tree_expr_maybe_signaling_nan_p (const_tree x) CASE_CFN_FABS: CASE_CFN_FABS_FN: return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0)); + CASE_CFN_COPYSIGN: + CASE_CFN_COPYSIGN_FN: + return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0)); + CASE_CFN_ATAN: + CASE_CFN_ATAN_FN: + CASE_CFN_CEIL: + CASE_CFN_CEIL_FN: + CASE_CFN_COS: + CASE_CFN_COS_FN: + CASE_CFN_ERF: + CASE_CFN_ERF_FN: + CASE_CFN_EXP: + CASE_CFN_EXP_FN: + CASE_CFN_FLOOR: + CASE_CFN_FLOOR_FN: CASE_CFN_FMAX: CASE_CFN_FMAX_FN: CASE_CFN_FMIN: CASE_CFN_FMIN_FN: - return tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 0)) - || tree_expr_maybe_signaling_nan_p (CALL_EXPR_ARG (x, 1)); + CASE_CFN_FMOD: + CASE_CFN_FMOD_FN: + CASE_CFN_HYPOT: + CASE_CFN_HYPOT_FN: + CASE_CFN_MODF: + CASE_CFN_MODF_FN: + CASE_CFN_POW: + CASE_CFN_POW_FN: + CASE_CFN_ROUND: + CASE_CFN_ROUND_FN: + CASE_CFN_SIN: + CASE_CFN_SIN_FN: + CASE_CFN_SQRT: + CASE_CFN_SQRT_FN: + CASE_CFN_TAN: + CASE_CFN_TAN_FN: + CASE_CFN_TRUNC: + CASE_CFN_TRUNC_FN: + return false; default: return true; } diff --git a/gcc/testsuite/gcc.dg/fold-signaling-nan-1.c b/gcc/testsuite/gcc.dg/fold-signaling-nan-1.c new file mode 100644 index 000000000000..085d16d1142b --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-signaling-nan-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsignaling-nans -fdump-tree-optimized" } */ +/* { dg-add-options ieee } */ + +double foo(double x) +{ + return (x + 0.0) * 1.0; +} + +/* { dg-final { scan-tree-dump " \\+ " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/fold-signaling-nan-2.c b/gcc/testsuite/gcc.dg/fold-signaling-nan-2.c new file mode 100644 index 000000000000..4b19e30c2969 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-signaling-nan-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsignaling-nans -fdump-tree-optimized" } */ +/* { dg-add-options ieee } */ + +double foo(double x) +{ + return (x * 1.0) * 1.0; +} + +/* { dg-final { scan-tree-dump-times " \\* " 1 "optimized" } } */ +
