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

--- Comment #7 from CVS 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:680e4202f23ce74f3b26c7f090b9d22a56765554

commit r11-5899-g680e4202f23ce74f3b26c7f090b9d22a56765554
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Dec 10 12:03:30 2020 +0100

    dojump: Improve float != comparisons on x86 [PR98212]

    The x86 backend doesn't have EQ or NE floating point comparisons,
    so splits x != y into x unord y || x <> y.  The problem with that is
    that unord comparison doesn't trap on qNaN operands but LTGT does.
    The end effect is that it doesn't trap on qNaN operands, because x unord y
    will be true for those and so LTGT will not be performed, but as the
backend
    is currently unable to merge signalling and non-signalling comparisons (and
    after all, with this exact exception it shouldn't unless the first one is
    signalling and the second one is non-signalling) it means we end up with:
            ucomiss %xmm1, %xmm0
            jp      .L4
            comiss  %xmm1, %xmm0
            jne     .L4
            ret
            .p2align 4,,10
            .p2align 3
    .L4:
            xorl    %eax, %eax
            jmp     foo
    where the comiss is the signalling comparison, but we already know that
    the right flags bits are already computed by the ucomiss insn.

    The following patch, if target supports UNEQ comparisons, splits NE
    as x unord y || !(x uneq y) instead, which in the end means we end up with
    just:
            ucomiss %xmm1, %xmm0
            jp      .L4
            jne     .L4
            ret
            .p2align 4,,10
            .p2align 3
    .L4:
            jmp     foo
    because UNEQ is like UNORDERED non-signalling.

    2020-12-10  Jakub Jelinek  <ja...@redhat.com>

            PR rtl-optimization/98212
            * dojump.c (do_compare_rtx_and_jump): When splitting NE and backend
            can do UNEQ, prefer splitting x != y into x unord y || !(x uneq y)
            instead of into x unord y || x ltgt y.

            * gcc.target/i386/pr98212.c: New test.

Reply via email to