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.
