Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
Hi,

Fortran 2018 introduced intrinsic functions for all the IEEE-754 comparison 
operations, compareQuiet* and compareSignaling*  I want to introduce those into 
the Fortran front-end, and make them emit the right code. But cannot find the 
correspondance between IEEE-754 nomenclature and GCC internal representation.

I understand that the middle-end representation was mostly created with C in 
mind, so I assume that the correspondance is that used by the C standard. That 
helps me to some extent, as I can find draft documents that seem to list the 
following table (page 8 of 
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1615.pdf):

compareQuietEqual ==
compareQuietNotEqual !=
compareSignalingEqual iseqsig
compareSignalingGreater >
compareSignalingGreaterEqual >=
compareSignalingLess <
compareSignalingLessEqual <=
compareSignalingNotEqual !iseqsig
compareSignalingNotGreater !(x>y)
compareSignalingLessUnordered !(x=>y)
compareSignalingNotLess !(xhttps://gcc.gnu.org/bugzilla/show_bug.cgi?id=77928). Is there a fundamental 
problem with creating one, and could someone help there?


Thanks,
FX

Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Jakub Jelinek via Gcc
On Thu, Sep 01, 2022 at 10:04:58AM +0200, FX wrote:
> Fortran 2018 introduced intrinsic functions for all the IEEE-754 comparison 
> operations, compareQuiet* and compareSignaling*  I want to introduce those 
> into the Fortran front-end, and make them emit the right code. But cannot 
> find the correspondance between IEEE-754 nomenclature and GCC internal 
> representation.
> 
> I understand that the middle-end representation was mostly created with C in 
> mind, so I assume that the correspondance is that used by the C standard. 
> That helps me to some extent, as I can find draft documents that seem to list 
> the following table (page 8 of 
> https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1615.pdf):
> 
> compareQuietEqual ==
> compareQuietNotEqual !=
> compareSignalingEqual iseqsig
> compareSignalingGreater >
> compareSignalingGreaterEqual >=
> compareSignalingLess <
> compareSignalingLessEqual <=
> compareSignalingNotEqual !iseqsig
> compareSignalingNotGreater !(x>y)
> compareSignalingLessUnordered !(x=>y)
> compareSignalingNotLess !(x compareSignalingGreaterUnorder !(x<=y)
> compareQuietGreater isgreater
> compareQuietGreaterEqual isgreaterequal
> compareQuietLess isless
> compareQuietLessEqual islessequal
> compareQuietUnordered isunordered
> compareQuietNotGreater !isgreater
> compareQuietLessUnordered !isgreaterequal
> compareQuietNotLess !isless
> compareQuietGreaterUnordered !islessequal
> compareQuietOrdered !isunordered
> 
> 
> I have two questions:
> 
> 1. Is this list normative, and was it modified later (I have only found a 
> 2012 draft)?
> 
> 2.  All the functions are available as GCC type-generic built-ins (yeah!),
> except there is no __builtin_ iseqsig
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77928).  Is there a
> fundamental problem with creating one, and could someone help there?

IMHO until that one is implemented you can just use
tx = x, ty = y, tx>=ty && tx<=ty
(in GENERIC just SAVE_EXPR >= SAVE_EXPR && SAVE_EXPR <= SAVE_EXPR
PowerPC backend is still broken, not just for that but for most other cases
above, it doesn't violate just Fortran requirements, but C too.

Jakub



Re: Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
Hi Jakub,

>> 2.  All the functions are available as GCC type-generic built-ins (yeah!),
>> except there is no __builtin_ iseqsig
>> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77928).  Is there a
>> fundamental problem with creating one, and could someone help there?
> 
> IMHO until that one is implemented you can just use
> tx = x, ty = y, tx>=ty && tx<=ty
> (in GENERIC just SAVE_EXPR >= SAVE_EXPR && SAVE_EXPR <= SAVE_EXPR

If it’s just that (optimization aside), I probably can create a C built-in. It 
would need to be:

1. defined in builtins.def
2. lowered in builtins.cc
3. type-checked in c-family/c-common.cc
4. documented in doc/extend.texi
5. tested in fp-test.cc
6. covered in the testsuite

Is that right?

Thanks,
FX


PS: I see that reclassify is not covered in fp-test.cc, is that file obsolete?

Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Jakub Jelinek via Gcc
On Thu, Sep 01, 2022 at 11:04:03AM +0200, FX wrote:
> Hi Jakub,
> 
> >> 2.  All the functions are available as GCC type-generic built-ins (yeah!),
> >> except there is no __builtin_ iseqsig
> >> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77928).  Is there a
> >> fundamental problem with creating one, and could someone help there?
> > 
> > IMHO until that one is implemented you can just use
> > tx = x, ty = y, tx>=ty && tx<=ty
> > (in GENERIC just SAVE_EXPR >= SAVE_EXPR && SAVE_EXPR <= 
> > SAVE_EXPR
> 
> If it’s just that (optimization aside), I probably can create a C built-in. 
> It would need to be:
> 
> 1. defined in builtins.def
> 2. lowered in builtins.cc
> 3. type-checked in c-family/c-common.cc
> 4. documented in doc/extend.texi
> 5. tested in fp-test.cc
> 6. covered in the testsuite
> 
> Is that right?

Dunno if we really need a builtin for this, especially if it is lowered
to that x >= y && x <= y early, will defer to Joseph.

Because if it is for better code generation only, IMNSHO we want to optimize
even when users write it that way by hand and so want to pattern recognize
that during instruction selection before expansion (isel pass) or during
expansion if target can do that.
E.g. x86 with AVX can do that:

where the 4 booleans are A>B, A= y && x <= y can be handled using vcmpeq_ossd or similar instructions.

Jakub



Re: Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
Hi,

> Dunno if we really need a builtin for this, especially if it is lowered
> to that x >= y && x <= y early, will defer to Joseph.

I think it’d be nice to have one for consistency, as the other standard 
floating-point functions are there. It would also make things slightly easier 
for our Fortran implementation, although admittedly we can do without.

A tentative patch is attached, it seems to work well on simple examples, but 
for test coverage the hard part is going to be that the comparisons seem to be 
optimised away very easily into their non-signaling versions. Basically, if I 
do:

  float x = __builtin_nanf("");
  printf("%d\n", __builtin_iseqsig(__builtin_nanf(""), __builtin_inff()));
  printf("%d\n", __builtin_iseqsig(x, __builtin_inff()));

With -O0 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans: first 
one does not raise invalid, second one does.
With -O2 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans: no 
invalid raised at all.

FX



iseqsig.diff
Description: Binary data


[wwwdocs] Re: unreachable intro to gcc page linked to on readings page

2022-09-01 Thread Jonathan Wakely via Gcc
On Mon, 29 Aug 2022 at 11:31, Gerald Pfeifer wrote:
>
> On Wed, 24 Aug 2022, Jonathan Wakely wrote:
> >> a broken link points to
> >>
> >>   An introduction to GCC by Brian J. Gough.
> >>   . http://www.network-theory.co.uk/gcc/intro/
> > There are much more recent archived copies like
> > https://web.archive.org/web/20181113021321/http://www.network-theory.co.uk/gcc/intro/
> > I'm not sure it's worth updating the link to an archived copy of that
> > page, because all the links for buying a PDF or printed copy are
> > probably dead now anyway.
> >
> > We could link to https://archive.org/details/B-001-002-835 instead, or
> > to the archived HTML version. The newest capture of the HTML version
> > seems to be this, although I didn't check that all pages are archived:
> > https://web.archive.org/web/20181206025406/http://www.network-theory.co.uk/docs/gccintro/
> > My preference would be to link to that latter. Although it's quite
> > dated, the sections on basic compilation and compiler flags are still
> > relevant for beginners.
> >
> > Gerald?
>
> I searched around a bit myself (since indeed the original and printed
> versions seem to be gone) and landed at
>
>https://archive.org/details/B-001-002-835
>
> as well. I probably would have gone for that, though the
> web.archive.org/web link you found works equally if you want to point
> there instead.

Why not both?  I've pushed the attached patch to [wwwdocs].
commit 0e4c9a39789b6dbcd44b2e0d4a42b5885d3bddb2
Author: Jonathan Wakely 
Date:   Thu Sep 1 10:57:46 2022 +0100

Replace stale link to the "An Introduction to GCC" book

diff --git a/htdocs/readings.html b/htdocs/readings.html
index 4269e9f0..5d1b78e8 100644
--- a/htdocs/readings.html
+++ b/htdocs/readings.html
@@ -22,8 +22,9 @@
 
 
 
-  http://www.network-theory.co.uk/gcc/intro/";>An Introduction
-  to GCC by Brian J. Gough.
+  https://web.archive.org/web/20060106062936/http://www.network-theory.co.uk/gcc/intro/";>An
 Introduction
+  to GCC by Brian J. Gough
+  (https://archive.org/details/B-001-002-835/";>e-book).
 
   https://en.wikibooks.org/wiki/GNU_C_Compiler_Internals";>GNU C 
Compiler Internals (Wikibook), numerous contributors.
 


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Segher Boessenkool
On Thu, Sep 01, 2022 at 10:19:59AM +0200, Jakub Jelinek via Gcc wrote:
> On Thu, Sep 01, 2022 at 10:04:58AM +0200, FX wrote:
> > 2.  All the functions are available as GCC type-generic built-ins (yeah!),
> > except there is no __builtin_ iseqsig
> > (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77928).  Is there a
> > fundamental problem with creating one, and could someone help there?
> 
> IMHO until that one is implemented you can just use
> tx = x, ty = y, tx>=ty && tx<=ty
> (in GENERIC just SAVE_EXPR >= SAVE_EXPR && SAVE_EXPR <= SAVE_EXPR
> PowerPC backend is still broken, not just for that but for most other cases
> above, it doesn't violate just Fortran requirements, but C too.

See my talk at the GCC cauldron 2019 (Montréal) for what needs to be
done in the generic handling for us to be able to fix what the rs6000
backend does here.


Segher


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Joseph Myers
On Thu, 1 Sep 2022, FX via Gcc wrote:

> 1. Is this list normative, and was it modified later (I have only found 
> a 2012 draft)?

See N3047 Annex F for the current bindings (there have been a lot of 
changes to the C2x working draft after N3047 in the course of editorial 
review, but I don't think any of them affect the IEEE bindings for 
comparisons).

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Joseph Myers
On Thu, 1 Sep 2022, FX via Gcc wrote:

> A tentative patch is attached, it seems to work well on simple examples, 
> but for test coverage the hard part is going to be that the comparisons 
> seem to be optimised away very easily into their non-signaling versions. 
> Basically, if I do:

Presumably that can be reproduced without depending on the new built-in 
function?  In which case it's an existing bug somewhere in the optimizers.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Marc Glisse via Gcc

On Thu, 1 Sep 2022, Joseph Myers wrote:


On Thu, 1 Sep 2022, FX via Gcc wrote:


A tentative patch is attached, it seems to work well on simple examples,
but for test coverage the hard part is going to be that the comparisons
seem to be optimised away very easily into their non-signaling versions.
Basically, if I do:


Presumably that can be reproduced without depending on the new built-in
function?  In which case it's an existing bug somewhere in the optimizers.


 (simplify
  (cmp @0 REAL_CST@1)
[...]
   (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
&& !tree_expr_signaling_nan_p (@1)
&& !tree_expr_maybe_signaling_nan_p (@0))
{ constant_boolean_node (cmp == NE_EXPR, type); })

only tries to preserve a comparison with sNaN, but not with qNaN. There 
are probably other issues since various gcc devs used to have a different 
opinion on the meaning of -ftrapping-math.



--
Marc Glisse


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Joseph Myers
On Thu, 1 Sep 2022, Marc Glisse via Gcc wrote:

> On Thu, 1 Sep 2022, Joseph Myers wrote:
> 
> > On Thu, 1 Sep 2022, FX via Gcc wrote:
> > 
> > > A tentative patch is attached, it seems to work well on simple examples,
> > > but for test coverage the hard part is going to be that the comparisons
> > > seem to be optimised away very easily into their non-signaling versions.
> > > Basically, if I do:
> > 
> > Presumably that can be reproduced without depending on the new built-in
> > function?  In which case it's an existing bug somewhere in the optimizers.
> 
>  (simplify
>   (cmp @0 REAL_CST@1)
> [...]
>(if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1))
> && !tree_expr_signaling_nan_p (@1)
> && !tree_expr_maybe_signaling_nan_p (@0))
> { constant_boolean_node (cmp == NE_EXPR, type); })
> 
> only tries to preserve a comparison with sNaN, but not with qNaN. There are

So that needs to take more care about what comparison operations are 
involved.  Since such an optimization is fine for quiet comparisons such 
as ==, != or isless, but not for signaling comparisons such as < <= > >= 
(subject to any question of splitting up -ftrapping-math into more 
fine-grained options allowing different transformations).

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
> Presumably that can be reproduced without depending on the new built-in 
> function?  In which case it's an existing bug somewhere in the optimizers.

Yes:

$ cat a.c
#include 
#include 
#include 

void foo (void) {
  if (fetestexcept (FE_INVALID) & FE_INVALID)
printf("Invalid raised\n");
  feclearexcept (FE_ALL_EXCEPT);
}

static inline int iseqsig(float x, float y) { return (x >= y && x <= y); }

int main (void) {
  float x = __builtin_nanf("");
  float y;

  printf("%d\n", iseqsig(__builtin_nanf(""), 1.));
  foo();

  printf("%d\n", iseqsig(x, __builtin_inff()));
  foo();
}

$ ./bin/gcc a.c -lm -fno-unsafe-math-optimizations -frounding-math 
-fsignaling-nans -O0 && ./a.out
0
Invalid raised
0
Invalid raised

$ ./bin/gcc a.c -lm -fno-unsafe-math-optimizations -frounding-math 
-fsignaling-nans -O1 && ./a.out
0
0


Do you want me to file a bug report?

FX

Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Joseph Myers
On Thu, 1 Sep 2022, FX via Gcc wrote:

> Do you want me to file a bug report?

Yes.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
For the record, this is now PR 106805
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106805

FX


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
Hi Joseph,

I have a Fortran patch ready to submit, but before I do so I’d like to know: do 
you support or oppose a __builtin_iseqsig()?
Jakub said he was against, but deferred to you on that.

For me, it makes the Fortran front-end part slightly simpler, so if it is 
decided to go that route I’ll propose a middle-end + C patch first. But I do 
not need it absolutely.

Thanks,
FX

Re: Floating-point comparisons in the middle-end

2022-09-01 Thread FX via Gcc
> See N3047 Annex F for the current bindings (there have been a lot of 
> changes to the C2x working draft after N3047 in the course of editorial 
> review, but I don't think any of them affect the IEEE bindings for 
> comparisons).

Thanks for the pointer, it is very helpful.

The next thing I need to tackle for Fortran is the implementation of functions 
that perform maxNum, maxNumMag, minNum, and minNumMag.
Am I correct in assuming that maxNum and minNum correspond to fmin and fmax? 
Are there builtins for maxNumMag and minNumMag? Or does anyone know what the 
“canonical” way to perform it is? I do not want to mess up corners cases, which 
is so easy to do…

Thanks again,
FX

Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Joseph Myers
On Thu, 1 Sep 2022, FX via Gcc wrote:

> I have a Fortran patch ready to submit, but before I do so I’d like to 
> know: do you support or oppose a __builtin_iseqsig()?

I support having such a built-in function.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: Floating-point comparisons in the middle-end

2022-09-01 Thread Joseph Myers
On Thu, 1 Sep 2022, FX via Gcc wrote:

> The next thing I need to tackle for Fortran is the implementation of 
> functions that perform maxNum, maxNumMag, minNum, and minNumMag. Am I 
> correct in assuming that maxNum and minNum correspond to fmin and fmax? 

Yes (note that maxNum and minNum were removed in IEEE 754-2019, but 
they're still what fmax and fmin correspond to; the new minimum / maximum 
operations in IEEE 754-2019 are provided by new functions in C2x).

> Are there builtins for maxNumMag and minNumMag? Or does anyone know what 
> the “canonical” way to perform it is? I do not want to mess up corners 
> cases, which is so easy to do…

TS 18661-1 defined functions fmaxmag and fminmag for those; we don't have 
built-in functions for them, and C2x does not include those functions 
given that those operations were also removed in IEEE 754-2019.

-- 
Joseph S. Myers
jos...@codesourcery.com


gcc-10-20220901 is now available

2022-09-01 Thread GCC Administrator via Gcc
Snapshot gcc-10-20220901 is now available on
  https://gcc.gnu.org/pub/gcc/snapshots/10-20220901/
and on various mirrors, see http://gcc.gnu.org/mirrors.html for details.

This snapshot has been generated from the GCC 10 git branch
with the following options: git://gcc.gnu.org/git/gcc.git branch 
releases/gcc-10 revision bd71b8b7b08852c5b4b8cb7189b00199af6017de

You'll find:

 gcc-10-20220901.tar.xz   Complete GCC

  SHA256=4c9bd605c76421baecdde7cb664676b3b73efa2d37ddad843bae81896fd7feb4
  SHA1=4e23c9456772569c8c4fd95194c4316de55e20be

Diffs from 10-20220825 are available in the diffs/ subdirectory.

When a particular snapshot is ready for public consumption the LATEST-10
link is updated and a message is sent to the gcc list.  Please do not use
a snapshot before it has been announced that way.


Re: GIMPLE undefined behavior

2022-09-01 Thread Krister Walfridsson via Gcc

On Thu, 1 Sep 2022, Richard Biener wrote:


It's generally poorly documented what is considered 'undefined behavior'.
We desparately need a section in the internals manual for this.
For the {L,R}SHIFT_EXPR case we assume the shift operand is
in range of [0, precision - 1], so in theory value-range propagation could
infer that b_8(D) < 32 after it "executed".  But it seems that
range-on-exit doesn't do that yet.

[...]

The problem with shifts is that there's not a "do it anway, but without
undefined behavior" operation to substitute.


I read this as I should not report these as bugs for now. But I'll 
probably keep this as UB in my tool to get an idea of how often this 
happens...




Calling f(-3, 0x75181005) makes slsr_9 overflow in the optimized code,
even though the original did not overflow. My understanding is that signed
overflow invokes undefined behavior in GIMPLE, so this is a bug in
ifcombine. Is my understanding correct?


Yes, the above would be a bug - again value-range propagation might be
leveraged to produce a wrong-code testcase.


OK. I'll open bugs for the signed overflow issues the tool finds.



I would appreciate some comments on which non-memory-related operations I
should treat as invoking undefined behavior (memory operations are more
complicated, and I'll be back with more concrete questions later...).


The more "interesting" cases are uninitialized values (registers or memory).


Yes, this is the next thing I was planning to implement. :)



In general what we should worry about most is introducing undefined
behavior that, when a later pass can assume it doesn't happen, causes
wrong code to be generated.  Likewise when we have late instrumentation
that would flag such undefined behavior as a user error.


Agreed. But that comes back to the issue of lacking documentation... :(

   /Krister


Re: GIMPLE undefined behavior

2022-09-01 Thread Richard Biener via Gcc
On Fri, Sep 2, 2022 at 2:03 AM Krister Walfridsson
 wrote:
>
> On Thu, 1 Sep 2022, Richard Biener wrote:
>
> > It's generally poorly documented what is considered 'undefined behavior'.
> > We desparately need a section in the internals manual for this.
> > For the {L,R}SHIFT_EXPR case we assume the shift operand is
> > in range of [0, precision - 1], so in theory value-range propagation could
> > infer that b_8(D) < 32 after it "executed".  But it seems that
> > range-on-exit doesn't do that yet.
> [...]
> > The problem with shifts is that there's not a "do it anway, but without
> > undefined behavior" operation to substitute.
>
> I read this as I should not report these as bugs for now. But I'll
> probably keep this as UB in my tool to get an idea of how often this
> happens...

Can you report a single case as kind-of meta-bug for this particular issue?
That would be nice.

>
> >> Calling f(-3, 0x75181005) makes slsr_9 overflow in the optimized code,
> >> even though the original did not overflow. My understanding is that signed
> >> overflow invokes undefined behavior in GIMPLE, so this is a bug in
> >> ifcombine. Is my understanding correct?
> >
> > Yes, the above would be a bug - again value-range propagation might be
> > leveraged to produce a wrong-code testcase.
>
> OK. I'll open bugs for the signed overflow issues the tool finds.

Thanks.

> >> I would appreciate some comments on which non-memory-related operations I
> >> should treat as invoking undefined behavior (memory operations are more
> >> complicated, and I'll be back with more concrete questions later...).
> >
> > The more "interesting" cases are uninitialized values (registers or memory).
>
> Yes, this is the next thing I was planning to implement. :)
>
>
> > In general what we should worry about most is introducing undefined
> > behavior that, when a later pass can assume it doesn't happen, causes
> > wrong code to be generated.  Likewise when we have late instrumentation
> > that would flag such undefined behavior as a user error.
>
> Agreed. But that comes back to the issue of lacking documentation... :(

Yes.  There's some "unknowns" in what GIMPLE treats as undefined given
the lack of a strict specification but there's also implementation facts for
which cases optimization passes already exploit undefined behavior (but even
that subset is not documented).

Richard.

> /Krister