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.

I'm also working on two follow-up patches... Obviously it should be
possible to evaluate pow(-Inf,0.5) at compile-time (with -fno-math-errno)
and in theory the new logic in this patch should enable us to optimize:
    double foo(int x) { return __builtin_pow((double)x,0.5); }
into sqrt, as conversion of an integer to double can't produce either
an infinity or a negative zero, but unfortunately the tree_expr_maybe_*
predicates aren't quite clever enough yet.


This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}
with no new failures.  Ok for mainline?


2026-10-05  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.


Thanks in advance,
Roger
--

diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 70ac17c9e2f..aa6820cf0af 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;
diff --git a/gcc/testsuite/gcc.dg/pr127544-1.c 
b/gcc/testsuite/gcc.dg/pr127544-1.c
new file mode 100644
index 00000000000..1493574007e
--- /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" } } */

Reply via email to