This patch addresses PR rtl-optimization/126521 where ifcvt transforms
x < 0 ? -x : x (and x < 0 ? x : -x) into ABS (and NABS respectively).
Unfortunately, these transformations are unsafe in the presence of NaNs.
The simple fix is a one-line change to noce_try_abs.

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 rtl-optimization/126521
        * ifcvt.c (noce_try_abs): These conversions are unsafe in the
        presence of NaNs.

gcc/testsuite/ChangeLog
        PR rtl-optimization/126521
        * gcc.target/i386/pr126521.c: New test case.


Thanks in advance,
Roger
--

diff --git a/gcc/ifcvt.cc b/gcc/ifcvt.cc
index 618c2976c5d..1d85516b1ce 100644
--- a/gcc/ifcvt.cc
+++ b/gcc/ifcvt.cc
@@ -3166,8 +3166,9 @@ noce_try_abs (noce_if_info *if_info)
   if (!noce_simple_bbs (if_info))
     return false;
 
-  /* Reject modes with signed zeros.  */
-  if (HONOR_SIGNED_ZEROS (if_info->x))
+  /* Reject modes with signed zeros or NaNs.  */
+  if (HONOR_SIGNED_ZEROS (if_info->x)
+      || HONOR_NANS (if_info->x))
     return false;
 
   /* Recognize A and B as constituting an ABS or NABS.  The canonical
diff --git a/gcc/testsuite/gcc.target/i386/pr126521.c 
b/gcc/testsuite/gcc.target/i386/pr126521.c
new file mode 100644
index 00000000000..0b49bd36bb9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126521.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -fno-signed-zeros -fno-ssa-phiopt" } */
+
+double g (double a)
+{
+  double x;
+  if (a < 0.0)
+    x = a;
+  else
+    x = -a;
+  return x;
+}
+
+/* { dg-final { scan-assembler "cmpnlt" } } */

Reply via email to