https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127119
--- Comment #1 from Hongyu Wang <hongyuw at gcc dot gnu.org> --- (In reply to Matthias Kretz (Vir) from comment #0) > I replaced fp subtract with XOR, doing integer compare against a value > computed in the "free" 8 cycles __trunc needs to compute __t_abs. > > The main issue is that `>> __exponent` is a vector shift, which is only > really efficient with AVX2. However, improving vector shifts without AVX2 is > again a separate issue to be resolved. Other than the full integer operation to emulate the fp subtract, can we use the integer compare to escape the inf in input? The pseudo code can be like below, then we don't need AVX2. abs_x = fabs(x); in_rng = int(abs_x) < int(0x1p23); xs = in_rng ? abs_x : 0.5; t_abs = trunc(xs); r_abs = t_abs + (xs - t_abs >= .5 ? 1 : 0); r_abs = in_rng ? r_abs : abs_x; return or(xor(abs_x, x), r_abs); > Now, all that said, the resulting number of instructions is likely too much > for inlining. So I assume we rather want to have such a solution in the > library, right? The llvm-mc emulation seems omitting the libcall penality, on real machine like cascadelake the conformant sequence could bring 4x speedup comparing with scalar libcall loop (for v4sf vector I tested). So we can have a conformant implementation like your proposal for optimize_for_speed. For -Os we just use libcall.
