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

--- Comment #6 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:05ab9447fe80e5b1450192e21f3116890d38ecc7

commit r15-5557-g05ab9447fe80e5b1450192e21f3116890d38ecc7
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Nov 21 09:39:06 2024 +0100

    phiopt: Improve spaceship_replacement for HONOR_NANS [PR117612]

    The following patch optimizes spaceship followed by comparisons of the
    spaceship value even for floating point spaceship when NaNs can appear.
    operator<=> for this emits roughly
    signed char c; if (i == j) c = 0; else if (i < j) c = -1; else if (i > j) c
= 1; else c = 2;
    and I believe the
    /* The optimization may be unsafe due to NaNs.  */
    comment just isn't true.
    Sure, the i == j comparison doesn't raise exceptions on qNaNs, but if
    one of the operands is qNaN, then i == j is false and i < j or i > j
    is then executed and raises exceptions even on qNaNs.
    And we can safely optimize say
    c == -1 comparison after the above into i < j, that also raises
    exceptions like before and handles NaNs the same way as the original.
    The only unsafe transormation would be c == 0 or c != 0, turning it
    into i == j or i != j wouldn't raise exception, so I'm not doing that
    optimization (but other parts of the compiler optimize the i < j comparison
    away anyway).

    Anyway, to match the HONOR_NANS case, we need to verify that the
    second comparison has true edge to the phi_bb (yielding there -1 or 1),
    it can't be the false edge because when NaNs are honored, the false
    edge is for both the case where the inverted comparison is true or when
    one of the operands is NaN.  Similarly we need to ensure that the two
    non-equality comparisons are the opposite, while for -ffast-math we can in
    some cases get one comparison x >= 5.0 and the other x > 5.0 and it is
fine,
    because NaN is UB, when NaNs are honored, they must be different to leave
    the unordered case with 2 value as the last one remaining.
    The patch also punts if HONOR_NANS and the phi has just 3 arguments instead
    of 4.
    When NaNs are honored, we also in some cases need to perform some
comparison
    and then invert its result (so that exceptions are properly thrown and we
    get the correct result).

    2024-11-21  Jakub Jelinek  <ja...@redhat.com>

            PR tree-optimization/94589
            PR tree-optimization/117612
            * tree-ssa-phiopt.cc (spaceship_replacement): Handle
            HONOR_NANS (TREE_TYPE (lhs1)) case when possible.

            * gcc.dg/pr94589-5.c: New test.
            * gcc.dg/pr94589-6.c: New test.
            * g++.dg/opt/pr94589-5.C: New test.
            * g++.dg/opt/pr94589-6.C: New test.

Reply via email to