https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122307

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Igor Shevlyakov
<[email protected]>:

https://gcc.gnu.org/g:8158ffe53bc70511246588be6efe5e98431e55d9

commit r17-5585-g8158ffe53bc70511246588be6efe5e98431e55d9
Author: Igor Shevlyakov <[email protected]>
Date:   Tue Oct 6 17:22:20 2026 -0700

    middle-end: Don't reverse LTGT/UNEQ when traps are honored [PR122307]

    LTGT is a signaling comparison and UNEQ is a quiet one, so reversing
    one into the other changes whether a quiet NaN operand raises
    FE_INVALID.  reversed_comparison_code_parts nevertheless reverses them
    unconditionally.  Return UNKNOWN for them when flag_trapping_math is
    set and the operands may be NaNs (or the comparison is in a MODE_CC
    mode, which does not tell), mirroring what invert_tree_comparison does
    at the GIMPLE level; keep the reversal otherwise.

    That change alone exposes a latent problem in emit_store_flag: it
    splits x != y into x unord y || x ltgt y, emitting a store-flag for
    UNORDERED and a conditional move on LTGT.  The conditional move
    evaluates its comparison unconditionally, so for a quiet != the LTGT
    raises FE_INVALID on a NaN operand.  Today this is hidden only because
    emit_conditional_move happens to reverse LTGT into the quiet UNEQ when
    canonicalizing its arms; with LTGT no longer reversible, x86 emits a
    signaling comisd for a quiet !=.  Use the equivalent
    x unord y || !(x uneq y) directly, as do_compare_rtx_and_jump already
    does for jumps, and no longer treat LTGT as a non-trapping remainder.
    The NE split in do_compare_rtx_and_jump itself is safe: the UNORDERED
    jump comes first, so LTGT only ever sees ordered operands.

            PR middle-end/122307

    gcc/ChangeLog:

            * jump.cc (reversed_comparison_code_parts): Do not reverse LTGT
            and UNEQ if traps are honored and NaNs are possible.
            * expmed.cc (emit_store_flag): Split NE as UNORDERED || !UNEQ
            instead of UNORDERED || LTGT; do not treat LTGT as non-trapping.

    gcc/testsuite/ChangeLog:

            * gcc.c-torture/execute/ieee/pr122307.c: New test.

    Signed-off-by: Igor Shevlyakov <[email protected]>

Reply via email to