https://gcc.gnu.org/g:152e49bf66b737d296bf66ac4c1d353d395e6e3b
commit r17-4951-g152e49bf66b737d296bf66ac4c1d353d395e6e3b Author: Roger Sayle <[email protected]> Date: Wed Oct 7 09:39:23 2026 +0100 PR tree-optimization/127544: Don't fold pow(-Inf,0.5) to sqrt. This patch fixes PR tree-optimization/127544 by tightening the conditions under which gimple_expand_builtin_pow is allowed to convert pow(x,0.5) into sqrt(x). Specifically, pow(-Inf,0.5) should return +Inf (by POSIX) but sqrt(-Inf) returns NaN, so this transformation is (also) unsafe in the presence of -Inf. The patch also fixes an instance of using REAL_VALUE_ISSIGNALING_NAN when the intended behavior is to check tree_expr_maybe_signaling_nan_p. 2026-10-07 Roger Sayle <[email protected]> gcc/ChangeLog PR tree-optimization/127544 PR tree-optimization/126562 * tree-ssa-math-opts.cc (gimple_expand_builtin_pow): Use tree_expr_maybe_signaling_nan_p insted of REAL_VALUE_ISSIGNALING_NAN to check whether an operand may be a signaling NaN. pow(x,0.5) also can't be transformed to sqrt(x) if x may be -Inf. gcc/testsuite/ChangeLog PR tree-optimization/127544 PR tree-optimization/126562 * gcc.dg/pr127544-1.c: New test case. Diff: --- gcc/testsuite/gcc.dg/pr127544-1.c | 14 ++++++++++++++ gcc/tree-ssa-math-opts.cc | 23 ++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/gcc/testsuite/gcc.dg/pr127544-1.c b/gcc/testsuite/gcc.dg/pr127544-1.c new file mode 100644 index 000000000000..1493574007e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr127544-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-math-errno -fno-signed-zeros -fdump-tree-optimized" } */ + +double foo() +{ + return __builtin_pow(-__builtin_inf(),0.5); +} + +double bar(double x) +{ + return __builtin_pow(x,0.5); +} + +/* { dg-final { scan-tree-dump-not "sqrt" "optimized" } } */ diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index df418435d0be..d74711cf4b87 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -2020,15 +2020,13 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, if (TREE_CODE (arg1) != REAL_CST) return NULL_TREE; - /* Don't perform the operation if flag_signaling_nans is on - and the operand is a signaling NaN. */ - if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))) - && ((TREE_CODE (arg0) == REAL_CST - && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0))) - || REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1)))) + if (flag_errno_math) return NULL_TREE; - if (flag_errno_math) + /* Don't perform the operation if flag_signaling_nans is on + and either operand is a signaling NaN. */ + if (tree_expr_maybe_signaling_nan_p (arg0) + || tree_expr_maybe_signaling_nan_p (arg1)) return NULL_TREE; /* If the exponent is equivalent to an integer, expand to an optimal @@ -2050,12 +2048,15 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, mode = TYPE_MODE (type); sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); - /* Optimize pow(x,0.5) = sqrt(x). This replacement is always safe - unless signed zeros must be maintained. pow(-0,0.5) = +0, while - sqrt(-0) = -0. */ + /* Optimize pow(x,0.5) = sqrt(x). This replacement is safe + except for signed zeros and negative infinity. + pow(-0,0.5) = +0, while sqrt(-0) = -0. + pow(-Inf,0.5) = +Inf, while sqrt(-Inf) is NaN. */ if (sqrtfn && real_equal (&c, &dconsthalf) - && !HONOR_SIGNED_ZEROS (mode)) + && !tree_expr_maybe_real_minus_zero_p (arg0) + && (!tree_expr_maybe_infinite_p (arg0) + || tree_expr_nonnegative_p (arg0))) return build_and_insert_call (gsi, loc, sqrtfn, arg0); hw_sqrt_exists = optab_handler (sqrt_optab, mode) != CODE_FOR_nothing;
