public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* patch to fix rtl documentation for new floating point comparisons
@ 2015-02-09 19:11 Kenneth Zadeck
  2015-02-09 23:25 ` Joseph Myers
  2015-02-09 23:26 ` Richard Henderson
  0 siblings, 2 replies; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-09 19:11 UTC (permalink / raw)
  To: gcc-patches, Joseph Myers

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

Before I commit this, or do the corresponding tree level patch, I would 
like this to be looked at by the FP people.   I am guessing at some of 
this, other parts i gleaned from various standards docs and an irc 
conversation with Joseph.   This should have been documented when it was 
put into the compiler.  This is certainly not obvious.


Kenny

[-- Attachment #2: frtl.diff --]
[-- Type: text/x-patch, Size: 6949 bytes --]

Index: gcc/doc/rtl.texi
===================================================================
--- gcc/doc/rtl.texi	(revision 220541)
+++ gcc/doc/rtl.texi	(working copy)
@@ -2553,40 +2553,52 @@ of comparisons is supported on a particu
 pass will try to merge the operations to produce the @code{eq} shown
 in case it exists in the context of the particular insn involved.
 
-Inequality comparisons come in two flavors, signed and unsigned.  Thus,
-there are distinct expression codes @code{gt} and @code{gtu} for signed and
-unsigned greater-than.  These can produce different results for the same
-pair of integer values: for example, 1 is signed greater-than @minus{}1 but not
-unsigned greater-than, because @minus{}1 when regarded as unsigned is actually
+Fixed point inequality comparisons come in two flavors, signed and
+unsigned.  Thus, there are distinct expression codes @code{gt} and
+@code{gtu} for signed and unsigned greater-than.  These can produce
+different results for the same pair of integer values: for example, 1
+is signed greater-than @minus{}1 but not unsigned greater-than,
+because @minus{}1 when regarded as unsigned is actually
 @code{0xffffffff} which is greater than 1.
 
-The signed comparisons are also used for floating point values.  Floating
-point comparisons are distinguished by the machine modes of the operands.
+Floating point comparisons come in two flavors, signaling and quiet,
+though these are not always paired.  The fixed point signed
+comparisons are also used for floating point comparisons.  Floating
+point comparisons are distinguished by the machine modes of the
+operands.
 
 @table @code
 @findex eq
 @cindex equal
 @item (eq:@var{m} @var{x} @var{y})
-@code{STORE_FLAG_VALUE} if the values represented by @var{x} and @var{y}
-are equal, otherwise 0.
+@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
+@var{y} are equal, otherwise 0.  If the operands are floating point,
+this is a quiet comparison and corresponds to the IEC 60559
+@code{compareQuietEqual} operation.
 
 @findex ne
 @cindex not equal
 @item (ne:@var{m} @var{x} @var{y})
-@code{STORE_FLAG_VALUE} if the values represented by @var{x} and @var{y}
-are not equal, otherwise 0.
+@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
+@var{y} are not equal, otherwise 0. If the operands are floating
+point, this is a quiet comparison and corresponds to the IEC 60559
+@code{compareQuietNotEqual} operation.
 
 @findex gt
 @cindex greater than
 @item (gt:@var{m} @var{x} @var{y})
-@code{STORE_FLAG_VALUE} if the @var{x} is greater than @var{y}.  If they
-are fixed-point, the comparison is done in a signed sense.
+@code{STORE_FLAG_VALUE} if the @var{x} is greater than @var{y}.  If
+the operands are fixed-point, the comparison is done in a signed
+sense.  If the operands are floating point, this is a signaling
+comparison and corresponds to the IEC 60559
+@code{compareSignalingGreater} operation.
 
 @findex gtu
 @cindex greater than
 @cindex unsigned greater than
 @item (gtu:@var{m} @var{x} @var{y})
-Like @code{gt} but does unsigned comparison, on fixed-point numbers only.
+Like @code{gt} but does unsigned comparison, on fixed-point numbers
+only.  This is undefined for floating point numbers.
 
 @findex lt
 @cindex less than
@@ -2594,7 +2606,10 @@ Like @code{gt} but does unsigned compari
 @cindex unsigned less than
 @item (lt:@var{m} @var{x} @var{y})
 @itemx (ltu:@var{m} @var{x} @var{y})
-Like @code{gt} and @code{gtu} but test for ``less than''.
+Like @code{gt} and @code{gtu} but test for ``less than''. If the
+operands are floating point, @code{gt} is a signaling comparison and
+corresponds to the IEC 60559 @code{compareSignalingLess} operation.
+@code{gtu} is undefined for floating point numbers.
 
 @findex ge
 @cindex greater than
@@ -2603,6 +2618,10 @@ Like @code{gt} and @code{gtu} but test f
 @item (ge:@var{m} @var{x} @var{y})
 @itemx (geu:@var{m} @var{x} @var{y})
 Like @code{gt} and @code{gtu} but test for ``greater than or equal''.
+If the operands are floating point, @code{ge} is a signaling
+comparison and corresponds to the IEC 60559
+@code{compareSignalingGreater} operation.  @code{geu} is undefined for
+floating point numbers.
 
 @findex le
 @cindex less than or equal
@@ -2610,7 +2629,64 @@ Like @code{gt} and @code{gtu} but test f
 @cindex unsigned less than
 @item (le:@var{m} @var{x} @var{y})
 @itemx (leu:@var{m} @var{x} @var{y})
-Like @code{gt} and @code{gtu} but test for ``less than or equal''.
+Like @code{gt} and @code{gtu} but test for ``less than or equal''.  If
+the operands are floating point, @code{le} is a signaling comparison
+and corresponds to the IEC 60559 @code{compareSignalingLess}
+operation.  @code{leu} is undefined for floating point numbers.
+
+@table @code
+@findex unlt
+@cindex unordered less than
+@item (unlt:@var{m} @var{x} @var{y})
+@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
+@var{y} are less or unordered, otherwise 0.  This is a quiet operation
+that applies only to floating point operands and corresponds to the
+IEC 60559 @code{compareQuietLessUnordered} operation.
+
+@table @code
+@findex unle
+@cindex unordered less equal
+@item (unle:@var{m} @var{x} @var{y})
+@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
+@var{y} are less, equal, or unordered, otherwise 0.  This is a quiet
+operation that applies only to floating point operands and corresponds
+to the IEC 60559 @code{compareQuietNotGreater} operation.
+
+@table @code
+@findex ltgt
+@cindex less than or greater than
+@item (ltgt:@var{m} @var{x} @var{y})
+@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
+@var{y} are less, or greater, otherwise 0.  This is a quiet operation
+that applies only to floating point operands and does not have a
+corresponding IEC 60559 operation.
+
+@table @code
+@findex uneq
+@cindex unordered or equal
+@item (uneq:@var{m} @var{x} @var{y})
+@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
+@var{y} are unordered or equal, otherwise 0.  This is a quiet
+operation that applies only to floating point operands and does not
+have a corresponding IEC 60559 operation.
+
+@table @code
+@findex ordered
+@cindex less equal or greater
+@item (ordered:@var{m} @var{x} @var{y})
+@code{STORE_FLAG_VALUE} if the values represented by both @var{x} and
+@var{y} are not nan, otherwise 0.  This is a quiet operation that
+applies only to floating point operands and corresponds to the IEC
+60559 @code{compareQuietOrdered} operation.
+
+@table @code
+@findex unordered
+@cindex is a nan
+@item (unordered:@var{m} @var{x} @var{y})
+@code{STORE_FLAG_VALUE} if the values represented by either @var{x}
+and either @var{y} are nan, otherwise 0.  This is a quiet operation
+that applies only to floating point operands and corresponds to the
+IEC 60559 @code{compareQuietUnordered} operation.
 
 @findex if_then_else
 @item (if_then_else @var{cond} @var{then} @var{else})

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-09 19:11 patch to fix rtl documentation for new floating point comparisons Kenneth Zadeck
@ 2015-02-09 23:25 ` Joseph Myers
  2015-02-10  1:16   ` Kenneth Zadeck
  2015-02-10 21:54   ` Eric Botcazou
  2015-02-09 23:26 ` Richard Henderson
  1 sibling, 2 replies; 19+ messages in thread
From: Joseph Myers @ 2015-02-09 23:25 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: gcc-patches

On Mon, 9 Feb 2015, Kenneth Zadeck wrote:

>  @findex ge
>  @cindex greater than
> @@ -2603,6 +2618,10 @@ Like @code{gt} and @code{gtu} but test f
>  @item (ge:@var{m} @var{x} @var{y})
>  @itemx (geu:@var{m} @var{x} @var{y})
>  Like @code{gt} and @code{gtu} but test for ``greater than or equal''.
> +If the operands are floating point, @code{ge} is a signaling
> +comparison and corresponds to the IEC 60559
> +@code{compareSignalingGreater} operation.  @code{geu} is undefined for
> +floating point numbers.

No, compareSignalingGreaterEqual.

>  @findex le
>  @cindex less than or equal
> @@ -2610,7 +2629,64 @@ Like @code{gt} and @code{gtu} but test f
>  @cindex unsigned less than
>  @item (le:@var{m} @var{x} @var{y})
>  @itemx (leu:@var{m} @var{x} @var{y})
> -Like @code{gt} and @code{gtu} but test for ``less than or equal''.
> +Like @code{gt} and @code{gtu} but test for ``less than or equal''.  If
> +the operands are floating point, @code{le} is a signaling comparison
> +and corresponds to the IEC 60559 @code{compareSignalingLess}
> +operation.  @code{leu} is undefined for floating point numbers.

compareSignalingLessEqual.

> +@table @code
> +@findex ltgt
> +@cindex less than or greater than
> +@item (ltgt:@var{m} @var{x} @var{y})
> +@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
> +@var{y} are less, or greater, otherwise 0.  This is a quiet operation
> +that applies only to floating point operands and does not have a
> +corresponding IEC 60559 operation.

On GENERIC, the documentation describes some ambiguity: "With the possible
exception of @code{LTGT_EXPR}, all of these operations are guaranteed
not to generate a floating point exception.".

LTGT (RTL code) was added by RTH in 
<https://gcc.gnu.org/ml/gcc-patches/2000-01/msg00974.html>.  LTGT_EXPR was 
added in the thread starting at 
<https://gcc.gnu.org/ml/gcc-patches/2004-05/msg01674.html>, wherein RTH 
stated "the LTGT rtl code is assumed to trap".  The documentation was soon 
thereafter changed to have the "possible exception" wording (r82467, which 
I can't find any sign of having been posted to gcc-patches so don't know 
the rationale).

I don't think it's useful to have the trapping semantics unspecified for a 
comparison operation like that.  So the question is what's most useful for 
LTGT and LTGT_EXPR to do (presumably they should do the same thing).  Lots 
of existing code in this area seems confused (for example, HONOR_SNANS 
should be irrelevant to reversing an equality comparison, as reversing it 
will change neither results nor exceptions raised, whether or not 
signaling NaNs are involved).  But maybe more code treats LTGT as a 
signaling operation than otherwise, in accordance with the original 
intent, and so that's the most appropriate way to document it (with !UNEQ 
being the representation of the corresponding quiet operation).

It's not clear to me that ad hoc logic around particular operations is the 
best way of handling optimizations in this area, instead of generic logic 
using four bits to track which conditions (< = > unordered) a comparison 
is true for and one bit to track whether it raises an exception for 
unordered operands.  Even if you keep using particular sets of tree / RTL 
codes for a subset of operations, maybe transformations that map into and 
out of such five-bit form would be more likely to be correct.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-09 19:11 patch to fix rtl documentation for new floating point comparisons Kenneth Zadeck
  2015-02-09 23:25 ` Joseph Myers
@ 2015-02-09 23:26 ` Richard Henderson
  2015-02-10  1:07   ` Kenneth Zadeck
  1 sibling, 1 reply; 19+ messages in thread
From: Richard Henderson @ 2015-02-09 23:26 UTC (permalink / raw)
  To: Kenneth Zadeck, gcc-patches, Joseph Myers

On 02/09/2015 11:10 AM, Kenneth Zadeck wrote:
> +@table @code
> +@findex ltgt
> +@cindex less than or greater than
> +@item (ltgt:@var{m} @var{x} @var{y})
> +@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
> +@var{y} are less, or greater, otherwise 0.  This is a quiet operation
> +that applies only to floating point operands and does not have a
> +corresponding IEC 60559 operation.

This is intended to match c99 7.12.14.5 islessgreater, which I believe is the
compareQuietNotEqual operation.

> +@table @code
> +@findex uneq
> +@cindex unordered or equal
> +@item (uneq:@var{m} @var{x} @var{y})
> +@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
> +@var{y} are unordered or equal, otherwise 0.  This is a quiet
> +operation that applies only to floating point operands and does not
> +have a corresponding IEC 60559 operation.

This is the strict inverse to LTGT, i.e. !compareQuietNotEqual, and you of
course note this is not the same as compareQuietEqual.

I believe that when the c99 math.h comparison builtins were added, treating
EQ+NE as quiet comparisons was common but not universal.  It's possible this
could be simplified now.


r~

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-09 23:26 ` Richard Henderson
@ 2015-02-10  1:07   ` Kenneth Zadeck
  0 siblings, 0 replies; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-10  1:07 UTC (permalink / raw)
  To: Richard Henderson, gcc-patches, Joseph Myers

On 02/09/2015 06:26 PM, Richard Henderson wrote:
> On 02/09/2015 11:10 AM, Kenneth Zadeck wrote:
>> +@table @code
>> +@findex ltgt
>> +@cindex less than or greater than
>> +@item (ltgt:@var{m} @var{x} @var{y})
>> +@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
>> +@var{y} are less, or greater, otherwise 0.  This is a quiet operation
>> +that applies only to floating point operands and does not have a
>> +corresponding IEC 60559 operation.
> This is intended to match c99 7.12.14.5 islessgreater, which I believe is the
> compareQuietNotEqual operation.
I think that the description that I have is correct.   According to IEEE 
754-2008, table 5.1, page 29,  compareQuietNotEqual is defined to have 
the true relations of LT GT UN.    What appears to be described in c99 
7.12.14.5 is a quiet version with relations LT GT and so returns false 
if either operand is a nan.   This does not have a defined name in IEEE 
754-2008, but if it did would have the name compareQuietLessGreater 
according to their naming conventions.

>
>> +@table @code
>> +@findex uneq
>> +@cindex unordered or equal
>> +@item (uneq:@var{m} @var{x} @var{y})
>> +@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
>> +@var{y} are unordered or equal, otherwise 0.  This is a quiet
>> +operation that applies only to floating point operands and does not
>> +have a corresponding IEC 60559 operation.
> This is the strict inverse to LTGT, i.e. !compareQuietNotEqual, and you of
> course note this is not the same as compareQuietEqual.
>
> I believe that when the c99 math.h comparison builtins were added, treating
> EQ+NE as quiet comparisons was common but not universal.  It's possible this
> could be simplified now.
I agree that this is the strict inverse of LTGT, but as the name of this 
implies, if either operand is a nan, this returns true.   As such, the 
relations are UN and EQ which matches the name.
>
> r~

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-09 23:25 ` Joseph Myers
@ 2015-02-10  1:16   ` Kenneth Zadeck
  2015-02-10 21:46     ` Joseph Myers
  2015-02-10 21:54   ` Eric Botcazou
  1 sibling, 1 reply; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-10  1:16 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches

On 02/09/2015 06:24 PM, Joseph Myers wrote:
> On Mon, 9 Feb 2015, Kenneth Zadeck wrote:
>
>>   @findex ge
>>   @cindex greater than
>> @@ -2603,6 +2618,10 @@ Like @code{gt} and @code{gtu} but test f
>>   @item (ge:@var{m} @var{x} @var{y})
>>   @itemx (geu:@var{m} @var{x} @var{y})
>>   Like @code{gt} and @code{gtu} but test for ``greater than or equal''.
>> +If the operands are floating point, @code{ge} is a signaling
>> +comparison and corresponds to the IEC 60559
>> +@code{compareSignalingGreater} operation.  @code{geu} is undefined for
>> +floating point numbers.
> No, compareSignalingGreaterEqual.

oops
>
>>   @findex le
>>   @cindex less than or equal
>> @@ -2610,7 +2629,64 @@ Like @code{gt} and @code{gtu} but test f
>>   @cindex unsigned less than
>>   @item (le:@var{m} @var{x} @var{y})
>>   @itemx (leu:@var{m} @var{x} @var{y})
>> -Like @code{gt} and @code{gtu} but test for ``less than or equal''.
>> +Like @code{gt} and @code{gtu} but test for ``less than or equal''.  If
>> +the operands are floating point, @code{le} is a signaling comparison
>> +and corresponds to the IEC 60559 @code{compareSignalingLess}
>> +operation.  @code{leu} is undefined for floating point numbers.
> compareSignalingLessEqual.
oops again
>> +@table @code
>> +@findex ltgt
>> +@cindex less than or greater than
>> +@item (ltgt:@var{m} @var{x} @var{y})
>> +@code{STORE_FLAG_VALUE} if the values represented by @var{x} and
>> +@var{y} are less, or greater, otherwise 0.  This is a quiet operation
>> +that applies only to floating point operands and does not have a
>> +corresponding IEC 60559 operation.
> On GENERIC, the documentation describes some ambiguity: "With the possible
> exception of @code{LTGT_EXPR}, all of these operations are guaranteed
> not to generate a floating point exception.".
>
> LTGT (RTL code) was added by RTH in
> <https://gcc.gnu.org/ml/gcc-patches/2000-01/msg00974.html>.  LTGT_EXPR was
> added in the thread starting at
> <https://gcc.gnu.org/ml/gcc-patches/2004-05/msg01674.html>, wherein RTH
> stated "the LTGT rtl code is assumed to trap".  The documentation was soon
> thereafter changed to have the "possible exception" wording (r82467, which
> I can't find any sign of having been posted to gcc-patches so don't know
> the rationale).
>
> I don't think it's useful to have the trapping semantics unspecified for a
> comparison operation like that.  So the question is what's most useful for
> LTGT and LTGT_EXPR to do (presumably they should do the same thing).  Lots
> of existing code in this area seems confused (for example, HONOR_SNANS
> should be irrelevant to reversing an equality comparison, as reversing it
> will change neither results nor exceptions raised, whether or not
> signaling NaNs are involved).  But maybe more code treats LTGT as a
> signaling operation than otherwise, in accordance with the original
> intent, and so that's the most appropriate way to document it (with !UNEQ
> being the representation of the corresponding quiet operation).
section 7.12.14.4 in C99 seems pretty much to say that this is a quiet 
operation.

> The islessgreater macro determines whether its first argument is less 
> than or
> greater than its second argument. The islessgreater(x, y) macro is 
> similar to
> (x) < (y) || (x) > (y); howev er, islessgreater(x, y) does not raise
> the ‘‘invalid’’ floating-point exception when x and y are unordered 
> (nor does it evaluate x
> and y twice).
So i think that it seems that we should be pretty safe saying it is quiet.


> It's not clear to me that ad hoc logic around particular operations is the
> best way of handling optimizations in this area, instead of generic logic
> using four bits to track which conditions (< = > unordered) a comparison
> is true for and one bit to track whether it raises an exception for
> unordered operands.  Even if you keep using particular sets of tree / RTL
> codes for a subset of operations, maybe transformations that map into and
> out of such five-bit form would be more likely to be correct.

I will work on the tree version tomorrow and resubmit.

Kenny

>

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-10  1:16   ` Kenneth Zadeck
@ 2015-02-10 21:46     ` Joseph Myers
  2015-02-11 15:22       ` Kenneth Zadeck
  2015-02-14 20:27       ` Paolo Bonzini
  0 siblings, 2 replies; 19+ messages in thread
From: Joseph Myers @ 2015-02-10 21:46 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: gcc-patches

On Mon, 9 Feb 2015, Kenneth Zadeck wrote:

> > I don't think it's useful to have the trapping semantics unspecified for a
> > comparison operation like that.  So the question is what's most useful for
> > LTGT and LTGT_EXPR to do (presumably they should do the same thing).  Lots
> > of existing code in this area seems confused (for example, HONOR_SNANS
> > should be irrelevant to reversing an equality comparison, as reversing it
> > will change neither results nor exceptions raised, whether or not
> > signaling NaNs are involved).  But maybe more code treats LTGT as a
> > signaling operation than otherwise, in accordance with the original
> > intent, and so that's the most appropriate way to document it (with !UNEQ
> > being the representation of the corresponding quiet operation).
> section 7.12.14.4 in C99 seems pretty much to say that this is a quiet
> operation.

It says islessgreater is quiet.  It says nothing about the LTGT RTL 
operation or the LTGT_EXPR GIMPLE/GENERIC operation.  
__builtin_islessgreater is implemented using UNEQ_EXPR not LTGT_EXPR.

It may make sense to define LTGT as exactly !UNEQ, and so quiet, but the 
choice of definition is a matter of what's convenient for the 
implementation (and which choice you make determines which existing code 
in GCC should be considered incorrect).

Where back ends implement ltgt patterns, I don't know if they are 
consistently quiet or signaling.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-09 23:25 ` Joseph Myers
  2015-02-10  1:16   ` Kenneth Zadeck
@ 2015-02-10 21:54   ` Eric Botcazou
  1 sibling, 0 replies; 19+ messages in thread
From: Eric Botcazou @ 2015-02-10 21:54 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches, Kenneth Zadeck

> But maybe more code treats LTGT as a signaling operation than otherwise, in
> accordance with the original intent, and so that's the most appropriate way
> to document it (with !UNEQ being the representation of the corresponding
> quiet operation).

SPARC supports all codes and treats everything but LT/LE/GT/GE as quiet.

-- 
Eric Botcazou

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-10 21:46     ` Joseph Myers
@ 2015-02-11 15:22       ` Kenneth Zadeck
  2015-02-14 20:27       ` Paolo Bonzini
  1 sibling, 0 replies; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-11 15:22 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches

I vote for quiet.    For three reasons:
1) it matches the expectation of what programmers expect.     I view 
people who do floating point as falling into two categories:
     a) people who wish that there were no such thing as nans. These 
people are happy to write programs with just < > <= >= == != and then be 
unhappily surprised if their code blows up.
     b) careful floating pt programmers.  These people never want a 
signal, they properly choose their operators to with knowledge of how 
each of those operations work with respect to nans.
These people will never use anything like a signaling <>
2) it matches iso n1778 which is primarily written to satisfy the needs 
to (b).
3) Whenever you leave something like this undefined, you are basically 
saying "do not optimize"

On 02/10/2015 04:46 PM, Joseph Myers wrote:
> On Mon, 9 Feb 2015, Kenneth Zadeck wrote:
>
>>> I don't think it's useful to have the trapping semantics unspecified for a
>>> comparison operation like that.  So the question is what's most useful for
>>> LTGT and LTGT_EXPR to do (presumably they should do the same thing).  Lots
>>> of existing code in this area seems confused (for example, HONOR_SNANS
>>> should be irrelevant to reversing an equality comparison, as reversing it
>>> will change neither results nor exceptions raised, whether or not
>>> signaling NaNs are involved).  But maybe more code treats LTGT as a
>>> signaling operation than otherwise, in accordance with the original
>>> intent, and so that's the most appropriate way to document it (with !UNEQ
>>> being the representation of the corresponding quiet operation).
>> section 7.12.14.4 in C99 seems pretty much to say that this is a quiet
>> operation.
> It says islessgreater is quiet.  It says nothing about the LTGT RTL
> operation or the LTGT_EXPR GIMPLE/GENERIC operation.
> __builtin_islessgreater is implemented using UNEQ_EXPR not LTGT_EXPR.
>
> It may make sense to define LTGT as exactly !UNEQ, and so quiet, but the
> choice of definition is a matter of what's convenient for the
> implementation (and which choice you make determines which existing code
> in GCC should be considered incorrect).
>
> Where back ends implement ltgt patterns, I don't know if they are
> consistently quiet or signaling.
>

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-10 21:46     ` Joseph Myers
  2015-02-11 15:22       ` Kenneth Zadeck
@ 2015-02-14 20:27       ` Paolo Bonzini
  2015-02-15 16:08         ` Kenneth Zadeck
  1 sibling, 1 reply; 19+ messages in thread
From: Paolo Bonzini @ 2015-02-14 20:27 UTC (permalink / raw)
  To: Joseph Myers, Kenneth Zadeck; +Cc: gcc-patches



On 10/02/2015 22:46, Joseph Myers wrote:
> It may make sense to define LTGT as exactly !UNEQ, and so quiet, but the 
> choice of definition is a matter of what's convenient for the 
> implementation (and which choice you make determines which existing code 
> in GCC should be considered incorrect).

It would be different from e.g. !UNLT and GE differing only in that UNLT
is quiet and GE is signaling.  So it makes sense to me to keep LTGT as
signaling.

Paolo

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-14 20:27       ` Paolo Bonzini
@ 2015-02-15 16:08         ` Kenneth Zadeck
  2015-02-17 10:07           ` Richard Earnshaw
  0 siblings, 1 reply; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-15 16:08 UTC (permalink / raw)
  To: Paolo Bonzini, Joseph Myers; +Cc: gcc-patches


On 02/14/2015 03:26 PM, Paolo Bonzini wrote:
>
> On 10/02/2015 22:46, Joseph Myers wrote:
>> It may make sense to define LTGT as exactly !UNEQ, and so quiet, but the
>> choice of definition is a matter of what's convenient for the
>> implementation (and which choice you make determines which existing code
>> in GCC should be considered incorrect).
> It would be different from e.g. !UNLT and GE differing only in that UNLT
> is quiet and GE is signaling.  So it makes sense to me to keep LTGT as
> signaling.
while in theory, your argument is correct, in practice, this is not how 
people use this stuff and so i disagree.

The interrupts are there to allow legacy code that does not know about 
nans to be "run"
in a mode where the nans can be used to signal that things did not run 
well.   Properly written floating point aware code never uses the 
interrupts.    In that code, you want a rich set of comparisons which 
allow the programmer to efficiently deal with the fact that any 
comparison can go one of 4 possible ways.

to support legacy code we need ne and eq to be quiet and lt gt le ge to 
be noisy.   This is what the standards call for and this is what gcc 
delivers.    Going beyond that for legacy code is a waste of time.

kenny
> Paolo

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-15 16:08         ` Kenneth Zadeck
@ 2015-02-17 10:07           ` Richard Earnshaw
  2015-02-17 12:05             ` Joseph Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Richard Earnshaw @ 2015-02-17 10:07 UTC (permalink / raw)
  To: Kenneth Zadeck, Paolo Bonzini, Joseph Myers; +Cc: gcc-patches

On 15/02/15 16:08, Kenneth Zadeck wrote:
> 
> On 02/14/2015 03:26 PM, Paolo Bonzini wrote:
>>
>> On 10/02/2015 22:46, Joseph Myers wrote:
>>> It may make sense to define LTGT as exactly !UNEQ, and so quiet, but the
>>> choice of definition is a matter of what's convenient for the
>>> implementation (and which choice you make determines which existing code
>>> in GCC should be considered incorrect).
>> It would be different from e.g. !UNLT and GE differing only in that UNLT
>> is quiet and GE is signaling.  So it makes sense to me to keep LTGT as
>> signaling.
> while in theory, your argument is correct, in practice, this is not how
> people use this stuff and so i disagree.
> 
> The interrupts are there to allow legacy code that does not know about
> nans to be "run"
> in a mode where the nans can be used to signal that things did not run
> well.   Properly written floating point aware code never uses the
> interrupts.    In that code, you want a rich set of comparisons which
> allow the programmer to efficiently deal with the fact that any
> comparison can go one of 4 possible ways.
> 
> to support legacy code we need ne and eq to be quiet and lt gt le ge to
> be noisy.   This is what the standards call for and this is what gcc
> delivers.    Going beyond that for legacy code is a waste of time.
> 

So the problem we have today is the compiler has no way to distinguish
between, say, < and __builtin_isless.  According to Annex F (c99) the
former should be signalling while the latter quiet.

I suspect there are two ways we could deal with that: add new comparison
RTL codes to distinguish the cases; or use something like the RTL /v bit
on a comparison to indicate that it should be signalling.

Of the two, the latter would probably be easiest to implement in a
backwards compatible manner (backends not understanding /v would
continue to use their existing code paths), but it would still take a
fair amount of rejigging in the mid end to fully preserve the signalling
nature of comparisons: there are many places where just RTX_CODE is
available and a new pattern is generated from that.  The first method
would require all back-ends to be updated pretty much simultaneously to
handle the new RTL codes.

> kenny

R.
>> Paolo
> 

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-17 10:07           ` Richard Earnshaw
@ 2015-02-17 12:05             ` Joseph Myers
  2015-02-18  0:17               ` Kenneth Zadeck
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph Myers @ 2015-02-17 12:05 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: Kenneth Zadeck, Paolo Bonzini, gcc-patches

On Tue, 17 Feb 2015, Richard Earnshaw wrote:

> So the problem we have today is the compiler has no way to distinguish
> between, say, < and __builtin_isless.  According to Annex F (c99) the
> former should be signalling while the latter quiet.

We do have a way: < is LT and __builtin_isless is !UNGE.

__builtin_islessgreater is !UNEQ.  The question is whether it's also LTGT 
or whether LTGT means LT || GT.  And the existing documentation of 
LTGT_EXPR leaves this unspecified, which seems clearly unhelpful.  Either 
way, you have existing code in GCC that's incorrect (i.e. that does not 
correspond to the set of transformations that are actually valid for the 
chosen semantics).

> I suspect there are two ways we could deal with that: add new comparison
> RTL codes to distinguish the cases; or use something like the RTL /v bit
> on a comparison to indicate that it should be signalling.
> 
> Of the two, the latter would probably be easiest to implement in a
> backwards compatible manner (backends not understanding /v would
> continue to use their existing code paths), but it would still take a
> fair amount of rejigging in the mid end to fully preserve the signalling
> nature of comparisons: there are many places where just RTX_CODE is
> available and a new pattern is generated from that.  The first method
> would require all back-ends to be updated pretty much simultaneously to
> handle the new RTL codes.

I don't know the optimal way of representing these variants in GENERIC, 
GIMPLE and RTL (the existing representation can cover everything, and is 
unambiguous apart from LTGT, but may not be optimal).

I think the main difficulty in proper Annex F support would be making 
optimizers (on each IR) understand the side-effects operations have in 
terms of raising exceptions, and how operations may take the rounding mode 
or existing exceptions raised as inputs - with an associated issue of 
defining the existing default floating-point rules well enough to keep a 
default mode that doesn't unduly inhibit optimization.

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-17 12:05             ` Joseph Myers
@ 2015-02-18  0:17               ` Kenneth Zadeck
  2015-02-18  1:01                 ` Joseph Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-18  0:17 UTC (permalink / raw)
  To: Joseph Myers, Richard Earnshaw; +Cc: Paolo Bonzini, gcc-patches


On 02/17/2015 07:05 AM, Joseph Myers wrote:
> On Tue, 17 Feb 2015, Richard Earnshaw wrote:
>
>> So the problem we have today is the compiler has no way to distinguish
>> between, say, < and __builtin_isless.  According to Annex F (c99) the
>> former should be signalling while the latter quiet.
> We do have a way: < is LT and __builtin_isless is !UNGE.
>
> __builtin_islessgreater is !UNEQ.  The question is whether it's also LTGT
> or whether LTGT means LT || GT.  And the existing documentation of
> LTGT_EXPR leaves this unspecified, which seems clearly unhelpful.  Either
> way, you have existing code in GCC that's incorrect (i.e. that does not
> correspond to the set of transformations that are actually valid for the
> chosen semantics).
>
Having spent the majority of my gcc life at the rtl level, i find it 
astonishing that the designers of the tree level allowed this machine 
dependency to get into what i was always told was a pristine machine 
independent pass.    i would have thought that the at the tree level 
this could/should be nailed down to being quiet and if someone wanted to 
support a noisy version in their port, then they would look for lt || gt 
when converting to the rtl level which has never been so pristine.

it would be nice to know exactly how many ports (if any) actually have a 
noisy version of this in hardware. ltgt is not a common primitive (it is 
not even mentioned in the ieee fp standards).


>> I suspect there are two ways we could deal with that: add new comparison
>> RTL codes to distinguish the cases; or use something like the RTL /v bit
>> on a comparison to indicate that it should be signalling.
>>
>> Of the two, the latter would probably be easiest to implement in a
>> backwards compatible manner (backends not understanding /v would
>> continue to use their existing code paths), but it would still take a
>> fair amount of rejigging in the mid end to fully preserve the signalling
>> nature of comparisons: there are many places where just RTX_CODE is
>> available and a new pattern is generated from that.  The first method
>> would require all back-ends to be updated pretty much simultaneously to
>> handle the new RTL codes.
> I don't know the optimal way of representing these variants in GENERIC,
> GIMPLE and RTL (the existing representation can cover everything, and is
> unambiguous apart from LTGT, but may not be optimal).
>
> I think the main difficulty in proper Annex F support would be making
> optimizers (on each IR) understand the side-effects operations have in
> terms of raising exceptions, and how operations may take the rounding mode
> or existing exceptions raised as inputs - with an associated issue of
> defining the existing default floating-point rules well enough to keep a
> default mode that doesn't unduly inhibit optimization.
i have been thinking a lot about the rounding modes.    the only way 
that could think about properly supporting them was to actually add new 
rtl and tree operations that take the rounding mode as an extra 
parameter.    i think that this is going to be the only way to support 
both the static and dynamic models.   This will be ugly, but having just 
finished the wide int patch it is natural to say "how bad could it 
be?"   some ports will want to support this and some will not.

kenny
>

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-18  0:17               ` Kenneth Zadeck
@ 2015-02-18  1:01                 ` Joseph Myers
  2015-02-18  4:44                   ` Kenneth Zadeck
  2015-02-18  8:38                   ` Andreas Schwab
  0 siblings, 2 replies; 19+ messages in thread
From: Joseph Myers @ 2015-02-18  1:01 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: Richard Earnshaw, Paolo Bonzini, gcc-patches

On Tue, 17 Feb 2015, Kenneth Zadeck wrote:

> On 02/17/2015 07:05 AM, Joseph Myers wrote:
> > On Tue, 17 Feb 2015, Richard Earnshaw wrote:
> > 
> > > So the problem we have today is the compiler has no way to distinguish
> > > between, say, < and __builtin_isless.  According to Annex F (c99) the
> > > former should be signalling while the latter quiet.
> > We do have a way: < is LT and __builtin_isless is !UNGE.
> > 
> > __builtin_islessgreater is !UNEQ.  The question is whether it's also LTGT
> > or whether LTGT means LT || GT.  And the existing documentation of
> > LTGT_EXPR leaves this unspecified, which seems clearly unhelpful.  Either
> > way, you have existing code in GCC that's incorrect (i.e. that does not
> > correspond to the set of transformations that are actually valid for the
> > chosen semantics).
> > 
> Having spent the majority of my gcc life at the rtl level, i find it
> astonishing that the designers of the tree level allowed this machine
> dependency to get into what i was always told was a pristine machine
> independent pass.    i would have thought that the at the tree level this
> could/should be nailed down to being quiet and if someone wanted to support a
> noisy version in their port, then they would look for lt || gt when converting
> to the rtl level which has never been so pristine.

As I said in <https://gcc.gnu.org/ml/gcc-patches/2015-02/msg00583.html>, I 
can't find any posting to gcc-patches of the r82467 commit that introduced 
the "possible exception" wording.

> it would be nice to know exactly how many ports (if any) actually have a noisy
> version of this in hardware. ltgt is not a common primitive (it is not even
> mentioned in the ieee fp standards).

For example, on MIPS the C.cond.fmt instruction has a four-bit condition 
field: "In the cond field of the instruction: cond 2..1 specify the nature 
of the comparison (equals, less than, and so on); cond 0 specifies whether 
the comparison is ordered or unordered, i.e. false or true if any operand 
is a NaN; cond 3 indicates whether the instruction should signal an 
exception on QNaN inputs, or not".  Together with possibly negating the 
result you get all 32 possible comparisons (choice of whether the 
comparison is true or false for each of = < > unordered, choice of whether 
to raise invalid for quiet NaNs).

> > I think the main difficulty in proper Annex F support would be making
> > optimizers (on each IR) understand the side-effects operations have in
> > terms of raising exceptions, and how operations may take the rounding mode
> > or existing exceptions raised as inputs - with an associated issue of
> > defining the existing default floating-point rules well enough to keep a
> > default mode that doesn't unduly inhibit optimization.
> i have been thinking a lot about the rounding modes.    the only way that
> could think about properly supporting them was to actually add new rtl and
> tree operations that take the rounding mode as an extra parameter.    i think
> that this is going to be the only way to support both the static and dynamic
> models.   This will be ugly, but having just finished the wide int patch it is
> natural to say "how bad could it be?"   some ports will want to support this
> and some will not.

My starting point is to presume that any port with hardware floating-point 
exceptions and rounding modes should support this.  But since ports would 
probably need to change anyway to ensure operations do raise the right 
exceptions, and to ensure that the machine-independent compiler can tell 
which registers referred to in inline asm are part of the floating-point 
exceptions / rounding modes state, maybe it wouldn't be so bad if they 
also need to change their instruction descriptions to describe the 
involvement of exceptions and rounding modes explicitly.  (You do need to 
handle the case of exceptions and rounding modes with software floating 
point, i.e. libcalls implicitly using them; this applies to powerpc-linux 
soft float at least.)

Of course many target architecture ports are for architectures without 
hardware floating point, and without any exception or rounding mode 
support, and these issues don't arise for them.

(When I say above certain things are the main difficulty I mean they are 
the only things with real design issues that I see.  Lots of other issues 
arise such as:

(a) writing thorough testcases for individual operations working properly 
with exceptions and rounding modes in various contexts (I could probably 
do that at least for basic arithmetic in a week or two; properly it should 
be done for every IEEE operation for which GCC allows a built-in function 
to be expanded inline);

(b) going through transformations to review whether they are correct for 
exceptions and rounding modes (a good starting point would be all 
references to e.g. HONOR_SIGN_DEPENDENT_ROUNDING, HONOR_NANS and 
flag_trapping_math, many of which are likely not checking quite the right 
condition, although transformations with no such checks are harder to 
find);

(c) avoiding spurious exceptions from libgcc functions e.g. converting 
floating-point to DImode;

(d) ensuring the right exceptions from converting floating-point to 
bit-fields;

(e) converting the standard pragmas to appropriate IR describing what 
transformations are permitted on what code;

(f) if you do Annex G as well, the ABI for _Imaginary argument passing.

When you get into static rounding modes, as described in TS 18661-1, there 
are a few more issues; e.g.:

(g) supporting both architectures that can encode rounding modes in 
instructions, and those where the rounding mode needs swapping at runtime;

(h) allowing library headers to define macros for standard library 
functions that cause them to use the constant rounding mode;

(i) ensuring that <float.h> macros have the correct value in all constant 
rounding modes, which is easy if they use hex floats, but if you allow the 
combination of C90 mode with constant rounding modes then you need long 
decimal expansions of those macros, so maybe that combination should be 
disallowed.

Those are examples of miscellaneous issues that I generally expect could 
be addressed by lots of incremental patches without tricky overall design 
issues.  More would probably come up in a full analysis / design process 
of how to do a high-quality implementation of C99/C11 Annex F/G and TS 
18661-1.)

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-18  1:01                 ` Joseph Myers
@ 2015-02-18  4:44                   ` Kenneth Zadeck
  2015-02-18 10:23                     ` Joseph Myers
  2015-02-18  8:38                   ` Andreas Schwab
  1 sibling, 1 reply; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-18  4:44 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Richard Earnshaw, Paolo Bonzini, gcc-patches





> On Feb 17, 2015, at 6:01 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> 
>> On Tue, 17 Feb 2015, Kenneth Zadeck wrote:
>> 
>>> On 02/17/2015 07:05 AM, Joseph Myers wrote:
>>>> On Tue, 17 Feb 2015, Richard Earnshaw wrote:
>>>> 
>>>> So the problem we have today is the compiler has no way to distinguish
>>>> between, say, < and __builtin_isless.  According to Annex F (c99) the
>>>> former should be signalling while the latter quiet.
>>> We do have a way: < is LT and __builtin_isless is !UNGE.
>>> 
>>> __builtin_islessgreater is !UNEQ.  The question is whether it's also LTGT
>>> or whether LTGT means LT || GT.  And the existing documentation of
>>> LTGT_EXPR leaves this unspecified, which seems clearly unhelpful.  Either
>>> way, you have existing code in GCC that's incorrect (i.e. that does not
>>> correspond to the set of transformations that are actually valid for the
>>> chosen semantics).
>> Having spent the majority of my gcc life at the rtl level, i find it
>> astonishing that the designers of the tree level allowed this machine
>> dependency to get into what i was always told was a pristine machine
>> independent pass.    i would have thought that the at the tree level this
>> could/should be nailed down to being quiet and if someone wanted to support a
>> noisy version in their port, then they would look for lt || gt when converting
>> to the rtl level which has never been so pristine.
> 
> As I said in <https://gcc.gnu.org/ml/gcc-patches/2015-02/msg00583.html>, I 
> can't find any posting to gcc-patches of the r82467 commit that introduced 
> the "possible exception" wording.
> 
>> it would be nice to know exactly how many ports (if any) actually have a noisy
>> version of this in hardware. ltgt is not a common primitive (it is not even
>> mentioned in the ieee fp standards).
> 
> For example, on MIPS the C.cond.fmt instruction has a four-bit condition 
> field: "In the cond field of the instruction: cond 2..1 specify the nature 
> of the comparison (equals, less than, and so on); cond 0 specifies whether 
> the comparison is ordered or unordered, i.e. false or true if any operand 
> is a NaN; cond 3 indicates whether the instruction should signal an 
> exception on QNaN inputs, or not".  Together with possibly negating the 
> result you get all 32 possible comparisons (choice of whether the 
> comparison is true or false for each of = < > unordered, choice of whether 
> to raise invalid for quiet NaNs).
> 
This is a pretty weak motivation.    Computer architects love this kind of thing, assuming they have the opcode space.   Just give them every possible combination and let the programmers decide what is useful -  and by doing that, the architect saves a couple of muxes and gate delays.    But that doesn't mean that the layers of software need to support all of this,   Especially  , in this case when there is not motivation from either the fp standards or the language standards.
>>> I think the main difficulty in proper Annex F support would be making
>>> optimizers (on each IR) understand the side-effects operations have in
>>> terms of raising exceptions, and how operations may take the rounding mode
>>> or existing exceptions raised as inputs - with an associated issue of
>>> defining the existing default floating-point rules well enough to keep a
>>> default mode that doesn't unduly inhibit optimization.
>> i have been thinking a lot about the rounding modes.    the only way that
>> could think about properly supporting them was to actually add new rtl and
>> tree operations that take the rounding mode as an extra parameter.    i think
>> that this is going to be the only way to support both the static and dynamic
>> models.   This will be ugly, but having just finished the wide int patch it is
>> natural to say "how bad could it be?"   some ports will want to support this
>> and some will not.
> 
> My starting point is to presume that any port with hardware floating-point 
> exceptions and rounding modes should support this.  But since ports would 
> probably need to change anyway to ensure operations do raise the right 
> exceptions, and to ensure that the machine-independent compiler can tell 
> which registers referred to in inline asm are part of the floating-point 
> exceptions / rounding modes state, maybe it wouldn't be so bad if they 
> also need to change their instruction descriptions to describe the 
> involvement of exceptions and rounding modes explicitly.  (You do need to 
> handle the case of exceptions and rounding modes with software floating 
> point, i.e. libcalls implicitly using them; this applies to powerpc-linux 
> soft float at least.)
> 
> Of course many target architecture ports are for architectures without 
> hardware floating point, and without any exception or rounding mode 
> support, and these issues don't arise for them.
> 
> (When I say above certain things are the main difficulty I mean they are 
> the only things with real design issues that I see.  Lots of other issues 
> arise such as:
> 
> (a) writing thorough testcases for individual operations working properly 
> with exceptions and rounding modes in various contexts (I could probably 
> do that at least for basic arithmetic in a week or two; properly it should 
> be done for every IEEE operation for which GCC allows a built-in function 
> to be expanded inline);
> 
> (b) going through transformations to review whether they are correct for 
> exceptions and rounding modes (a good starting point would be all 
> references to e.g. HONOR_SIGN_DEPENDENT_ROUNDING, HONOR_NANS and 
> flag_trapping_math, many of which are likely not checking quite the right 
> condition, although transformations with no such checks are harder to 
> find);
> 
> (c) avoiding spurious exceptions from libgcc functions e.g. converting 
> floating-point to DImode;
> 
> (d) ensuring the right exceptions from converting floating-point to 
> bit-fields;
> 
> (e) converting the standard pragmas to appropriate IR describing what 
> transformations are permitted on what code;
> 
> (f) if you do Annex G as well, the ABI for _Imaginary argument passing.
> 
> When you get into static rounding modes, as described in TS 18661-1, there 
> are a few more issues; e.g.:
> 
> (g) supporting both architectures that can encode rounding modes in 
> instructions, and those where the rounding mode needs swapping at runtime;
> 
> (h) allowing library headers to define macros for standard library 
> functions that cause them to use the constant rounding mode;
> 
> (i) ensuring that <float.h> macros have the correct value in all constant 
> rounding modes, which is easy if they use hex floats, but if you allow the 
> combination of C90 mode with constant rounding modes then you need long 
> decimal expansions of those macros, so maybe that combination should be 
> disallowed.
> 
> Those are examples of miscellaneous issues that I generally expect could 
> be addressed by lots of incremental patches without tricky overall design 
> issues.  More would probably come up in a full analysis / design process 
> of how to do a high-quality implementation of C99/C11 Annex F/G and TS 
> 18661-1.)
> 
The fp exceptions raise some very tricky issues with respect to gcc and optimization.     On many machines, noisy does not mean to throw an exception, it means that you set a bit and then check later.    If you try to model this kind of behavior in gcc, you end up pinning the code so that   nothing can be moved or reordered.   

to get this right gcc needs something like a monotonic dependency which would allow reordering     
and gcc has nothing like this.  essentially, you need way to say that all of these insns modify the same variable, but they all just move the value in the same direction so you do not care what order the operations are performed in.   that does not mean that this could not be added but gcc has nothing like this.

however, even on the machines where you throw an exception, most people will at least like an option where the exception can be out of order.    

going back to the rounding modes issue, there is a huge range in the architectural implementation space.  you have a few that are pure dynamic, a few that are pure static and some in the middle that are just a mess.   a lot of machines would have liked to support fully static, but could not fit the bits to specify the rounding modes into the instruction.   my point here is you do need to at least have a plan that will support the full space even if you do this with a 1000 small patches.
> -- 
> Joseph S. Myers
> joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-18  1:01                 ` Joseph Myers
  2015-02-18  4:44                   ` Kenneth Zadeck
@ 2015-02-18  8:38                   ` Andreas Schwab
  1 sibling, 0 replies; 19+ messages in thread
From: Andreas Schwab @ 2015-02-18  8:38 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Kenneth Zadeck, Richard Earnshaw, Paolo Bonzini, gcc-patches

Joseph Myers <joseph@codesourcery.com> writes:

> For example, on MIPS the C.cond.fmt instruction has a four-bit condition 
> field: "In the cond field of the instruction: cond 2..1 specify the nature 
> of the comparison (equals, less than, and so on); cond 0 specifies whether 
> the comparison is ordered or unordered, i.e. false or true if any operand 
> is a NaN; cond 3 indicates whether the instruction should signal an 
> exception on QNaN inputs, or not".  Together with possibly negating the 
> result you get all 32 possible comparisons (choice of whether the 
> comparison is true or false for each of = < > unordered, choice of whether 
> to raise invalid for quiet NaNs).

The m68k fpu has the same feature.

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-18  4:44                   ` Kenneth Zadeck
@ 2015-02-18 10:23                     ` Joseph Myers
  2015-02-18 14:59                       ` Kenneth Zadeck
  0 siblings, 1 reply; 19+ messages in thread
From: Joseph Myers @ 2015-02-18 10:23 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: Richard Earnshaw, Paolo Bonzini, gcc-patches

On Tue, 17 Feb 2015, Kenneth Zadeck wrote:

> The fp exceptions raise some very tricky issues with respect to gcc and 
> optimization.  On many machines, noisy does not mean to throw an 
> exception, it means that you set a bit and then check later.  If you try 
> to model this kind of behavior in gcc, you end up pinning the code so 
> that nothing can be moved or reordered.

When I say exception here, I'm always referring to that flag bit setting, 
not to processor-level exceptions.  In IEEE 754 terms, an exception is 
*signaled*, and the default exception handling is to *raise* a flag and 
deliver a default result (except for exact underflow which doesn't raise 
the flag).

To quote Annex F, "This specification does not require support for trap 
handlers that maintain information about the order or count of 
floating-point exceptions. Therefore, between function calls, 
floating-point exceptions need not be precise: the actual order and number 
of occurrences of floating-point exceptions (> 1) may vary from what the 
source code expresses.".  So it is not necessary to be concerned about 
configurations where trap handlers may be called.

There is as yet no public draft of TS 18661-5 (Supplementary attributes).  
That will provide C bindings for alternate exception handling as described 
in IEEE 754-2008 clause 8.  I suspect such bindings will not readily be 
efficiently implementable using processor-level exception handlers; SIGFPE 
is an awkward interface for implementing such things at the C language 
level, some processors do not support such trap handlers at all (e.g. many 
ARM processors), and where traps are supported they may be asynchronous 
rather than occurring immediately on execution of the relevant 
instruction.  In addition, at least x86 does not support raising exception 
flags without running trap handlers on the next floating-point instruction 
(raiseFlags operation, fesetexcept in TS 18661-1); that is, if trap 
handlers were used to implement standard functionality, it would need to 
be in a way such that this x86 peculiarity is not visible.

> to get this right gcc needs something like a monotonic dependency which 
> would allow reordering and gcc has nothing like this.  essentially, you 
> need way to say that all of these insns modify the same variable, but 
> they all just move the value in the same direction so you do not care 
> what order the operations are performed in.  that does not mean that 
> this could not be added but gcc has nothing like this.

Indeed, this is one of the things about defining the default mode that I 
referred to; the present default is -ftrapping-math, but we may wish to 
distinguish between strict trapping-math (whenever exception flags might 
be tested / raised / lowered, exactly the computations specified by the 
abstract machine have occurred, which might mean rather more limits on 
code movement in the absence of monotonic dependencies) and loose trapping 
math (like the present default; maybe don't transform expressions locally 
in ways that add or remove exceptions, but don't treat an expression as 
having side effects or reading global state purely because of possible 
raising of floating-point exceptions).

> going back to the rounding modes issue, there is a huge range in the 
> architectural implementation space.  you have a few that are pure 
> dynamic, a few that are pure static and some in the middle that are just 
> a mess.  a lot of machines would have liked to support fully static, but 
> could not fit the bits to specify the rounding modes into the 
> instruction.  my point here is you do need to at least have a plan that 
> will support the full space even if you do this with a 1000 small 
> patches.

I think the norm is dynamic, because that's what was in IEEE 754-1985, 
with static rounding added more recently on some processors, because of 
IEEE 754-2008.  (There are other variants - IA64 having multiple dynamic 
rounding mode registers and allowing instructions to specify which one the 
rounding mode is taken from.)

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-18 10:23                     ` Joseph Myers
@ 2015-02-18 14:59                       ` Kenneth Zadeck
  2015-02-18 15:23                         ` Joseph Myers
  0 siblings, 1 reply; 19+ messages in thread
From: Kenneth Zadeck @ 2015-02-18 14:59 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Richard Earnshaw, Paolo Bonzini, gcc-patches





> On Feb 18, 2015, at 3:23 AM, Joseph Myers <joseph@codesourcery.com> wrote:
> 
>> On Tue, 17 Feb 2015, Kenneth Zadeck wrote:
>> 
>> The fp exceptions raise some very tricky issues with respect to gcc and 
>> optimization.  On many machines, noisy does not mean to throw an 
>> exception, it means that you set a bit and then check later.  If you try 
>> to model this kind of behavior in gcc, you end up pinning the code so 
>> that nothing can be moved or reordered.
> 
> When I say exception here, I'm always referring to that flag bit setting, 
> not to processor-level exceptions.  In IEEE 754 terms, an exception is 
> *signaled*, and the default exception handling is to *raise* a flag and 
> deliver a default result (except for exact underflow which doesn't raise 
> the flag).
> 
> To quote Annex F, "This specification does not require support for trap 
> handlers that maintain information about the order or count of 
> floating-point exceptions. Therefore, between function calls, 
> floating-point exceptions need not be precise: the actual order and number 
> of occurrences of floating-point exceptions (> 1) may vary from what the 
> source code expresses.".  So it is not necessary to be concerned about 
> configurations where trap handlers may be called.
> 
> There is as yet no public draft of TS 18661-5 (Supplementary attributes).  
> That will provide C bindings for alternate exception handling as described 
> in IEEE 754-2008 clause 8.  I suspect such bindings will not readily be 
> efficiently implementable using processor-level exception handlers; SIGFPE 
> is an awkward interface for implementing such things at the C language 
> level, some processors do not support such trap handlers at all (e.g. many 
> ARM processors), and where traps are supported they may be asynchronous 
> rather than occurring immediately on execution of the relevant 
> instruction.  In addition, at least x86 does not support raising exception 
> flags without running trap handlers on the next floating-point instruction 
> (raiseFlags operation, fesetexcept in TS 18661-1); that is, if trap 
> handlers were used to implement standard functionality, it would need to 
> be in a way such that this x86 peculiarity is not visible.
my point here is that what you want to be able to do is freely reorder the fp operations ( within the rules of reordering fp operations) between places were those bits are explicitly read or cleared.   were have no way to model that chain of modify operations in gcc.
> 
>> to get this right gcc needs something like a monotonic dependency which 
>> would allow reordering and gcc has nothing like this.  essentially, you 
>> need way to say that all of these insns modify the same variable, but 
>> they all just move the value in the same direction so you do not care 
>> what order the operations are performed in.  that does not mean that 
>> this could not be added but gcc has nothing like this.
> 
> Indeed, this is one of the things about defining the default mode that I 
> referred to; the present default is -ftrapping-math, but we may wish to 
> distinguish between strict trapping-math (whenever exception flags might 
> be tested / raised / lowered, exactly the computations specified by the 
> abstract machine have occurred, which might mean rather more limits on 
> code movement in the absence of monotonic dependencies) and loose trapping 
> math (like the present default; maybe don't transform expressions locally 
> in ways that add or remove exceptions, but don't treat an expression as 
> having side effects or reading global state purely because of possible 
> raising of floating-point exceptions).
> 
>> going back to the rounding modes issue, there is a huge range in the 
>> architectural implementation space.  you have a few that are pure 
>> dynamic, a few that are pure static and some in the middle that are just 
>> a mess.  a lot of machines would have liked to support fully static, but 
>> could not fit the bits to specify the rounding modes into the 
>> instruction.  my point here is you do need to at least have a plan that 
>> will support the full space even if you do this with a 1000 small 
>> patches.
> 
> I think the norm is dynamic, because that's what was in IEEE 754-1985, 
> with static rounding added more recently on some processors, because of 
> IEEE 754-2008.  (There are other variants - IA64 having multiple dynamic 
> rounding mode registers and allowing instructions to specify which one the 
> rounding mode is taken from.)
the first ieee standard only allowed the dynamic model.   the second allows the static model.   while dynamic is more common, there are/were architectures that are fully static.   i believe that the first sparks were fully static and this was why the standard changed. ( i could be completely wrong on which arch was the first fully static).  the private port that i am working on is currently fully static, but i am trying to change that.   code generation of a dynamic program on a fully static machine is gruesome. 

my point here is that there are fully static machines so do not do anything that precludes this.

also remember that constant prop on the rounding mode can be a win.   without knowing the rounding mode precisely, you cannot really do constant prop on the data.  also the constant prop on the rounding mode can let you avoid a lot of code which sets that register.   this can be important if the machine requires a cycle or two to settle that setting before the next fp operation.
> 
> -- 
> Joseph S. Myers
> joseph@codesourcery.com

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

* Re: patch to fix rtl documentation for new floating point comparisons
  2015-02-18 14:59                       ` Kenneth Zadeck
@ 2015-02-18 15:23                         ` Joseph Myers
  0 siblings, 0 replies; 19+ messages in thread
From: Joseph Myers @ 2015-02-18 15:23 UTC (permalink / raw)
  To: Kenneth Zadeck; +Cc: Richard Earnshaw, Paolo Bonzini, gcc-patches

On Wed, 18 Feb 2015, Kenneth Zadeck wrote:

> > I think the norm is dynamic, because that's what was in IEEE 754-1985, 
> > with static rounding added more recently on some processors, because of 
> > IEEE 754-2008.  (There are other variants - IA64 having multiple dynamic 
> > rounding mode registers and allowing instructions to specify which one the 
> > rounding mode is taken from.)
> the first ieee standard only allowed the dynamic model.  the second 
> allows the static model.  while dynamic is more common, there are/were 
> architectures that are fully static.  i believe that the first sparks 
> were fully static and this was why the standard changed. ( i could be 
> completely wrong on which arch was the first fully static).  the private 
> port that i am working on is currently fully static, but i am trying to 
> change that.  code generation of a dynamic program on a fully static 
> machine is gruesome.
> 
> my point here is that there are fully static machines so do not do 
> anything that precludes this.

The C99 standard was hardly designed for such systems, given the 
expectation that you can set the rounding mode with fesetround and then 
have it affect library functions (those that are fully-defined operations 
such as sqrt and fma, that is).  It's not that you can't implement it on 
such a system (by having the functions contain a switch over the 
thread-local variable with the rounding mode, for example, and doing the 
same in all user code that enables FENV_ACCESS and might possibly run in 
non-default rounding modes), but it's not exactly convenient.

Essentially that would involve the reverse of what TS 18661-1 envisages 
when it gives an example of a code sequence with __swapround to implement 
constant rounding directions on a machine where the rounding mode is 
dynamic only.

(To implement the FENV_ROUND pragma, one might have the front end insert 
__builtin_feswapround calls - in which case machines with static rounding 
modes would need to reverse that to identify the rounding modes for 
particular operations - or one might have it tag the operations and a 
later lowering stage insert such calls.  That's in addition to affecting 
constants and appropriately marked function calls.)

-- 
Joseph S. Myers
joseph@codesourcery.com

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

end of thread, other threads:[~2015-02-18 15:23 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-09 19:11 patch to fix rtl documentation for new floating point comparisons Kenneth Zadeck
2015-02-09 23:25 ` Joseph Myers
2015-02-10  1:16   ` Kenneth Zadeck
2015-02-10 21:46     ` Joseph Myers
2015-02-11 15:22       ` Kenneth Zadeck
2015-02-14 20:27       ` Paolo Bonzini
2015-02-15 16:08         ` Kenneth Zadeck
2015-02-17 10:07           ` Richard Earnshaw
2015-02-17 12:05             ` Joseph Myers
2015-02-18  0:17               ` Kenneth Zadeck
2015-02-18  1:01                 ` Joseph Myers
2015-02-18  4:44                   ` Kenneth Zadeck
2015-02-18 10:23                     ` Joseph Myers
2015-02-18 14:59                       ` Kenneth Zadeck
2015-02-18 15:23                         ` Joseph Myers
2015-02-18  8:38                   ` Andreas Schwab
2015-02-10 21:54   ` Eric Botcazou
2015-02-09 23:26 ` Richard Henderson
2015-02-10  1:07   ` Kenneth Zadeck

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 read-only IMAP folder(s) and NNTP newsgroup(s).