Hi! The following testcase is miscompiled on powerpc64le-linux starting with r15-6777. That change has the if (HONOR_NANS (GET_MODE (XEXP (op0, 0)))) all = 15; lines which work fine if the comparisons use MODE_FLOAT or MODE_INT operands (or say MODE_VECTOR* etc.). But on this testcase on ppc64le during combine we see (set (reg:SI 134) (ior:SI (ge:SI (reg:CCFP 128) (const_int 0 [0])) (lt:SI (reg:CCFP 128) (const_int 0 [0])))) HONOR_NANS is obviously false on CCFPmode, because MODE_HAS_NANS is false, it isn't FLOAT_MODE_P. But still it is a MODE_CC mode used for floating point comparisons and so we need to consider the possibility of unordered operands. I'm not sure how we could look at the setter of those MODE_CC regs from the simplifiers, after all they can happen in the middle of combiner trying to combine multiple instructions. So, instead the following patch attempts to be conservative for MODE_CC with some exceptions. One is flag_finite_math_only, regardless of MODE_HAS_NANS in that case HONOR_NANS will be always false. Another one is for targets which provide REVERSE_CONDITION condition and reverse one way the floating point MODE_CC modes and another the integral ones. If REVERSE_CONDITION for GT gives LE, then unordered is not an option. And finally it searches if there are any scalar floating point modes with MODE_HAS_NANS at all, if not, it is also safe to assume there are no NaNs.
Bootstrapped/regtested on x86_64-linux, i686-linux, powerpc64le-linux, aarch64-linux and bootstrapped on s390x-linux (regtest there still pending). Ok for trunk? Or any other ideas how to handle this? 2025-02-24 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/119002 * simplify-rtx.cc: Include tm_p.h. (simplify_context::simplify_logical_relational_operation): Set all = 15 also if op0's first operand has MODE_CC mode and it is or could be floating point comparison which honors NaNs. * gcc.c-torture/execute/ieee/pr119002.c: New test. --- gcc/simplify-rtx.cc.jj 2025-01-15 08:43:39.611918569 +0100 +++ gcc/simplify-rtx.cc 2025-02-24 21:16:09.980758481 +0100 @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. #include "selftest-rtl.h" #include "rtx-vector-builder.h" #include "rtlanal.h" +#include "tm_p.h" /* Simplification and canonicalization of RTL. */ @@ -2675,6 +2676,24 @@ simplify_context::simplify_logical_relat /* See whether the operands might be unordered. */ if (HONOR_NANS (GET_MODE (XEXP (op0, 0)))) all = 15; + else if (GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC + && !flag_finite_math_only) + { + /* HONOR_NANS will be false for MODE_CC comparisons, eventhough + they could actually be floating point. If the mode is + reversible, ask the backend if it could be unordered, otherwise + err on the side of caution and assume it could be unordered + if any supported floating mode honors NaNs. */ + machine_mode mode = GET_MODE (XEXP (op0, 0)); + if (!REVERSIBLE_CC_MODE (mode) + || REVERSE_CONDITION (GT, mode) != LE) + FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) + if (HONOR_NANS (mode)) + { + all = 15; + break; + } + } mask0 = comparison_to_mask (code0) & all; mask1 = comparison_to_mask (code1) & all; } --- gcc/testsuite/gcc.c-torture/execute/ieee/pr119002.c.jj 2025-02-24 21:18:45.880622627 +0100 +++ gcc/testsuite/gcc.c-torture/execute/ieee/pr119002.c 2025-02-24 21:19:02.418396051 +0100 @@ -0,0 +1,23 @@ +/* PR rtl-optimization/119002 */ + +__attribute__((noipa)) unsigned int +foo (void *x, float y, float z) +{ + unsigned int a, b; + float c, d, e; + c = y; + d = z; + a = c < d; + d = y; + e = z; + b = d >= e; + a |= b; + return a; +} + +int +main () +{ + if (foo ((void *) 0, 0.f, __builtin_nanf (""))) + __builtin_abort (); +} Jakub