On Mon, Jun 15, 2026 at 1:21 AM Andrew Pinski <[email protected]> wrote: > > > > On Mon, Jun 15, 2026, 1:09 AM Roger Sayle <[email protected]> wrote: >> >> >> Hi Jeff, >> I'd like to ping/progress a patch of mine from July 2024: >> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658482.html >> which was initially (positively) reviewed here: >> https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659433.html >> >> 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. >> >> A quick summary is that GCC currently fails to optimize: >> int foo(long long x) { return x == 1.0; } >> to use an integral comparison (and avoid a floating point conversion) >> because all the values of long long can't be precisely represented >> as a (IEEE) double. This is too strict a condition, as only one >> value of a "long long" gets converted to 1.0 (even with overflow >> and rounding). >> >> The code review above agreed the implementation itself is reasonable >> and both machine and floating-point independent, the challenge is in >> writing test cases for the code, which unfortunately must assume a >> particular floating point format, and are therefore non-portable. >> >> To respond to Jeff's previous request/question, my preferred >> solution is rather than try to add "-mieee" to these new test cases, >> which should still pass even without strict IEEE (i.e. NaN) support, >> and therefore we should still be testing with -O2 default flags, >> but instead it makes sense for various backends to add additional >> tests/copies to their gcc.target directories including "-mieee", >> "-msoft-float", "-md-float", "-mg-float", "-mfpmath=387" etc. if >> they so wish. A failure of these tests does not indicate an issue >> with the implementation, which simply uses the current compile-time >> integer to FP (real) conversion support, but that that test hasn't >> been ported to the new/native floating point format (say FP8 or FP4). >> >> This patch has been retested on x86_64-pc-linux-gnu with make bootstrap >> and make -k check, both with and without --target_board=unix{-m32} >> with no new failures. Ok for mainline (cleaning up any testsuite >> wrinkles if/as they're reported)? >> >> >> 2026-06-15 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 ranger to determine >> whether value is exactly representable by floating point type, >> and check flag_trapping_math if not. Use the new helper >> fold_cmp_float_cst_p to check that transformation to an integer >> comparison is safe. > > > Hmm, I have someone working on a related patch and this will conflict. > We are changing (cmp (convert int) (float_cst)) to use the ranger and adding > a new function to the format helper to check if the range of the integer can > fit into the floating point exactly. > The person working on this should be posting today or tomorrow. > Since I helped with that patch I can review this one too.
See https://gcc.gnu.org/pipermail/gcc-patches/2026-June/720633.html . I do know there is some overlap between the 2 patches. Like for an example in your patch you do: ``` + if (!vr0.undefined_p ()) + { + lo = vr0.lower_bound (); + hi = vr0.upper_bound (); + int prec = (isign == SIGNED) + ? MAX (wi::min_precision (hi, SIGNED), + wi::min_precision (lo, SIGNED)) - 1 + : wi::min_precision (hi, UNSIGNED); + wide_int nz = vr0.get_nonzero_bits (); + if (nz != 0) + prec -= wi::ctz (nz); + exact_p = prec <= significand_size (fmt); + } `` While Eikansh does: +#if GIMPLE + int_range_max vr; + if (!value_ok + && gimple_match_range_of_expr (vr, @0, @2)) + value_ok = fmt.can_represent_integral_value_p (&vr); +#endif And then can_represent_integral_value_p calls range_fits_type_p which is basically what you do here (but better): + int prec = (isign == SIGNED) + ? MAX (wi::min_precision (hi, SIGNED), + wi::min_precision (lo, SIGNED)) - 1 + : wi::min_precision (hi, UNSIGNED); + wide_int nz = vr0.get_nonzero_bits (); + if (nz != 0) + prec -= wi::ctz (nz); + exact_p = prec <= significand_size (fmt); > > Thanks, > Andrea > > >> >> 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. >> >> >> Thanks in advance, >> Roger >> -- >>
