* 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).