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.

Reply via email to