I have a question relating to variadic builtins and floating point arguments. I'm trying to implement "isnormal" like so: http://gcc.gnu.org/ml/gcc-patches/2007-06/msg01292.html
Basically, I change __builtin_isnormal(x) -> isgreaterequal(fabs(x),FP_MIN) & islessequal(fabs(x),FP_MAX) (where FP_MIN/FP_MAX are the respective min and max values that the type of 'x' could contain. And fabs may be fabsl/fabsf as necessary.) The builtin has a variadic prototype to faciliate accepting any FP type as an argument. The problem arises when isnormal is passed a float parameter, which according to C promotion rules is cast to double. Inside the middle-end, the builtin sees the type as double. I don't believe you can tell the difference between a promoted float and a user-cast float. Normally, this is merely a performance penalty as the float is widened unecessarily and the comparisons, etc are done in the wider mode. However if isnormal is passed a subnormal float, e.g. FLT_MAX/2, if it's widened to a double, then the number suddenly becomes "normal" again because of the wider range of double types. Now we return incorrect results because isgreaterequal(FLT_MIN/2,DBL_MIN) returns true. My original patch above actually checks that FLT_MIN/2 is correctly identified in the testcase. So I spent a lot of time scratching my head why it was aborting in another file I was working on. Long story short, the testcase in the patch above uses -funsafe-math-optimizations. This doesn't change the resulting assembler code output. However on sparc it activates crtfastmath.c. That in turn changes the FP behavior for sparc to truncate all subnormal numbers to zero. Presto, testcase passes because FLT_MIN/2 becomes zero before being cast to double and therefore maintains that it is not "normal". So how do we detect or work around this promotion issue and discriminate between the case where a float is promoted because of the variadic prototype vs a user supplied cast or other user code? Thanks, --Kaveh -- Kaveh R. Ghazi [EMAIL PROTECTED]