Daniel Lemire b57a12270e Fold the format at compile time under clang, mark cold checks unlikely
Clang generated ~35% more instructions per float than GCC on identical
code (canada.txt, 64-bit: 276 vs 200 i/f on a Xeon Gold 6548N). Two
causes, confirmed with exact instruction traces:

1. Clang declines to inline the parser (from_chars_caller<T>::call) into
   its callers, so parse_options stays a runtime value and every format
   flag is re-tested on every conversion: javascript, skip_white_space,
   allow_leading_plus, fixed/scientific, the decimal point, the JSON
   dispatch. GCC inlines the whole parser into each call site, where
   chars_format::general is a constant, and all of it folds away.

   Fix: from_chars dispatches chars_format::general to a
   from_chars_fixed_format<T, UC, Fmt> instantiation, so the format is a
   compile-time constant inside the parser body whether or not the user's
   call is inlined. The call forwarder gets fastfloat_clang_really_inline
   so that it folds into that instantiation.

2. Clang if-converts the rare over/underflow fix-ups at the end of
   compute_float and the result_out_of_range test into cmov chains that
   every conversion executes. Marking them fastfloat_clang_unlikely keeps
   them as never-taken branches.

Both are applied under clang only, and GCC's generated code is identical
to before (verified on the object code). That is on purpose: forcing
always_inline on from_chars, or even on the trivial call forwarder,
regressed GCC by up to 14% on mesh.txt by changing its inlining order;
dispatching to the fixed-format instantiation made it stop inlining into
the loop; and the unlikely hints alone cost it 2-6% on mesh.txt by
reordering blocks (GCC already emits branches there).

realbenchmark, cycles per float, 5 interleaved rounds, medians:

clang 21, Xeon Gold 6548N        before   after
  canada.txt ASCII  (64)          49.7    44.6   -10%
  canada.txt UTF-16 (64)          57.4    52.0    -9%
  mesh.txt   ASCII  (64)          26.5    22.4   -16%
  mesh.txt   UTF-16 (64)          28.1    24.0   -15%
  (32-bit: -8% to -14%)
gcc 14, same machine: generated code unchanged.
Apple clang 17, arm64: +3% to +18% Mfloat/s.
2026-09-21 22:30:43 -04:00
..
fast_float Fold the format at compile time under clang, mark cold checks unlikely 2026-09-21 22:30:43 -04:00