Hi, Steve! On Oct 27, Steve Ellcey wrote:
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.
Yes, I agree absolutely. Let's fix the test instead. Was that cast(cast(20010203101112.1 as double) as datetime(1)) the only one that failed?
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.
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.
Because new THD is created or initialized in all these places. The pattern is { THD *thd; thd= new THD; thd->thread_stack= (char*) &thd; ... // do some work delete new_thd; } Regards, Sergei