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" } } */