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

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

https://gcc.gnu.org/g:081959973e38fde06077cbfa70e036e4f018489c

commit r17-2324-g081959973e38fde06077cbfa70e036e4f018489c
Author: Roger Sayle <[email protected]>
Date:   Fri Jul 10 23:09:04 2026 +0100

    PR tree-optimization/57371: Improved comparison of integers to FP
constants.

    This patch improves the tree-level optimization of (fptype)ivar != CST
    in match.pd (historically tracked under PR 57371).  Joseph Myers'
    description in comment #1 provides an excellent overview of the issues,
    that historically it's the trapping behaviour of (fptype)ivar conversion
    that is the primary concern, which is why the current code in match.pd
    checks fmt.can_represent_integral_type_p (itype).  The first of the
    improvements with this patch is to check flag_trapping_math to control
    whether FP_OVERFLOW/FP_INEXACT needs to be preserved.

    The main optimization concerns checking whether the comparison
    against CST is unambiguous allowing it to be replaced with a integer
    comparison.  For reference, consider the table below which shows the
    default conversion of integers to IEEE 32-bit float.

    (float)16777211 => 16777211.0f;
    (float)16777212 => 16777212.0f;
    (float)16777213 => 16777213.0f;
    (float)16777214 => 16777214.0f;
    (float)16777215 => 16777215.0f;
    (float)16777216 => 16777216.0f;
    (float)16777217 => 16777216.0f;  // rounded
    (float)16777218 => 16777218.0f;
    (float)16777219 => 16777220.0f;  // rounded
    (float)16777220 => 16777220.0f;
    (float)16777221 => 16777220.0f;  // rounded
    (float)16777222 => 16777222.0f;
    (float)16777223 => 16777224.0f;  // rounded
    (float)16777224 => 16777224.0f;
    (float)16777225 => 16777224.0f;  // rounded
    (float)16777226 => 16777226.0f;

    Observe that it's safe to optimize (float)i == 16777212.0f to the
    equivalent i == 16777212 (as this is the only integer that can
    convert to that floating point constant), but that it's unsafe to
    optimize (float)i == 16777220.0f, as with default rounding there
    are three possible integer values that FLOAT_EXPR to 16777220.0f.
    The pragmatic check used in this patch is to confirm that (float)(i-1)
    and (float)(i+1) are both distinct from (float)i before simplifying
    the comparison to an integer-typed comparison.

    Finally, this patch also handles non-default rounding modes.
    In the table above, it's safe to optimize (float)i == 16777222.0f
    in IEEE's default rounding mode, but not in all FP rounding modes.
    This eventuality is handled by testing whether the (float)i, the
    (float)(i-1) and the (float)(i+1) are all exactly rounded when
    -frounding-math is specified.

    The original motivation for this patch was Claudiu's issue/analysis at
    https://github.com/foss-for-synopsys-dwc-arc-processors/gcc/issues/118
    which predicted a dramatic +26% performance improvement on EEMBC's
    iirflt01 benchmark.

    2026-07-10  Roger Sayle  <[email protected]>

    gcc/ChangeLog
            PR tree-optimization/57371
            * fold-const.cc (fold_cmp_float_cst_p): New helper function.
            * fold-const.h (fold_cmp_float_cst_p): Prototype here.
            * match.pd ((FTYPE) N CMP CST): Use the new helper
            fold_cmp_float_cst_p to check that transformation to an integer
            comparison is safe.

    gcc/testsuite/ChangeLog
            PR tree-optimization/57371
            * c-c++-common/pr57371-6.c: New test case.
            * c-c++-common/pr57371-7.c: Likewise.
            * c-c++-common/pr57371-8.c: Likewise.
            * c-c++-common/pr57371-9.c: Likewise.
            * c-c++-common/pr57371-10.c: Likewise.

Reply via email to