mailing list of musl libc
 help / color / mirror / code / Atom feed
* FE Exception triggered by comparison
@ 2019-02-24 13:28 Damian McGuckin
  2019-02-24 17:12 ` Markus Wichmann
  2019-02-24 19:25 ` Szabolcs Nagy
  0 siblings, 2 replies; 27+ messages in thread
From: Damian McGuckin @ 2019-02-24 13:28 UTC (permalink / raw)
  To: musl


What comparison of FP numbers trigger invalid operation exceptions?

Does a comparison like

 	if (x != x)
 	{
 		/* get to here if x == NaN *
 	}

which tests for a NaN cause an invalid operation if given an sNaN?

Even reading the standard numerous times and I am not any wiser.

Thanks - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-24 13:28 FE Exception triggered by comparison Damian McGuckin
@ 2019-02-24 17:12 ` Markus Wichmann
  2019-02-24 19:25 ` Szabolcs Nagy
  1 sibling, 0 replies; 27+ messages in thread
From: Markus Wichmann @ 2019-02-24 17:12 UTC (permalink / raw)
  To: musl

On Mon, Feb 25, 2019 at 12:28:20AM +1100, Damian McGuckin wrote:
> 
> What comparison of FP numbers trigger invalid operation exceptions?
> 
> Does a comparison like
> 
> 	if (x != x)
> 	{
> 		/* get to here if x == NaN *
> 	}
> 
> which tests for a NaN cause an invalid operation if given an sNaN?
> 
> Even reading the standard numerous times and I am not any wiser.
> 
> Thanks - Damian
> 

In cases like these, I like to read the documentation of an
implementation, under the assumption that it is conforming. One
implementation of IEE 754 general considered to be conforming is the x87
instruction set. And AMD's documentation of the same (AMD64 Architecture
Programmer's Manual, Volume 5, Order No. 26569) says about the FCOM
instruction, that it will generate an invalid-operation exception if any
source operand was a NaN. Same for FCOMI and FICOM.

Only difference for FUCOM and FUCOMI is that those only raise IE for an
SNaN.

Cross-checking with volume 4 shows that the SSE FP compare instructions
all raise IE in case of SNan source operand, and in case of "Undefined
operation". No idea what the latter is supposed to mean in context,
unless it means that QNaNs trigger it, too.

So yes, it appears at least in a PC, comparison with NaN raises IE.

Ciao,
Markus


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-24 13:28 FE Exception triggered by comparison Damian McGuckin
  2019-02-24 17:12 ` Markus Wichmann
@ 2019-02-24 19:25 ` Szabolcs Nagy
  2019-02-24 20:04   ` Jens Gustedt
  1 sibling, 1 reply; 27+ messages in thread
From: Szabolcs Nagy @ 2019-02-24 19:25 UTC (permalink / raw)
  To: musl

* Damian McGuckin <damianm@esi.com.au> [2019-02-25 00:28:20 +1100]:
> What comparison of FP numbers trigger invalid operation exceptions?
> 
> Does a comparison like
> 
> 	if (x != x)
> 	{
> 		/* get to here if x == NaN *
> 	}
> 
> which tests for a NaN cause an invalid operation if given an sNaN?

iso c does not say much about sNaN: a conforming implementation
does not have to support sNaN (it is usually treated as qNaN,
with unspecified signaling behaviour and you need special
compiler options to ensure sNaN breaking transformations are
not done if you want to rely on sNaN signals)

with c99 annex F, c == and != operators are mapped to ieee 754
compareQuiet{Not}Equal, which is non-signaling with qNaN inputs
but signals invalid with sNaN inputs, so in practice sNaN != sNaN
will signal in c.

> Even reading the standard numerous times and I am not any wiser.

i think it's better to look at the ieee 754 spec instead
of the c spec, drafts are at http://754r.ucbtest.org/drafts/

annex F.3 describes how c is mapped to ieee 754 (iec 60559
is supposed to be very close to ieee 754).

ts 18661-* provides more detailed description of the mapping
to ieee 754-2008 (it will likely be part of c2x and it is a
bit more strict than what iso c currently allows).


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-24 19:25 ` Szabolcs Nagy
@ 2019-02-24 20:04   ` Jens Gustedt
  2019-02-24 21:50     ` Damian McGuckin
  0 siblings, 1 reply; 27+ messages in thread
From: Jens Gustedt @ 2019-02-24 20:04 UTC (permalink / raw)
  Cc: musl

[-- Attachment #1: Type: text/plain, Size: 2644 bytes --]

Hello,

On Sun, 24 Feb 2019 20:25:11 +0100 Szabolcs Nagy <nsz@port70.net> wrote:

> * Damian McGuckin <damianm@esi.com.au> [2019-02-25 00:28:20 +1100]:
> > What comparison of FP numbers trigger invalid operation exceptions?
> > 
> > Does a comparison like
> > 
> > 	if (x != x)
> > 	{
> > 		/* get to here if x == NaN *
> > 	}
> > 
> > which tests for a NaN cause an invalid operation if given an sNaN?  
> 
> iso c does not say much about sNaN: a conforming implementation
> does not have to support sNaN (it is usually treated as qNaN,
> with unspecified signaling behaviour and you need special
> compiler options to ensure sNaN breaking transformations are
> not done if you want to rely on sNaN signals)
> 
> with c99 annex F, c == and != operators are mapped to ieee 754
> compareQuiet{Not}Equal, which is non-signaling with qNaN inputs
> but signals invalid with sNaN inputs, so in practice sNaN != sNaN
> will signal in c.
> 
> > Even reading the standard numerous times and I am not any wiser.  
> 
> i think it's better to look at the ieee 754 spec instead
> of the c spec, drafts are at http://754r.ucbtest.org/drafts/
> 
> annex F.3 describes how c is mapped to ieee 754 (iec 60559
> is supposed to be very close to ieee 754).
> 
> ts 18661-* provides more detailed description of the mapping
> to ieee 754-2008 (it will likely be part of c2x and it is a
> bit more strict than what iso c currently allows).

Yes, we are currently integrating parts 1 and 2 of this TS into the
standard. Usually you should be able to see a first version of that in
a few weeks in the pre-London mailing.

For the moment they are integrated "as such" that is with "WANT"
macros that make these "new" interfaces optional. Further in the
process I hope that we will be able to do a bit more:

   - Remove this "optionality" from the numbered clauses and make all
     interfaces mandatory.

   - Some naming changes while these are not too fixed in peoples
     minds. Only very few identifiers in <math.h> are reserved for
     future use, so adding new interfaces will necessarily step on
     someones shoes.

   - Add some version macros for the different header files, such that
     applications and implementors have better chances to adapt during
     the time of transition.

Jens

-- 
:: INRIA Nancy Grand Est ::: Camus ::::::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::

[-- Attachment #2: Digitale Signatur von OpenPGP --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-24 20:04   ` Jens Gustedt
@ 2019-02-24 21:50     ` Damian McGuckin
  2019-02-25  5:21       ` Damian McGuckin
  2019-02-25 15:51       ` Markus Wichmann
  0 siblings, 2 replies; 27+ messages in thread
From: Damian McGuckin @ 2019-02-24 21:50 UTC (permalink / raw)
  To: musl


Hi Markus, Jens,

Thanks for the replies.

On Sun, 24 Feb 2019, Jens Gustedt wrote:

>> with c99 annex F, c == and != operators are mapped to ieee 754
>> compareQuiet{Not}Equal, which is non-signaling with qNaN inputs
>> but signals invalid with sNaN inputs, so in practice sNaN != sNaN
>> will signal in c.

I guess I am still trying to figure out where/when sNaN will appear so I 
can code defensively to protect my code. The C interface like 'isless' and 
friends are really woeful performers.

>> i think it's better to look at the ieee 754 spec instead
>> of the c spec, drafts are at http://754r.ucbtest.org/drafts/

I agree. But while I found the 1985 standard readable and clear, all the 
subsequent revisions have sections, especially related to exceptions, that 
are difficult to comprehend. And I thought I spoke English. The language 
is convoluted.

> Yes, we are currently integrating parts 1 and 2 of this TS into the
> standard. Usually you should be able to see a first version of that in
> a few weeks in the pre-London mailing.

Thanks.

> For the moment they are integrated "as such" that is with "WANT"
> macros that make these "new" interfaces optional.

Hmmm. Scary. I

The context of this is that I want a coding style which means I can 
compare numbers without affecting the exception state. And it must have 
zero overhead, and not affect the readability of the code, i.e. no 
function calls.

I want to know that

 	x != x

will always detect any NaN with affecting the exception status and that
comparisons like

 	if (x == x) { ... }
 	else if (x > y) { .... }
 	else if (x < y) { .... }
 	else { x or y are NaN }

will similarly also not modify the exception status, and in the last 
section let me process how I interpret the NaNs.

Otherwise, avoidance of creating spurious exceptions forces you to start 
working at the IEEE 754 encoding level. This is counterproductive to clear 
and concise programming. Such a style is riddled through a lot of the 
maths routines in MUSL and the libraries that came before it. It also 
means that all these magic constants start to appear in the code, severely 
affecting comprehensibility. Any generic coding style is just stopped in 
its tracks.

Regards - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-24 21:50     ` Damian McGuckin
@ 2019-02-25  5:21       ` Damian McGuckin
  2019-02-25 15:51       ` Markus Wichmann
  1 sibling, 0 replies; 27+ messages in thread
From: Damian McGuckin @ 2019-02-25  5:21 UTC (permalink / raw)
  To: musl

On Mon, 25 Feb 2019, Damian McGuckin wrote:

> comparisons like
>
> 	 if (x == x) { ... }

Sorry, typo. I should have been written this as

 	if (x == y) { ... }

and the rest is OK.

Regards - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-24 21:50     ` Damian McGuckin
  2019-02-25  5:21       ` Damian McGuckin
@ 2019-02-25 15:51       ` Markus Wichmann
  2019-02-26  3:55         ` Damian McGuckin
  1 sibling, 1 reply; 27+ messages in thread
From: Markus Wichmann @ 2019-02-25 15:51 UTC (permalink / raw)
  To: musl

On Mon, Feb 25, 2019 at 08:50:52AM +1100, Damian McGuckin wrote:
> The context of this is that I want a coding style which means I can compare
> numbers without affecting the exception state. And it must have zero
> overhead, and not affect the readability of the code, i.e. no function
> calls.
> 

Yet another problem brought to you by premature optimization. What you
want to know is if a certain number is NaN. There's a perfectly
acceptable idiom for that:

if (isnan(x)) {
}

This (the exception stuff) is the reason why the special cases are
always front-loaded in musl. So they can be sorted out without raising
spurious exceptions.

The only reason the above may not be acceptable to you is that it looks
like a function call. But it isn't. isnan() is a macro that doesn't
always revert to a function call.

> I want to know that
> 
> 	x != x
> 
> will always detect any NaN with affecting the exception status and that
> comparisons like
> 
> 	if (x == x) { ... }
> 	else if (x > y) { .... }
> 	else if (x < y) { .... }
> 	else { x or y are NaN }
> 
> will similarly also not modify the exception status, and in the last section
> let me process how I interpret the NaNs.
> 

Well, sorry, but these instructions do not work that way. Any operation
on a NaN, including comparison, even comparison for equality, will raise
IE, at least if it is an sNaN.

Honestly, though, I wonder what the big deal is. In most cases, if you
see a NaN, someone probably just made an invalid operation, or chose to
start another invalid operation with your function. In which case
raising IE is not spurious at all.

> Otherwise, avoidance of creating spurious exceptions forces you to start
> working at the IEEE 754 encoding level.

Or you could just use the interface provided by the C standard:

if (!isnormal(x) || !isnormal(y)) {
    guard clause here;
    return;
}
/* definitely normal x and y from this point on. */

Hopefully you don't need to deal with subnormals...

> This is counterproductive to clear
> and concise programming. Such a style is riddled through a lot of the maths
> routines in MUSL and the libraries that came before it.

No, that's just an optimization. Musl strives to minimize the numeric
error while also delivering good performance, and that means that often
a lot of boundary conditions can be detected at the same time with a
single comparison (e.g. you can detect "x < 0 || x > 2**limit ||
isinf(x)" by detecting if the exponent and sign bit together exceed a
certain limit.)

But nothing is stopping you from writing these conditions out entirely.

Ciao,
Markus


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-25 15:51       ` Markus Wichmann
@ 2019-02-26  3:55         ` Damian McGuckin
  2019-02-27 14:14           ` Alexander Monakov
  0 siblings, 1 reply; 27+ messages in thread
From: Damian McGuckin @ 2019-02-26  3:55 UTC (permalink / raw)
  To: musl


Hi Markus,

Thanks for taking the time to reply in depth.

Where I am coming from is some research writing low level routines for a 
language other than C/C++, learning lessons from that, and then wanting to 
contribute that back some of what I have learnt in a fashion that can be 
used in MUSL. The metrics/goals/style in that other programming language 
are somewhat different to MUSL so I only want to give back what integrates 
well into MUSL's metrics/goals/style. That way, I do not waste anyone's 
time.

On Mon, 25 Feb 2019, Markus Wichmann wrote:

> On Mon, Feb 25, 2019 at 08:50:52AM +1100, Damian McGuckin wrote:

>> The context of this is that I want a coding style which means I can 
>> compare numbers without affecting the exception state. And it must have 
>> zero overhead, and not affect the readability of the code, i.e. no 
>> function calls.
>
> Yet another problem brought to you by premature optimization. What you
> want to know is if a certain number is NaN. There's a perfectly
> acceptable idiom for that:
>
> if (isnan(x)) {
> }

I understand this. But, at least on an X86 architecture, that involves a 
write-to+read-from memory and I want to avoid that.

> This (the exception stuff) is the reason why the special cases are
> always front-loaded in musl. So they can be sorted out without raising
> spurious exceptions.

Front-loading often results in more lines of code and regularly, less 
lines of code means faster execution so with careful avoidance of the 
front-loading is feasible, I prefer it.

> The only reason the above may not be acceptable to you is that it looks
> like a function call. But it isn't. isnan() is a macro that doesn't
> always revert to a function call.

All of the fpclassify() and friends routines are quite heavy, even if they 
are macros and are done in line so I avoid them. That is just my opinion. 
Do I have a better solution for usage by the masses - No, well not in 
C/C++. See my later comments on builtins.

>> I want to know that
>>
>> 	x != x
>>
>> will always detect any NaN with affecting the exception status and that
>> comparisons like
>>
>> 	if (x == x) { ... }
>> 	else if (x > y) { .... }
>> 	else if (x < y) { .... }
>> 	else { x or y are NaN }
>>
>> will similarly also not modify the exception status, and in the last 
>> section let me process how I interpret the NaNs.

> Well, sorry, but these instructions do not work that way. Any operation
> on a NaN, including comparison, even comparison for equality, will raise
> IE, at least if it is an sNaN.

Table 5.1 of the 20X8 standard, as I read it, and as confirmed by Kahan's 
lecture notes, says that neither equality nor inequality is supposed to 
raise an IE on a qNaN. As you rightly say, Kahan's lecture notes, the 1985 
standard and Table 5.2 in the 2008 and the 2018(draft) standards says that 
any comparison with a '<' or '>' as part (or all) of the predicate should 
raise IE.

However, on experiments on GCC, the if/else/else/else above does not raise 
an IE. Is this an optimizer bug? For a while there, I questioned my whole 
understanding of the standard in terms of comparison until I went back to 
it and re-read it. Something is weird with GCC. And either you or I has 
the wrong understanding of what Table 5.1 implies for both an equality and 
an inequality comparison. And at least mine agrees with Kahan's lecture 
notes. It is not the latest GCC but one that I, and clients, need to use.

Note that if I manually create an sNaN and use it in the comparisons, then 
GCC behaves as the standard says. I wish I knew what creates an sNaN. The
only optimization I use is -O3.

> Honestly, though, I wonder what the big deal is. In most cases, if you 
> see a NaN, someone probably just made an invalid operation, or chose to 
> start another invalid operation with your function. In which case 
> raising IE is not spurious at all.

I agree that in most cases it is not a big deal. And the raising of an IE 
is not spurious in most cases. But there are cases where it is. I tried to 
rewrite frexp so it can be done in line but I get an IE which is a no-no 
for this routine. I know that frexp is supposed to be builtin in GCC/G++ 
but I kept seeing the function call in the assembler so I have no idea why 
GCC says it is builtin. Hence my original reason for doing frexp.

>> Otherwise, avoidance of creating spurious exceptions forces you to 
>> start working at the IEEE 754 encoding level.
>
> Or you could just use the interface provided by the C standard:
>
> if (!isnormal(x) || !isnormal(y)) {
>    guard clause here;
>    return;
> }

Again, memory access is the killer. Also, there is a lot of duplication in 
those macros that does not always get optimized away unless you rely on a 
built-in. And I try and stay away from things that one or another compiler 
thinks is a built-in.

I do need to deal with subnormals but I can handle that. Besides, any 
comparison of subnormals does not trigger an exception unless there are 
arithmetic expressions as either a LHS or RHS of the comparison operator. 
Mind you, I once saw some code where it looks like the author did think 
that an underflow exception got triggered during the comparison of a 
possibly subnormal number against a constant which was not subnormal.

> Musl strives to minimize the numeric error while also delivering good 
> performance, and that means that often a lot of boundary conditions can 
> be detected at the same time with a single comparison (e.g. you can 
> detect "x < 0 || x > 2**limit || isinf(x)" by detecting if the exponent 
> and sign bit together exceed a certain limit.)

What MUSL's strives to do is indeed what I also seek. That said, I have 
found that you often get less lines of code and better performance if you 
can postpone the inspection of the IEEE 754 encoding as late as possible 
within a routine. It is only at that point do you think about extracting 
the exponent and sign cheaply.

Just my 2c.

Regards - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-26  3:55         ` Damian McGuckin
@ 2019-02-27 14:14           ` Alexander Monakov
  2019-02-27 15:38             ` Damian McGuckin
  0 siblings, 1 reply; 27+ messages in thread
From: Alexander Monakov @ 2019-02-27 14:14 UTC (permalink / raw)
  To: musl

On Tue, 26 Feb 2019, Damian McGuckin wrote:

> > Yet another problem brought to you by premature optimization. What you
> > want to know is if a certain number is NaN. There's a perfectly
> > acceptable idiom for that:
> > 
> > if (isnan(x)) {
> > }
> 
> I understand this. But, at least on an X86 architecture, that involves a
> write-to+read-from memory and I want to avoid that.

I don't understand this claim.  With both SSE and x87 this should amount to
comparing a register with itself and testing flags.  Can you elaborate?

> > Well, sorry, but these instructions do not work that way. Any operation
> > on a NaN, including comparison, even comparison for equality, will raise
> > IE, at least if it is an sNaN.

(for sNaNs, sure, but notably for qNaNs comparisons for equality, as opposed
to ordered comparisons, should not raise "invalid" in C and C++)

> However, on experiments on GCC, the if/else/else/else above does not raise an
> IE. Is this an optimizer bug?

You're probably seeing the long-standing bug in gcc x86 backend where it would
emit 'ucom'-kind instructions for both ordered and equality comparisons.  It
appears to be finally fixed starting from GCC 8.

Alexander


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 14:14           ` Alexander Monakov
@ 2019-02-27 15:38             ` Damian McGuckin
  2019-02-27 16:00               ` Alexander Monakov
  0 siblings, 1 reply; 27+ messages in thread
From: Damian McGuckin @ 2019-02-27 15:38 UTC (permalink / raw)
  To: musl


On Wed, 27 Feb 2019, Alexander Monakov wrote:

>> I understand this. But, at least on an X86 architecture, that involves 
>> a write-to+read-from memory and I want to avoid that.
>
> I don't understand this claim.  With both SSE and x87 this should amount 
> to comparing a register with itself and testing flags.  Can you 
> elaborate?

I would love to be proved wrong, but if you want something that is safe 
from generating an exception with an signalling NaN, you need to do this.

For qNaN stuff, I personally normally do

 	if (x != x) /* then 'x' is an NaN */

but I find that isnan(x) does not expand to anything like this.  Anyway, 
when I tried the code below, I was just shocked.

 	#include	<math.h>
 	#include	<stdio.h>

 	main()
 	{
 		double x = 5.0;

 		x -= x, x /= x;
 		printf("what %s\n", isnan(x) ? "yes" : "no!");
 		return(0);
 	}

Looking at the assembler, there is a subroutine call to __isnan. Awful!

>>> Well, sorry, but these instructions do not work that way. Any 
>>> operation on a NaN, including comparison, even comparison for 
>>> equality, will raise IE, at least if it is an sNaN.
>
> (for sNaNs, sure, but notably for qNaNs comparisons for equality, as 
> opposed to ordered comparisons, should not raise "invalid" in C and C++)

You are correct. Markus was reading the standard incorrectly I believe. Or 
maybe my explanation of what I was trying to do was poor and Markus simply
misunderstood what I was trying to say!

>> However, on experiments on GCC, the if/else/else/else above does not 
>> raise an IE. Is this an optimizer bug?
>
> You're probably seeing the long-standing bug in gcc x86 backend where it 
> would emit 'ucom'-kind instructions for both ordered and equality 
> comparisons.  It appears to be finally fixed starting from GCC 8.

Wonderful. Thanks for that information. GCC 8 is on my list of updates but 
I have yet to get around to it. I will rerun my tests against that.

I do lament that I have to resort to using

 	isless()

macro and friends to do a comparison in C/C++ without triggering an IE. It 
really does seriously compromise the readability of code. It would be nice 
if we had operators like

 	~<=

instead of having to use the long-winded

 	islessequal

Than again, everybody wants their own succint operators and there are only 
a limited number of characters to exploit. I think Professor Kahan asked 
for
 	!<

for 'not less than' over 20 years ago and we have not seen any movement
on that front.

Regards - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 15:38             ` Damian McGuckin
@ 2019-02-27 16:00               ` Alexander Monakov
  2019-02-27 16:09                 ` Damian McGuckin
  0 siblings, 1 reply; 27+ messages in thread
From: Alexander Monakov @ 2019-02-27 16:00 UTC (permalink / raw)
  To: musl

On Thu, 28 Feb 2019, Damian McGuckin wrote:

> I tried the code below, I was just shocked.
> 
> 	#include	<math.h>
> 	#include	<stdio.h>
> 
> 	main()
> 	{
> 		double x = 5.0;
> 
> 		x -= x, x /= x;
> 		printf("what %s\n", isnan(x) ? "yes" : "no!");
> 		return(0);
> 	}
> 
> Looking at the assembler, there is a subroutine call to __isnan. Awful!

Hm, no, for x86 with GCC you should not see that: the compiler knows how
to expand isnan efficiently.  Are you perhaps on OS X and the 'gcc' command
actually invokes Clang/LLVM?  If not, can you show output of 'gcc -v',
command-line flags you used, and the assembly you're seeing?

Thanks.
Alexander


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:00               ` Alexander Monakov
@ 2019-02-27 16:09                 ` Damian McGuckin
  2019-02-27 16:14                   ` Markus Wichmann
  2019-02-27 16:32                   ` Alexander Monakov
  0 siblings, 2 replies; 27+ messages in thread
From: Damian McGuckin @ 2019-02-27 16:09 UTC (permalink / raw)
  To: musl


Thanks for the feedback.

On Wed, 27 Feb 2019, Alexander Monakov wrote:

> On Thu, 28 Feb 2019, Damian McGuckin wrote:
>
>> I tried the code below, I was just shocked.
>>
>> 	#include	<math.h>
>> 	#include	<stdio.h>
>>
>> 	main()
>> 	{
>> 		double x = 5.0;
>>
>> 		x -= x, x /= x;
>> 		printf("what %s\n", isnan(x) ? "yes" : "no!");
>> 		return(0);
>> 	}
>>
>> Looking at the assembler, there is a subroutine call to __isnan. Awful!
>
> Hm, no, for x86 with GCC you should not see that: the compiler knows how 
> to expand isnan efficiently.  Are you perhaps on OS X and the 'gcc' 
> command actually invokes Clang/LLVM?

No.

> If not, can you show output of 'gcc -v', command-line flags you used, 
> and the assembly you're seeing?

 	gcc -O3 -S -msse4.2 -mfma mynan.c

Here is the assembler:

 	.file	"mynan.c"
 	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
 	.string	"yes"
.LC1:
 	.string	"no!"
.LC3:
 	.string	"what %s\n"
 	.section	.text.startup,"ax",@progbits
 	.p2align 4,,15
 	.globl	main
 	.type	main, @function
main:
.LFB14:
 	.cfi_startproc
 	vxorpd	%xmm0, %xmm0, %xmm0
 	subq	$8, %rsp
 	.cfi_def_cfa_offset 16
 	vdivsd	%xmm0, %xmm0, %xmm0
 	call	__isnan
 	movl	$.LC0, %esi
 	testl	%eax, %eax
 	movl	$.LC1, %eax
 	cmove	%rax, %rsi
 	movl	$.LC3, %edi
 	xorl	%eax, %eax
 	call	printf
 	xorl	%eax, %eax
 	addq	$8, %rsp
 	.cfi_def_cfa_offset 8
 	ret
 	.cfi_endproc
.LFE14:
 	.size	main, .-main
 	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
 	.section	.note.GNU-stack,"",@progbits

Regards - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:09                 ` Damian McGuckin
@ 2019-02-27 16:14                   ` Markus Wichmann
  2019-02-27 16:20                     ` Damian McGuckin
  2019-02-28  1:07                     ` Damian McGuckin
  2019-02-27 16:32                   ` Alexander Monakov
  1 sibling, 2 replies; 27+ messages in thread
From: Markus Wichmann @ 2019-02-27 16:14 UTC (permalink / raw)
  To: musl

On Thu, Feb 28, 2019 at 03:09:54AM +1100, Damian McGuckin wrote:
> 	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"

You might want to consider upgrading:

	.file	"nan.c"
	.text
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"yes"
.LC1:
	.string	"no!"
.LC3:
	.string	"what %s\n"
	.section	.text.startup,"ax",@progbits
	.p2align 4,,15
	.globl	main
	.type	main, @function
main:
.LFB17:
	.cfi_startproc
	pxor	%xmm0, %xmm0
	subq	$8, %rsp
	.cfi_def_cfa_offset 16
	movabsq	$9218868437227405312, %rdx
	divsd	%xmm0, %xmm0
	leaq	.LC0(%rip), %rsi
	leaq	.LC3(%rip), %rdi
	movq	%xmm0, %rax
	btrq	$63, %rax
	cmpq	%rdx, %rax
	leaq	.LC1(%rip), %rax
	cmovbe	%rax, %rsi
	xorl	%eax, %eax
	call	printf@PLT
	xorl	%eax, %eax
	addq	$8, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE17:
	.size	main, .-main
	.ident	"GCC: (Debian 8.2.0-14) 8.2.0"
	.section	.note.GNU-stack,"",@progbits

That sufficiently efficient for you?

Ciao,
Markus


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:14                   ` Markus Wichmann
@ 2019-02-27 16:20                     ` Damian McGuckin
  2019-02-28  1:07                     ` Damian McGuckin
  1 sibling, 0 replies; 27+ messages in thread
From: Damian McGuckin @ 2019-02-27 16:20 UTC (permalink / raw)
  To: musl


On Wed, 27 Feb 2019, Markus Wichmann wrote:

> That sufficiently efficient for you?

Yes.

Thanks - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:09                 ` Damian McGuckin
  2019-02-27 16:14                   ` Markus Wichmann
@ 2019-02-27 16:32                   ` Alexander Monakov
  2019-02-27 16:42                     ` Rich Felker
  1 sibling, 1 reply; 27+ messages in thread
From: Alexander Monakov @ 2019-02-27 16:32 UTC (permalink / raw)
  To: musl

On Thu, 28 Feb 2019, Damian McGuckin wrote:

> > Hm, no, for x86 with GCC you should not see that: the compiler knows how to
> > expand isnan efficiently.  Are you perhaps on OS X and the 'gcc' command
> > actually invokes Clang/LLVM?
> 
> No.
> 
> > If not, can you show output of 'gcc -v', command-line flags you used, and
> > the assembly you're seeing?
> 
> 	gcc -O3 -S -msse4.2 -mfma mynan.c

Ah, in this case you're falling victim of a problem in your Glibc version:
while GCC is sufficiently new to know how to expand isnan efficiently,
Glibc math.h defines isnan as a macro that redirects to __isnan that GCC
does not recognize. Newer Glibc versions use __builtin_isnan where suitable,
which leads to optimal assembly.

(musl does not use this builtin, expanding the macro to a bit test instead)

Alexander


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:32                   ` Alexander Monakov
@ 2019-02-27 16:42                     ` Rich Felker
  2019-02-27 17:08                       ` Szabolcs Nagy
  2019-02-27 17:14                       ` Alexander Monakov
  0 siblings, 2 replies; 27+ messages in thread
From: Rich Felker @ 2019-02-27 16:42 UTC (permalink / raw)
  To: musl

On Wed, Feb 27, 2019 at 07:32:01PM +0300, Alexander Monakov wrote:
> On Thu, 28 Feb 2019, Damian McGuckin wrote:
> 
> > > Hm, no, for x86 with GCC you should not see that: the compiler knows how to
> > > expand isnan efficiently.  Are you perhaps on OS X and the 'gcc' command
> > > actually invokes Clang/LLVM?
> > 
> > No.
> > 
> > > If not, can you show output of 'gcc -v', command-line flags you used, and
> > > the assembly you're seeing?
> > 
> > 	gcc -O3 -S -msse4.2 -mfma mynan.c
> 
> Ah, in this case you're falling victim of a problem in your Glibc version:
> while GCC is sufficiently new to know how to expand isnan efficiently,
> Glibc math.h defines isnan as a macro that redirects to __isnan that GCC
> does not recognize. Newer Glibc versions use __builtin_isnan where suitable,
> which leads to optimal assembly.
> 
> (musl does not use this builtin, expanding the macro to a bit test instead)

Are there reasons we should perhaps use the __builtin versions of
these when __GNUC__ indicates they're available? I like our bit test
versions we have now, and I think they're sufficiently efficient, but
I'm open to changes if there's a good reason.

Rich


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:42                     ` Rich Felker
@ 2019-02-27 17:08                       ` Szabolcs Nagy
  2019-02-27 17:14                       ` Alexander Monakov
  1 sibling, 0 replies; 27+ messages in thread
From: Szabolcs Nagy @ 2019-02-27 17:08 UTC (permalink / raw)
  To: musl

* Rich Felker <dalias@libc.org> [2019-02-27 11:42:25 -0500]:
> On Wed, Feb 27, 2019 at 07:32:01PM +0300, Alexander Monakov wrote:
> > On Thu, 28 Feb 2019, Damian McGuckin wrote:
> > 
> > > > Hm, no, for x86 with GCC you should not see that: the compiler knows how to
> > > > expand isnan efficiently.  Are you perhaps on OS X and the 'gcc' command
> > > > actually invokes Clang/LLVM?
> > > 
> > > No.
> > > 
> > > > If not, can you show output of 'gcc -v', command-line flags you used, and
> > > > the assembly you're seeing?
> > > 
> > > 	gcc -O3 -S -msse4.2 -mfma mynan.c
> > 
> > Ah, in this case you're falling victim of a problem in your Glibc version:
> > while GCC is sufficiently new to know how to expand isnan efficiently,
> > Glibc math.h defines isnan as a macro that redirects to __isnan that GCC
> > does not recognize. Newer Glibc versions use __builtin_isnan where suitable,
> > which leads to optimal assembly.
> > 
> > (musl does not use this builtin, expanding the macro to a bit test instead)
> 
> Are there reasons we should perhaps use the __builtin versions of
> these when __GNUC__ indicates they're available? I like our bit test
> versions we have now, and I think they're sufficiently efficient, but
> I'm open to changes if there's a good reason.

yeah, a target may have slow fpreg->greg moves to do the bit checks,
but fast single instruction check on the fpreg and then the builtin
would be preferred.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:42                     ` Rich Felker
  2019-02-27 17:08                       ` Szabolcs Nagy
@ 2019-02-27 17:14                       ` Alexander Monakov
  2019-02-27 17:26                         ` Rich Felker
  1 sibling, 1 reply; 27+ messages in thread
From: Alexander Monakov @ 2019-02-27 17:14 UTC (permalink / raw)
  To: musl



On Wed, 27 Feb 2019, Rich Felker wrote:

> Are there reasons we should perhaps use the __builtin versions of
> these when __GNUC__ indicates they're available? I like our bit test
> versions we have now, and I think they're sufficiently efficient, but
> I'm open to changes if there's a good reason.

Well, it really depends on what one considers 'sufficiently efficient'.
Instead of comparing a register with itself and testing flags (2 instructions)
you get (for 'int f(double x){return isnan(x);}'):

f:
        movabsq $9223372036854775807, %rdx
        movq    %xmm0, %rax
        andq    %rdx, %rax
        movabsq $9218868437227405312, %rdx
        cmpq    %rdx, %rax
        seta    %al
        movzbl  %al, %eax
        ret

(note that movq %xmm0, %rax is going to be more costly than a normal
move as it crosses from fp to integer domain in the cpu)

I think musl bit test can be implemented more efficiently via right-shifting
the representation in %rax first, avoiding 64-bit immediates, but even then
I'd say the "native" version is preferable.

Alexander


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 17:14                       ` Alexander Monakov
@ 2019-02-27 17:26                         ` Rich Felker
  2019-02-27 19:36                           ` Szabolcs Nagy
  2019-02-27 19:48                           ` Alexander Monakov
  0 siblings, 2 replies; 27+ messages in thread
From: Rich Felker @ 2019-02-27 17:26 UTC (permalink / raw)
  To: musl

On Wed, Feb 27, 2019 at 08:14:07PM +0300, Alexander Monakov wrote:
> 
> 
> On Wed, 27 Feb 2019, Rich Felker wrote:
> 
> > Are there reasons we should perhaps use the __builtin versions of
> > these when __GNUC__ indicates they're available? I like our bit test
> > versions we have now, and I think they're sufficiently efficient, but
> > I'm open to changes if there's a good reason.
> 
> Well, it really depends on what one considers 'sufficiently efficient'.
> Instead of comparing a register with itself and testing flags (2 instructions)
> you get (for 'int f(double x){return isnan(x);}'):
> 
> f:
>         movabsq $9223372036854775807, %rdx
>         movq    %xmm0, %rax
>         andq    %rdx, %rax
>         movabsq $9218868437227405312, %rdx
>         cmpq    %rdx, %rax
>         seta    %al
>         movzbl  %al, %eax
>         ret
> 
> (note that movq %xmm0, %rax is going to be more costly than a normal
> move as it crosses from fp to integer domain in the cpu)
> 
> I think musl bit test can be implemented more efficiently via right-shifting
> the representation in %rax first, avoiding 64-bit immediates,

Or left-shifting rather than masking to get rid of the sign bit?
That's all it's doing. I don't think right-shift is okay since losing
any low bits would break the comparison.

> but even then
> I'd say the "native" version is preferable.

I suspect this is probably true, though I also worry a bit whether
there are archs where it does something inefficient or broken.

Ideally the compiler would be able to recognize portable (within IEEE)
patterns for floating point representation examination and optimize
them if there's a more efficient way to be able to do it for a
particular machine.

Rich


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 17:26                         ` Rich Felker
@ 2019-02-27 19:36                           ` Szabolcs Nagy
  2019-02-27 19:48                           ` Alexander Monakov
  1 sibling, 0 replies; 27+ messages in thread
From: Szabolcs Nagy @ 2019-02-27 19:36 UTC (permalink / raw)
  To: musl

* Rich Felker <dalias@libc.org> [2019-02-27 12:26:41 -0500]:
> On Wed, Feb 27, 2019 at 08:14:07PM +0300, Alexander Monakov wrote:
> > On Wed, 27 Feb 2019, Rich Felker wrote:
> > 
> > > Are there reasons we should perhaps use the __builtin versions of
> > > these when __GNUC__ indicates they're available? I like our bit test
> > > versions we have now, and I think they're sufficiently efficient, but
> > > I'm open to changes if there's a good reason.
> > 
> > Well, it really depends on what one considers 'sufficiently efficient'.
> > Instead of comparing a register with itself and testing flags (2 instructions)
> > you get (for 'int f(double x){return isnan(x);}'):
> > 
> > f:
> >         movabsq $9223372036854775807, %rdx
> >         movq    %xmm0, %rax
> >         andq    %rdx, %rax
> >         movabsq $9218868437227405312, %rdx
> >         cmpq    %rdx, %rax
> >         seta    %al
> >         movzbl  %al, %eax
> >         ret
> > 
> > (note that movq %xmm0, %rax is going to be more costly than a normal
> > move as it crosses from fp to integer domain in the cpu)
> > 
> > I think musl bit test can be implemented more efficiently via right-shifting
> > the representation in %rax first, avoiding 64-bit immediates,
> 
> Or left-shifting rather than masking to get rid of the sign bit?
> That's all it's doing. I don't think right-shift is okay since losing
> any low bits would break the comparison.
> 
> > but even then
> > I'd say the "native" version is preferable.
> 
> I suspect this is probably true, though I also worry a bit whether
> there are archs where it does something inefficient or broken.

e.g. isnan is broken with -fsignaling-nan since it should
not signal but the ucomisd gcc generates does as discussed.

(although it's unlikely to matter much: we dont support
snan in all apis)

but gcc used to generate horrible code for fpclassify things,
nowadays it should be mostly fixed, i don't remember if
there were actual correctness bugs or just inefficient code.

> 
> Ideally the compiler would be able to recognize portable (within IEEE)
> patterns for floating point representation examination and optimize
> them if there's a more efficient way to be able to do it for a
> particular machine.
> 
> Rich


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 17:26                         ` Rich Felker
  2019-02-27 19:36                           ` Szabolcs Nagy
@ 2019-02-27 19:48                           ` Alexander Monakov
  2019-02-27 20:16                             ` Szabolcs Nagy
  1 sibling, 1 reply; 27+ messages in thread
From: Alexander Monakov @ 2019-02-27 19:48 UTC (permalink / raw)
  To: musl

On Wed, 27 Feb 2019, Rich Felker wrote:

> Or left-shifting rather than masking to get rid of the sign bit?
> That's all it's doing. I don't think right-shift is okay since losing
> any low bits would break the comparison.

Right, thanks. Make it a rotate then: with a rotate you can place the
exponent in the least significant bits, then force sign bit to 1 and
compare against a small immediate.

(note that on 32-bit this bit test makes a mess for doubles anyhow)

> > but even then
> > I'd say the "native" version is preferable.
> 
> I suspect this is probably true, though I also worry a bit whether
> there are archs where it does something inefficient or broken.
> 
> Ideally the compiler would be able to recognize portable (within IEEE)
> patterns for floating point representation examination and optimize
> them if there's a more efficient way to be able to do it for a
> particular machine.

There's a difference for sNaN operands: the bit-test version obviously
is not going to raise "invalid", while comparing the fpu register with
itself will.  So I'm afraid the compiler wouldn't do that for x86 (but
could for targets where an suitable instruction is available).

Alexander


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 19:48                           ` Alexander Monakov
@ 2019-02-27 20:16                             ` Szabolcs Nagy
  2019-02-27 20:35                               ` Rich Felker
  0 siblings, 1 reply; 27+ messages in thread
From: Szabolcs Nagy @ 2019-02-27 20:16 UTC (permalink / raw)
  To: musl

* Alexander Monakov <amonakov@ispras.ru> [2019-02-27 22:48:02 +0300]:
> On Wed, 27 Feb 2019, Rich Felker wrote:
> > Ideally the compiler would be able to recognize portable (within IEEE)
> > patterns for floating point representation examination and optimize
> > them if there's a more efficient way to be able to do it for a
> > particular machine.
> 
> There's a difference for sNaN operands: the bit-test version obviously
> is not going to raise "invalid", while comparing the fpu register with
> itself will.  So I'm afraid the compiler wouldn't do that for x86 (but
> could for targets where an suitable instruction is available).

using -fsignaling-nan is extremely rare, by default the transformation
is valid (but maybe tricky anyway).


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 20:16                             ` Szabolcs Nagy
@ 2019-02-27 20:35                               ` Rich Felker
  2019-02-27 21:03                                 ` Szabolcs Nagy
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2019-02-27 20:35 UTC (permalink / raw)
  To: musl

On Wed, Feb 27, 2019 at 09:16:09PM +0100, Szabolcs Nagy wrote:
> * Alexander Monakov <amonakov@ispras.ru> [2019-02-27 22:48:02 +0300]:
> > On Wed, 27 Feb 2019, Rich Felker wrote:
> > > Ideally the compiler would be able to recognize portable (within IEEE)
> > > patterns for floating point representation examination and optimize
> > > them if there's a more efficient way to be able to do it for a
> > > particular machine.
> > 
> > There's a difference for sNaN operands: the bit-test version obviously
> > is not going to raise "invalid", while comparing the fpu register with
> > itself will.  So I'm afraid the compiler wouldn't do that for x86 (but
> > could for targets where an suitable instruction is available).
> 
> using -fsignaling-nan is extremely rare, by default the transformation
> is valid (but maybe tricky anyway).

I'm not sure if I'd call transforming non-floating-point
bit-manipulation code into a floating point instruction that alters
exception flags "valid" regardless of the -fsignaling-nan state. It's
one thing to say "this program isn't using and doesn't care about
signaling nans [as floating point values]"; it's completely different
to say "you can optimize integer operations as floating point without
regard for how that affects fenv".

Rich


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 20:35                               ` Rich Felker
@ 2019-02-27 21:03                                 ` Szabolcs Nagy
  0 siblings, 0 replies; 27+ messages in thread
From: Szabolcs Nagy @ 2019-02-27 21:03 UTC (permalink / raw)
  To: musl

* Rich Felker <dalias@libc.org> [2019-02-27 15:35:03 -0500]:
> On Wed, Feb 27, 2019 at 09:16:09PM +0100, Szabolcs Nagy wrote:
> > * Alexander Monakov <amonakov@ispras.ru> [2019-02-27 22:48:02 +0300]:
> > > On Wed, 27 Feb 2019, Rich Felker wrote:
> > > > Ideally the compiler would be able to recognize portable (within IEEE)
> > > > patterns for floating point representation examination and optimize
> > > > them if there's a more efficient way to be able to do it for a
> > > > particular machine.
> > > 
> > > There's a difference for sNaN operands: the bit-test version obviously
> > > is not going to raise "invalid", while comparing the fpu register with
> > > itself will.  So I'm afraid the compiler wouldn't do that for x86 (but
> > > could for targets where an suitable instruction is available).
> > 
> > using -fsignaling-nan is extremely rare, by default the transformation
> > is valid (but maybe tricky anyway).
> 
> I'm not sure if I'd call transforming non-floating-point
> bit-manipulation code into a floating point instruction that alters
> exception flags "valid" regardless of the -fsignaling-nan state. It's
> one thing to say "this program isn't using and doesn't care about
> signaling nans [as floating point values]"; it's completely different
> to say "you can optimize integer operations as floating point without
> regard for how that affects fenv".

ok i assumed gcc would also detect that the source of those bits
are from an fp value, but that may be too much to ask (and may
still have the same safety issue if the fp value is not from
normal fp computations).



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-27 16:14                   ` Markus Wichmann
  2019-02-27 16:20                     ` Damian McGuckin
@ 2019-02-28  1:07                     ` Damian McGuckin
  2019-02-28  1:27                       ` Rich Felker
  1 sibling, 1 reply; 27+ messages in thread
From: Damian McGuckin @ 2019-02-28  1:07 UTC (permalink / raw)
  To: musl

On Wed, 27 Feb 2019, Markus Wichmann wrote:

> On Thu, Feb 28, 2019 at 03:09:54AM +1100, Damian McGuckin wrote:
>> 	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
>
> You might want to consider upgrading:

Done. But the subroutine call is still hanging around. What am I doing 
wrong.

Yours is:

> 	.globl	main
> 	.type	main, @function
> main:
> .LFB17:
> 	.cfi_startproc
> 	pxor	%xmm0, %xmm0
> 	subq	$8, %rsp
> 	.cfi_def_cfa_offset 16
> 	movabsq	$9218868437227405312, %rdx
> 	divsd	%xmm0, %xmm0
> 	leaq	.LC0(%rip), %rsi
> 	leaq	.LC3(%rip), %rdi
> 	movq	%xmm0, %rax
> 	btrq	$63, %rax
> 	cmpq	%rdx, %rax
> 	leaq	.LC1(%rip), %rax
> 	cmovbe	%rax, %rsi
> 	xorl	%eax, %eax
> 	call	printf@PLT
> 	xorl	%eax, %eax
> 	addq	$8, %rsp
> 	.cfi_def_cfa_offset 8
> 	ret
> 	.cfi_endproc
> .LFE17:
> 	.size	main, .-main
> 	.ident	"GCC: (Debian 8.2.0-14) 8.2.0"
> 	.section	.note.GNU-stack,"",@progbits
>
> That sufficiently efficient for you?

It would be if I could achieve it.  What options do I need? I use

 	gcc -S -O3 -msse4.2 -mfma mynan.c

See below:

 	.file	"mynan.c"
 	.text
 	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
 	.string	"yes"
.LC1:
 	.string	"no!"
.LC3:
 	.string	"what %s\n"
 	.section	.text.startup,"ax",@progbits
 	.p2align 4,,15
 	.globl	main
 	.type	main, @function
main:
.LFB14:
 	.cfi_startproc
 	vxorpd	%xmm0, %xmm0, %xmm0
 	subq	$8, %rsp
 	.cfi_def_cfa_offset 16
 	vdivsd	%xmm0, %xmm0, %xmm0
 	call	__isnan
 	movl	$.LC0, %esi
 	movl	$.LC3, %edi
 	testl	%eax, %eax
 	movl	$.LC1, %eax
 	cmove	%rax, %rsi
 	xorl	%eax, %eax
 	call	printf
 	xorl	%eax, %eax
 	addq	$8, %rsp
 	.cfi_def_cfa_offset 8
 	ret
 	.cfi_endproc
.LFE14:
 	.size	main, .-main
 	.ident	"GCC: (GNU) 8.2.1 20180905 (Red Hat 8.2.1-3)"
 	.section	.note.GNU-stack,"",@progbits

It is the standard package with devtools-8 under CentOS.

Thanks - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-28  1:07                     ` Damian McGuckin
@ 2019-02-28  1:27                       ` Rich Felker
  2019-02-28  2:28                         ` Damian McGuckin
  0 siblings, 1 reply; 27+ messages in thread
From: Rich Felker @ 2019-02-28  1:27 UTC (permalink / raw)
  To: musl

On Thu, Feb 28, 2019 at 12:07:36PM +1100, Damian McGuckin wrote:
> On Wed, 27 Feb 2019, Markus Wichmann wrote:
> 
> >On Thu, Feb 28, 2019 at 03:09:54AM +1100, Damian McGuckin wrote:
> >>	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-36)"
> >
> >You might want to consider upgrading:
> 
> Done. But the subroutine call is still hanging around. What am I
> doing wrong.

It's an old glibc, not an old gcc, causing this.

Rich


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: FE Exception triggered by comparison
  2019-02-28  1:27                       ` Rich Felker
@ 2019-02-28  2:28                         ` Damian McGuckin
  0 siblings, 0 replies; 27+ messages in thread
From: Damian McGuckin @ 2019-02-28  2:28 UTC (permalink / raw)
  To: musl

On Wed, 27 Feb 2019, Rich Felker wrote:

>> Done. But the subroutine call is still hanging around. What am I
>> doing wrong.
>
> It's an old glibc, not an old gcc, causing this.

Don't worry. With MUSL's definitions, it is all in-line.

Not really interested in GLIBC. I was just reverting to vanilla stuff for 
my testing in case I was doing stupid things with MUSL, ....

And Alexander was right, I was being stabbed in the back by GCC with its
use of UCOM... rather than COM.... That just added to my confusion. I also 
move back and forth between Chapel and C/C++ which further scrambles the 
thought processes.

All sorted. Thanks - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2019-02-28  2:28 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-24 13:28 FE Exception triggered by comparison Damian McGuckin
2019-02-24 17:12 ` Markus Wichmann
2019-02-24 19:25 ` Szabolcs Nagy
2019-02-24 20:04   ` Jens Gustedt
2019-02-24 21:50     ` Damian McGuckin
2019-02-25  5:21       ` Damian McGuckin
2019-02-25 15:51       ` Markus Wichmann
2019-02-26  3:55         ` Damian McGuckin
2019-02-27 14:14           ` Alexander Monakov
2019-02-27 15:38             ` Damian McGuckin
2019-02-27 16:00               ` Alexander Monakov
2019-02-27 16:09                 ` Damian McGuckin
2019-02-27 16:14                   ` Markus Wichmann
2019-02-27 16:20                     ` Damian McGuckin
2019-02-28  1:07                     ` Damian McGuckin
2019-02-28  1:27                       ` Rich Felker
2019-02-28  2:28                         ` Damian McGuckin
2019-02-27 16:32                   ` Alexander Monakov
2019-02-27 16:42                     ` Rich Felker
2019-02-27 17:08                       ` Szabolcs Nagy
2019-02-27 17:14                       ` Alexander Monakov
2019-02-27 17:26                         ` Rich Felker
2019-02-27 19:36                           ` Szabolcs Nagy
2019-02-27 19:48                           ` Alexander Monakov
2019-02-27 20:16                             ` Szabolcs Nagy
2019-02-27 20:35                               ` Rich Felker
2019-02-27 21:03                                 ` Szabolcs Nagy

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).