[gcc r17-3466] PR middle-end/126775: ICE optimizing (T)0.0 - x with -ffinite-math-only

Roger Sayle via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:579349b0f12681ffcbfd14eafe6efdc8da67a1f2

commit r17-3466-g579349b0f12681ffcbfd14eafe6efdc8da67a1f2
Author: Roger Sayle <[email protected]>
Date:   Thu Aug 20 09:31:48 2026 +0100

    PR middle-end/126775: ICE optimizing (T)0.0 - x with -ffinite-math-only
    
    This patch fixes PR middle-end/126775, an ICE caused by my recent change
    to match.pd around tweaking the conditions under which 0.0 - x can
    safely be transformed into -x.  Unfortunately, that change assumed
    that real_zerop@0 implies that TREE_CODE(@0) == REAL_CST.  Alas things
    aren't that simple, so this fix introduces a new real_negzerop predicate
    that in addition to REAL_CST also handles VECTOR_CST and COMPLEX_CST,
    and most importantly fails gracefully on TREE_CODEs that it isn't
    expecting.
    
    2026-08-20  Roger Sayle  <[email protected]>
    
    gcc/ChangeLog
            PR middle-end/126775
            * match.pd (0.0 - x -> -x): Use new real_negzerop function.
            * tree.cc (real_negzerop): New predicate function to test if
            a tree expression is -0.0 or equivalent (like real_zerop).
            * tree.h (real_negzerop): Prototype here.
    
    gcc/testsuite/ChangeLog
            PR middle-end/126775
            * gcc.dg/pr126775.c: New test case.

Diff:
---
 gcc/match.pd                    |  2 +-
 gcc/testsuite/gcc.dg/pr126775.c |  8 ++++++++
 gcc/tree.cc                     | 23 +++++++++++++++++++++++
 gcc/tree.h                      |  3 +++
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 0d1a61321d49..51f825ec3279 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6209,7 +6209,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && (!HONOR_SIGNED_ZEROS (type)
 	  || tree_expr_nonzero_p (@1)
 	  || (!flag_rounding_math
-	      && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@0)))))
+	      && real_negzerop (@0))))
   (negate @1)))
 
 /* Transform x * -1 into -x.  */
diff --git a/gcc/testsuite/gcc.dg/pr126775.c b/gcc/testsuite/gcc.dg/pr126775.c
new file mode 100644
index 000000000000..12eb8078b156
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126775.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffinite-math-only" } */
+
+_Complex float foo(_Complex float x)
+{
+  _Complex float negzero = -0.0f + -0.0fi;
+  return negzero - x;
+}
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 52313fbd129f..69a7c7e6d34d 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -3326,6 +3326,29 @@ real_zerop (const_tree expr)
     }
 }
 
+/* Return true if EXPR is the real constant negative zero.  */
+
+bool
+real_negzerop (const_tree expr)
+{
+  STRIP_ANY_LOCATION_WRAPPER (expr);
+
+  if (TREE_CODE (expr) == VECTOR_CST)
+    {
+      expr = uniform_vector_p (expr);
+      if (!expr)
+	return false;
+    }
+
+  if (TREE_CODE (expr) == COMPLEX_CST)
+    return real_negzerop (TREE_REALPART (expr))
+	   && real_negzerop (TREE_IMAGPART (expr));
+
+  return TREE_CODE (expr) == REAL_CST
+	  && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (expr))
+	  && !(DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (expr))));
+}
+
 /* Return true if EXPR is the real constant one in real or complex form.
    Trailing zeroes matter for decimal float constants, so don't return
    true for them.
diff --git a/gcc/tree.h b/gcc/tree.h
index e079082a81af..bc6a304631dd 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5693,6 +5693,9 @@ extern tree decl_type_context (const_tree);
 /* Return true if EXPR is the real constant zero.  */
 extern bool real_zerop (const_tree);
 
+/* Return true if EXPR is the real constant negative zero.  */
+extern bool real_negzerop (const_tree);
+
 /* Initialize the iterator I with arguments from function FNDECL  */
 
 inline void
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.