![](https://secure.gravatar.com/avatar/63e41c26f1b269cef456dc21b8ff4f27.jpg?s=120&d=mm&r=g)
On Thu, 2011-10-27 at 12:12 +0200, Sergei Golubchik wrote:
Two answers: There should be no strtod, because the argument of the cast(... as double) is not a string, but a decimal number. I'd expect the conversion to happen in decimal2double() function. Secondly, I think you're right - it is not.
OK, that is a big help. I looked at decimal2double and that is where the problem occurs. IA64 has an fma (fused multiply and add) instruction and if you use it you can get slightly different results then you would if you did a multiply followed by a separate add instruction because with fma the result of the multiplication is not truncated before you do the addition. If I put '#pragma STDC FP_CONTRACT OFF' before decimal2double (and #pragma STDC FP_CONTRACT ON) afterwards then the function does not use the fma instruction and the main.cast test does not fail. This would only work with the HP compiler though, if someone compiled with GCC on IA64, it would still fail because GCC does not honor the FP_CONTRACT pragma. I am not sure if we want to do this as a permanent fix though, if we fix the test to use a value that is exactly representable as a double (say .5 instead of .1 or something like that) then I would probably not try to add the pragma and/or use an option to turn off fma usage because that would slow the code down. If we need more accurate results then maybe we should consider using gmp like GCC and glibc do, but maybe we are OK with the fact that different systems (or the same system with different compiler optimization flags) may generate different results for values that cannot be represented exactly.
FYI: The other failure I get is main.cast, this test is trying to check for a stack overflow before it happens but IA64 HP-UX has two stacks, a register stack and a user data stack. In this test case the recursion of p_ere and p_ere_exp wind up using only the register stack because all the local variables and arguments are stored in registers. The stack check in check_stack_overrun is checking the user stack which doesn't overflow (or even change) and so we eventually die with a register stack overflow. There is a way to check the register stack on IA64 HP-UX, but it would require using IA64 assembly language so it may not be worth doing.
Okay. What would you suggest? Just disable the test in the test suite? Do not check for stack overflow on IA64 HP-UX at all? Check for both stacks?
I will spend some time seeing how easy/hard it would be to check both stacks. One question I have about the current stack check is in check_stack_overrun there is: if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >= (long) (my_thread_stack_size - margin)) I believe that thd->thread_stack should be pointing at the base of the stack we are checking for overflow, but I see that that variable is set in a lot of places, mostly with: thd->thread_stack = (char*)&thd; Why is thd->thread_stack set in so many different places? If I need to save the base of the IA64 register stack in all those places too, that would be touching a lot of files. Steve Ellcey sje@cup.hp.com