[Bug middle-end/90248] [8/9/10/11 Regression] larger than 0 compare fails with -ffinite-math-only -funsafe-math-optimizations

cvs-commit at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Jan 22 10:51:48 GMT 2021


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

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

https://gcc.gnu.org/g:36fe1cdc9534c36c02803ce97557130354d2b2a0

commit r11-6853-g36fe1cdc9534c36c02803ce97557130354d2b2a0
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Jan 22 11:50:18 2021 +0100

    match.pd: Replace incorrect simplifications into copysign [PR90248]

    In the PR Andrew said he has implemented a simplification that has been
    added to LLVM, but that actually is not true, what is in there are
    X * (X cmp 0.0 ? +-1.0 : -+1.0) simplifications into +-abs(X)
    but what has been added into GCC are (X cmp 0.0 ? +-1.0 : -+1.0)
    simplifications into copysign(1, +-X) and then
    X * copysign (1, +-X) into +-abs (X).
    The problem is with the (X cmp 0.0 ? +-1.0 : -+1.0) simplifications,
    they don't work correctly when X is zero.
    E.g.
    (X > 0.0 ? 1.0 : -1.0)
    is -1.0 when X is either -0.0 or 0.0, but copysign will make it return
    1.0 for 0.0 and -1.0 only for -0.0.
    (X >= 0.0 ? 1.0 : -1.0)
    is 1.0 when X is either -0.0 or 0.0, but copysign will make it return
    still 1.0 for 0.0 and -1.0 for -0.0.
    The simplifications were guarded on !HONOR_SIGNED_ZEROS, but as discussed
in
    the PR, that option doesn't mean that -0.0 will not ever appear as operand
    of some operation, it is hard to guarantee that without compiler adding
    canonicalizations of -0.0 to 0.0 after most of the operations and thus
    making it very slow, but that the user asserts that he doesn't care if the
result
    of operations will be 0.0 or -0.0.  Not to mention that some of the
    transformations are incorrect even for positive 0.0.

    So, instead of those simplifications this patch recognizes patterns where
    those ?: expressions are multiplied by X, directly into +-abs.
    That works fine even for 0.0 and -0.0 (as long as we don't care about
    whether the result is exactly 0.0 or -0.0 in those cases), because
    whether the result of copysign is -1.0 or 1.0 doesn't matter when it is
    multiplied by 0.0 or -0.0.

    As a follow-up, maybe we should add the simplification mentioned in the PR,
    in particular doing copysign by hand through
    VIEW_CONVERT_EXPR <int, float_X> < 0 ? -float_constant : float_constant
    into copysign (float_constant, float_X).  But I think that would need to be
    done in phiopt.

    2021-01-22  Jakub Jelinek  <jakub@redhat.com>

            PR tree-optimization/90248
            * match.pd (X cmp 0.0 ? 1.0 : -1.0 -> copysign(1, +-X),
            X cmp 0.0 ? -1.0 : +1.0 -> copysign(1, -+X)): Remove
            simplifications.
            (X * (X cmp 0.0 ? 1.0 : -1.0) -> +-abs(X),
            X * (X cmp 0.0 ? -1.0 : 1.0) -> +-abs(X)): New simplifications.

            * gcc.dg/tree-ssa/copy-sign-1.c: Don't expect any copysign
            builtins.
            * gcc.dg/pr90248.c: New test.


More information about the Gcc-bugs mailing list