[Bug c/28795] New: __builtin_isunordered() and __builtin_isnan() should behave consistently

2006-08-21 Thread iano at apple dot com
I expect this is widespread over the entire GCC family, but at least with
Apple's GCC we have a consistency problem with the meaning of various hacky
math flags in GCC and methods to detect NaN's in GCC:

[ollmia:/tmp] iano% cat main3.c
#include 
#include 
#include 

int main( void )
{
union
{
int32_t i;
float   f;
}u = {-1};

printf( "__FINITE_MATH_ONLY__ = %d\n", __FINITE_MATH_ONLY__ );
printf( "__builtin_isunordered(%f,%f) = %d\n", u.f, u.f,
__builtin_isunordered(u.f, u.f) );
printf( "__builtin_isnan(%f) = %d\n", u.f, __builtin_isnan( u.f) );
printf( " (%f != %f) = %d\n", u.f, u.f, u.f != u.f );


return 0;
}
[ollmia:/tmp] iano% gcc main3.c -Wall; ./a.out
__FINITE_MATH_ONLY__ = 0
__builtin_isunordered(nan,nan) = 1
__builtin_isnan(nan) = 1
 (nan != nan) = 1
[ollmia:/tmp] iano% gcc main3.c -Wall -ffinite-math-only; ./a.out
__FINITE_MATH_ONLY__ = 1
__builtin_isunordered(nan,nan) = 1
__builtin_isnan(nan) = 0
 (nan != nan) = 0
[ollmia:/tmp] iano% gcc main3.c -Wall -mno-ieee-fp ; ./a.out
__FINITE_MATH_ONLY__ = 0
__builtin_isunordered(nan,nan) = 1
__builtin_isnan(nan) = 1
 (nan != nan) = 0
[ollmia:/tmp] iano% gcc main3.c -Wall -funsafe-math-optimizations ; ./a.out
__FINITE_MATH_ONLY__ = 0
__builtin_isunordered(nan,nan) = 0
__builtin_isnan(nan) = 0
 (nan != nan) = 0

Here's my plug:  I'm (speaking for) the rare developer who can actually use
these flags responsibly, who has actually verified that NaNs do not occur in my
code. However, to be responsible, I also need to guard my application against
NaNs contained in malicious data sources. So, even though I said that NaNs do
not occur, I still need a way to test for them.  This is very hard to do in a
cross platform way on GCC at the moment.

Most GCC engineers that I've spoken to say that because we've thrown the
standard out the window for speed, GCC should set all these tests to 0.  The
problem is that GCC doesn't seem to have actually done that. What GCC appears
to have done is remove some but not all of them, presumably because it was
convenient for the compiler to do it that way. This doesn't serve the end user.
If there is a philosophy here, either "correct at all costs" or "speed at all
costs", GCC should pick one and stick to it.

Personally, I favor correct at all costs for the __builtins. If the end user
really wants all isnan(x) to return 0 even if x is NaN (which I guarantee you,
he doesn't) he can just define his own test with x != x.  

Since I am personally a math library provider and need my isnan() to work
uniformly all the time, even when the user has a temporary bout with insanity
and turns IEEE-754 conformance off, I favor a __builtin_isnan() that always
works properly. Only then can I pay heed to the GCC advice:

 http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
  "GCC provides built-in versions of the ISO C99 floating point comparison
macros that avoid raising exceptions for unordered operands. They have the same
names as the standard macros ( isgreater, isgreaterequal, isless, islessequal,
islessgreater, and isunordered) , with __builtin_ prefixed. We intend for a
library implementor to be able to simply #define each standard macro to its
built-in equivalent."

...with emphasis on the last sentence.  I can not do this until you are
actually C99 compliant *all the time*.  I have to support well written legacy
applications that expect this macro to work *all the time*.


[ollmia:/tmp] iano% gcc -v
Using built-in specs.
Target: i686-apple-darwin8
Configured with: /private/var/tmp/gcc/gcc-5363.obj~28/src/configure
--disable-checking -enable-werror --prefix=/usr --mandir=/share/man
--enable-languages=c,objc,c++,obj-c++
--program-transform-name=/^[cg][^.-]*$/s/$/-4.0/
--with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib
--build=powerpc-apple-darwin8 --with-arch=nocona --with-tune=generic
--program-prefix= --host=i686-apple-darwin8 --target=i686-apple-darwin8
Thread model: posix
gcc version 4.0.1 (Apple Computer, Inc. build 5363)


-- 
   Summary: __builtin_isunordered() and __builtin_isnan() should
behave consistently
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
     Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: iano at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28795



[Bug target/28795] __builtin_isunordered() and __builtin_isnan() should behave consistently

2006-08-21 Thread iano at apple dot com


--- Comment #4 from iano at apple dot com  2006-08-22 00:14 ---
Pinski, look at the data I presented.

You do not actually return 0 for these cases


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28795



[Bug c/28796] New: __builtin_nan() and __builtin_unordered() inconsistent

2006-08-21 Thread iano at apple dot com
actually C99 compliant *all the time*.  I have to support well written legacy
applications that expect this macro to work *all the time*.


For if you read the docs for -ffinite-math-only, it specificially says finite
fp is only supported which means it is compliant to the C99 standard.

And for the fact -mno-ieee-fp says we don't support IEEE FP for compares which
means no NaNs when doing compares:
-mieee-fp
-mno-ieee-fp
Control whether or not the compiler uses IEEE floating point comparisons.
These handle correctly the case where the result of a comparison is unordered. 

so this is invalid and/or a dup bug.

So closing as invalid.

--- Comment #4 From Ian Ollmann 2006-08-22 00:14 [reply] ---
Pinski, look at the data I presented.

You do not actually return 0 for these cases.


-- 
   Summary: __builtin_nan() and __builtin_unordered() inconsistent
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
      Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: iano at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug target/28795] __builtin_isunordered() and __builtin_isnan() should behave consistently

2006-08-21 Thread iano at apple dot com


--- Comment #6 from iano at apple dot com  2006-08-22 00:18 ---
Subject: Re:  __builtin_isunordered() and __builtin_isnan() should behave
consistently


On Aug 21, 2006, at 5:16 PM, pinskia at gcc dot gnu dot org wrote:

>
>
> --- Comment #5 from pinskia at gcc dot gnu dot org  2006-08-22  
> 00:16 ---
> (In reply to comment #4)
>> Pinski, look at the data I presented.
>>
>> You do not actually return 0 for these cases
>
> Try it on a real processor instead of x86 which does funny stuff in  
> the
> back-end and does not fully support IEEE math without longer compares.

Can I get this reviewed by someone a little less prejudicial, please?

Cloned as 28796.

Ian


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28795



[Bug c/28796] __builtin_nan() and __builtin_unordered() inconsistent

2006-08-21 Thread iano at apple dot com


--- Comment #5 from iano at apple dot com  2006-08-22 00:31 ---
My first complaint is that the implementation is inconsistent.
My second complaint is that the fine manual is wrong headed, leading to hacky
math flags that are less useful than they otherwise would be.


-- 

iano at apple dot com changed:

   What|Removed |Added

 CC||iano at apple dot com
  Component|middle-end  |c


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug middle-end/28796] __builtin_nan() and __builtin_unordered() inconsistent

2006-08-21 Thread iano at apple dot com


--- Comment #7 from iano at apple dot com  2006-08-22 00:39 ---
Subject: Re:  __builtin_nan() and __builtin_unordered() inconsistent


On Aug 21, 2006, at 5:34 PM, pinskia at gcc dot gnu dot org wrote:

>
>
> --- Comment #6 from pinskia at gcc dot gnu dot org  2006-08-22  
> 00:34 ---
> (In reply to comment #5)
>> My first complaint is that the implementation is inconsistent.
>
> It is not inconsistent really.  Just the -funsafe-math- 
> optimizations is done
> incorrectly for x86 (see the other bug which I keep on mentioning  
> over and over
> again).

Which part of:

__builtin_isunordered(nan,nan) = 1
__builtin_isnan(nan) = 0

is consistent?

[ollmia:/tmp] iano% gcc main3.c -Wall -ffinite-math-only; ./a.out


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug middle-end/28796] __builtin_nan() and __builtin_unordered() inconsistent

2006-08-21 Thread iano at apple dot com


--- Comment #9 from iano at apple dot com  2006-08-22 00:49 ---
Subject: Re:  __builtin_nan() and __builtin_unordered() inconsistent


On Aug 21, 2006, at 5:42 PM, pinskia at physics dot uc dot edu wrote:

>
>
> --- Comment #8 from pinskia at physics dot uc dot edu   
> 2006-08-22 00:42 ---
> Subject: Re:  __builtin_nan() and __builtin_unordered() inconsistent
>
>> Which part of:
>>
>> __builtin_isunordered(nan,nan) = 1
>> __builtin_isnan(nan) = 0
>>
>> is consistent?
>
> Did you read what the options do because it seems like you did not  
> and you keep
> on agruing that
> it is inconsistent except for the fact this is way these options  
> are done as it
> just says "allows for
> optimizations" and not always assume finite math and ignore NaNs  
> all the time.

Yes, I did.  All one sentence of it:

-ffinite-math-only
Allow optimizations for floating-point arithmetic that assume
that  
arguments and results are not NaNs or +-Infs.

Do you know what an unordered compare is?

Ian


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug middle-end/28796] __builtin_nan() and __builtin_unordered() inconsistent

2006-08-21 Thread iano at apple dot com


--- Comment #11 from iano at apple dot com  2006-08-22 01:45 ---
About the manual wrongheadedness:

The major argument that I have heard from members of the GCC community (here
and elsewhere) against isnan() in its various forms correctly detecting NaN
when various hacky math flags are turned on, is that the hacky math flags are
defined to preclude the presence of NaNs.  The argument goes that the user
actually asked for the possibility all NaNs to be ignored! 

This is circular reasoning. The fact of the matter is that GCC defines all the
meanings of the flags. You can't claim the user wanted isnan(NaN) to return 0,
because you provided him with no opportunity to say otherwise.  I contend that
given the choice, the user will want isnan(NaN) to correctly  detect NaN's even
if the rest of the application does not, because when one is walking on a tight
rope, it is good to have a safety net in case something goes wrong.  You can't
deal with NaNs in special case code unless you have a way to find them. What
you've given him is a choice between unavoidably wrong results, or "poor
speed".

If you can find a set of flags that would allow the user to do speed enhancing
things like assume that make the assumption that x-x is always 0, while at the
same time have __builtin_isnan(NaN) still work in the same compilation unit --
we want these things to inline for speed! -- then I will be happy to concede
this point. Otherwise, I assert that the overly simple interpretation of these
flags currently in practice does not serve the developer's needs. 


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug middle-end/28796] __builtin_nan() and __builtin_unordered() inconsistent

2006-08-21 Thread iano at apple dot com


--- Comment #12 from iano at apple dot com  2006-08-22 02:05 ---
"That however is not a clear bug. 
-ffinite-math-only says that it assumes that there are no NaNs in the 
input, and you violated that assumption, so the results you will get are 
undefined.  That is, gcc is allowed to give you any answer here.  One 
can argue that the documentation could be improved to indicate this. 
One could perhaps also argue that this feature is poorly designed.  One 
can't argue that this is an obvious bug."

Let's go with your interpretation for a moment here:

If -ffinite-math-only says that it "assumes that there are no NaNs in the
input" , then it should not return a result saying that there are NaNs there. I
don't think the results here are undefined. I think the results are pretty
clear. This is a bug.

But, yes, you are mostly right. I want something very feature-ish.  I would
like you to fix/clarify the design you already have in a direction that works
well for users.   I would like those builtins (or maybe some other hypothetical
future builtins) to function correctly all the time, no matter what.  In that
regard, I think that the fact that __builtin_isunordered() does the right thing
in that particular case is pretty nifty. I just can't depend on it, so it's a
useless behavior.  


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug middle-end/28796] __builtin_nan() and __builtin_unordered() inconsistent

2006-08-22 Thread iano at apple dot com


--- Comment #14 from iano at apple dot com  2006-08-22 18:25 ---

For your amusement:

[ollmia:/tmp] iano% cat main.c
#include 

extern int __isnand( double );

static __inline__ int __inline_isnan( double __a )
{
if( __builtin_isnan( __builtin_nan("") ) )
return __builtin_isnan( __a );

return __isnand( __a);   //this is our isnan() compiled in a separate
compilation unit that always works
}


int main( void )
{
volatile double g = __builtin_nan("");

printf( "isnan(%g) = %d\n", g, __inline_isnan( g ) );

return 0;
}

[ollmia:/tmp] iano% gcc main.c -O0 -g -ffast-math ; ./a.out
isnan(nan) = 0

If you step through in gdb, we see that what the compiler has done here is use
the IEEE compare result to determine that __builtin_isnan( __builtin_nan("") ) 
is always true. It faills through to the next line where, __builtin_isnan()
returns always false.  

For reasons I can't explain, we also see this:

[ollmia:/tmp] iano% cat main.c
#include 

extern int __isnand( double );

static __inline__ int __inline_isnan( double __a )
{
static const double nan = __builtin_nan("");
if( nan != nan )
return __a != __a;

return __isnand( __a);
}


int main( void )
{
volatile double g = __builtin_nan("");

printf( "isnan(%g) = %d\n", g, __inline_isnan( g ) );

return 0;
}

[ollmia:/tmp] iano% gcc main.c -O0 -g -ffast-math ; ./a.out
isnan(nan) = 1
[ollmia:/tmp] iano% gcc main.c -O3 -g -ffast-math ; ./a.out
isnan(nan) = 0
[ollmia:/tmp] iano% gcc main.c -O0 -g -ffinite-math-only ; ./a.out
isnan(nan) = 1
[ollmia:/tmp] iano% gcc main.c -O3 -g -ffinite-math-only ; ./a.out
isnan(nan) = 0


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28796



[Bug driver/28877] New: gcc file1.c file2.c file3.c -o file.o fails

2006-08-28 Thread iano at apple dot com
This doesn't work on my apple gcc. If you inspect with -v, it compiles each
file in turn and writes to file.o, each file overwriting the one before it,
rather than combining the three .c files into one .o.

I can think of some pretty good reasons to do this, including cross
compilation-unit inlining. 

Is/should this be a supported feature?


-- 
   Summary: gcc file1.c file2.c file3.c -o file.o fails
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: driver
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: iano at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28877



[Bug driver/28877] gcc file1.c file2.c file3.c -o file.o fails

2006-08-28 Thread iano at apple dot com


--- Comment #3 from iano at apple dot com  2006-08-28 23:13 ---
Thanks for fixing it Andrew. I can confirm that -combine works. Hopefully Apple
will get around to updating to 4.0.3 one of these days.

...and really, you should be thrilled to get duplicate bug reports! They are
sooo much easier to fix. 


-- 

iano at apple dot com changed:

   What|Removed |Added

 Status|RESOLVED|VERIFIED


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28877



[Bug c/30254] New: Need method to determine if AltiVec PIM is available

2006-12-18 Thread iano at apple dot com
It is possible with most compilers use the __VEC__ symbol to indicate that the
AltiVec C Programming Interface is available. GCC has taken a different track.
It is possible to have __VEC__ defined (-maltivec) without the C Programming
Interface operational (altivec.h has not been included.)  

It is difficult to deal with this problem in places like system headers, where
the current compilation environment is not known. On a vector ISA like SSE this
is not a problem. Such system headers can safely include things like
xmmintrin.h as needed to get the types/interfaces they need. Not so with
AltiVec!  The addition of several new keywords like vector and bool may cause
ordinary C and C++ programs to fail to compile. We need to know if the user has
turned on the PIM so we know if should use the interface in library/system
headers, where we have no control over the compilation environment.

The current situation is a bit tangly because of -faltivec:

 -faltivec:defines __VEC__, defines __APPLE_ALTIVEC__, 
   does not include altivec.h (on Apple compiler at least)
   does not define _AltiVec_H

-maltivec:   defines __VEC__,  may or may not define __APPLE_ALTIVEC__
depending on GCC version
   PIM active status dependent on whether altivec.h is
included. 
   We don't know if the symbol _AltiVec_H

I'm asking for one of several solutions:

1) Attempt to conform to behavior of other compilers -- only define __VEC__ if
the PIM is on.
 I think this would mean that -maltivec does not define __VEC__,
-faltivec does and altivec.h
 defines it too 

2) Provide a new symbol such as __ALTIVEC__PIM__ that we can test against

3) Fix __APPLE_ALTIVEC__ so that is is defined in some predicable manner that
can be used for this purpose.  Perhaps all you need here is a verification test
case. The problem case appears to be the Cell / Linux GNU tool chain, which
defines __APPLE__ALTIVEC__ without -faltivec or include "altivec.h"

Maybe some other way?


-- 
   Summary: Need method to determine if AltiVec PIM is available
   Product: gcc
   Version: 4.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
    ReportedBy: iano at apple dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30254



[Bug target/30254] Need method to determine if AltiVec PIM is available

2006-12-18 Thread iano at apple dot com


--- Comment #4 from iano at apple dot com  2006-12-18 20:24 ---

A gcc test case that verfies behavior in this area would drive conformance by
external vendors like IBM. 

Unfortunately, it is not clear that GCC even has an approved method for
determining if the PIM is active. 


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30254



[Bug target/30254] Need method to determine if AltiVec PIM is available

2006-12-18 Thread iano at apple dot com


--- Comment #5 from iano at apple dot com  2006-12-18 20:52 ---

I will nominate the following as a test case.  It should compile without
errors:

for each affected arch:

gcc test_case.c
gcc test_case.c -maltivec
gcc test_case.c -faltivec
gcc test_case.c -maltivec -DINCLUDE_HEADER

test_case.c:

#include 
#if defined( INCLUDE_HEADER )
   #include 
#endif

/* The approved method for detecting PIM availability on GCC */
#if defined( __VEC__ )
 #if defined( __GNUC__ ) && ! defined __APPLE_ALTIVEC__
#if defined _ALTIVEC_H  /* defined by altivec.h */
 #define __ALTIVEC_PIM__
#endif
 #else
#define __ALTIVEC_PIM__
 #endif  /* __GNUC__ */
#endif /* __VEC__ */


int main( void )
{
#if defined( __ALTIVEC_PIM__ )
vector unsigned char v = (vector unsigned char) (
'A','l','t','i','V','e','c',' ','i','s',' ','o','n', 0, 0, 0 );   
v = vec_or( v, v );
printf( "%vc\n", v );//note, some operating systems don't
support %v format specifiers, which is a separate problem
#else
printf( "AltiVec is off\n" );
#endif

return 0;
}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30254