flat assembler
Message board for the users of flat assembler.

Index > High Level Languages > Why GCC is checking for x < 0, calling libm sqrtf()?

Author
Thread Post new topic Reply to topic
fpissarra



Joined: 10 Apr 2019
Posts: 64
fpissarra 10 Apr 2019, 13:49
A simple function, in C:

Code:
float f( float x ) { return sqrtf( x ); }    


Creates code like this:

Code:
f:
  pxor xmm2,xmm2
  sqrtss xmm1,xmm0
  ucomiss xmm2,xmm0
  ja .L8
  movabs xmm0,xmm1
  ret
.L8:
  sub  rsp,24
  movss dword [rsp+8],xmm1
  call sqrtf
  movss xmm1,dword [rsp+8]
  add  rsp,24
  movabs xmm0,xmm1
  ret    


Using only the sqrtss instruction I get the same results for negative and invalid inputs (-1.0, +/-NAN and +/-INFINITY). Why GCC is checking for x < 0, calling libm sqrtf() if so, and using sqrtss results anyway? Any thoughts?[/code]
Post 10 Apr 2019, 13:49
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2596
Furs 10 Apr 2019, 13:55
Compile with -Ofast and it will be just a sqrtss. Looks like a bug to me but GCC is full of crap code generation without -ffast-math.
Post 10 Apr 2019, 13:55
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20519
Location: In your JS exploiting you and your system
revolution 10 Apr 2019, 14:05
My guess would be for exception generation/handling.
Post 10 Apr 2019, 14:05
View user's profile Send private message Visit poster's website Reply with quote
fpissarra



Joined: 10 Apr 2019
Posts: 64
fpissarra 03 May 2019, 03:51
Sorry, here's a follow up:

Yes, GCC has a tiny problem with this built in function. It should check if the argument is less than 0 before executing sqrtss (or sqrtsd for sqrt() function).

The call to libm sqrtf() needs to be made if x < 0 because errno and math exceptions must be set acordingly.

I've reported this bug to GCC Bugzilla and it was accepted as such. Future versions (or patches) will correct the problem (which doesn't affect the correctness of the built in function, but makes it very slow only - I've measured 70000 clock cycles in my machine)...
Post 03 May 2019, 03:51
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20519
Location: In your JS exploiting you and your system
revolution 03 May 2019, 04:26
Exceptions are expensive.

Glad you were able to fix the C silliness. Smile
Post 03 May 2019, 04:26
View user's profile Send private message Visit poster's website Reply with quote
fpissarra



Joined: 10 Apr 2019
Posts: 64
fpissarra 04 May 2019, 17:25
The solutions, until GCC gets patched, are:

1- Use -ffast-math. This way, the compiler will not touch errno (won't call libm sqrt()) and still returns -NAN when x < 0;

2- Use inline assembly:
Code:
#include <math.h>

inline double sqrt_(double x)
{
  if ( x < 0 ) { errno = EDOM; return -NAN; }
  __asm__ __volatile__ ( "sqrtsd %0,%0" : "+x" (x) );
  return x;
}    
Post 04 May 2019, 17:25
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20519
Location: In your JS exploiting you and your system
revolution 04 May 2019, 17:29
fpissarra wrote:
The solutions, until GCC gets patched, are:

1- Use -ffast-math. This way, the compiler will not touch errno (won't call libm sqrt()) and still returns -NAN when x < 0;

2- Use inline assembly:
I like option 2 better than 1.

But what about option 3?

3- Use pure assembly Laughing
Post 04 May 2019, 17:29
View user's profile Send private message Visit poster's website Reply with quote
fpissarra



Joined: 10 Apr 2019
Posts: 64
fpissarra 04 May 2019, 20:35
revolution wrote:
But what about option 3?

3- Use pure assembly Laughing


Yep... but, in this case, every call to sqrtf_() won't be 'inline'.
PS: I do prefer #1, since is portable (if you are using GCC on multiple platforms).
Post 04 May 2019, 20:35
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.