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

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

https://gcc.gnu.org/g:4ee9e8319abfeec1a9ba452661cb3d55aef684fa

commit r16-3474-g4ee9e8319abfeec1a9ba452661cb3d55aef684fa
Author: Jakub Jelinek <[email protected]>
Date:   Sat Aug 30 18:29:04 2025 +0200

    phiopt, math-opts: Adjust spaceship_replacement and optimize_spaceship for
recent libstdc++ changes [PR121698]

    libstdc++ changed its ABI in <compare> for C++20 recently (under the
    C++20 is still experimental rule).  In addition to the -1, 0, 1 values
    for less, equal, greater it now uses -128 for unordered instead of
    former 2 and changes some of the operators, instead of checks like
    (_M_value & ~1) == _M_value in some cases it now uses _M_reverse()
    which is negation in unsigned char type + conversion back to the original
    type. _M_reverse() thus turns the -1, 0, 1, -128 values into
    1, 0, -1, -128.  Note libc++ uses value -127 instead of 2/-128.

    Now, the middle-end has some optimizations which rely on the particular
    implementation and don't optimize if not.  One is optimize_spaceship
    which on some targets (currently x86, aarch64 and s390) attempts to use
    better comparison instructions (ideally just one floating point comparison
    to get all 4 possible outcomes plus some flag tests or magic instead of
    2 or 3 floating point comparisons).  This one can actually handle
    arbitrary int non-[-1,1] values for unordered but still has a default
    of 2.  The patch changes that default to -128 so that even if something
    is expanded as branches if it is later during RTL optimizations determined
    to convert that into partial_ordering we get better code.

    The other optimization (phiopt one) is about optimizing (x <=> y) < 0
    etc. into just x < y.  This one actually relies on the exact unordered
    value (2) and has code to deal with that (_M_value & ~1) == _M_value
    kind of tests and whatever match.pd lowers it.  So, this patch partially
    rewrites it to look for -128 instead of 2, drop those
    (_M_value & ~1) == _M_value pattern recognitions and instead introduces
    pattern recognition of _M_reverse(), i.e. cast to unsigned char, negation
    in that type and cast back to the original signed type.

    With all these changes we get back the desired optimizations for all
    the cases we could optimize previously (note, for HONOR_NANS case
    we don't try to optimize say (x <=> y) == 0 because the original
    will raise exception if either x or y is a NaN, while turning it into
    x == y will not, but (x <=> y) <= 0 is fine (x <= y), because it
    does raise those exceptions.

    2025-08-30  Jakub Jelinek  <[email protected]>

            PR tree-optimization/121698
            * tree-ssa-phiopt.cc (spaceship_replacement): Adjust
            to handle spaceship unordered value -128 rather than 2 and
            stmts from the new std::partial_order::_M_reverse() instead
            of (_M_value & ~1) == _M_value etc.
            * doc/md.texi (spaceship@var{m}4): Use -128 instead of 2.
            * tree-ssa-math-opts.cc (optimize_spaceship): Adjust comments
            that libstdc++ unordered value is -128 rather than 2 and use
            that as the default unordered value.
            * config/i386/i386-expand.cc (ix86_expand_fp_spaceship): Use
            GEN_INT (-128) instead of const2_rtx and adjust comment
accordingly.
            * config/aarch64/aarch64.cc (aarch64_expand_fp_spaceship):
Likewise.
            * config/s390/s390.cc (s390_expand_fp_spaceship): Likewise.

            * gcc.dg/pr94589-2.c: Adjust for expected unordered value -128
            rather than 2 and negations in unsigned char instead of and with
            ~1 and comparison against original value.
            * gcc.dg/pr94589-4.c: Likewise.
            * gcc.dg/pr94589-5.c: Likewise.
            * gcc.dg/pr94589-6.c: Likewise.

Reply via email to