Latest working kernel version: none Earliest failing kernel version: tested on 2.6.18, but should not work anywhere Distribution: Debian Hardware Environment: alphaev56, alphaev68 Software Environment: mathemu=y Problem Description: conversion from denormal float to double is wrong Steps to reproduce: Compile with -O0 -mieee or -O2 -mieee: #include <stdio.h> float x = 1.0; double y; int g(float z) { printf ("%g\n", z); } int main() { x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 65536.0f); x *= (1.0f / 32.0f); g(x); y = x; g(y); } Correct value should be: 1.4013e-45 1.4013e-45 Actual value is: 2.65249e-315 2.65249e-315 or 2.65249e-315 0 The right value is 2-149, that is 1.4013e-45, but the alpha does not do it. The architecture handbook says "A trap handler can convert an S_ floating denormal value into the corresponding T_ floating finite value by adding 896 to the exponent and normalizing", but here 896 is not added (math-emu should, at least on older alphas where it is relevant) and I get a denormal double, 2.65249e-315. Actually both compiled programs are correct. You get a zero if the denormal is casted back to float (which makes a zero, because it is way off the range of a float); you get 2.65249e-315 if the compiler performs some copy propagation and sees through the conversion (because if it was not for the errata, the two values should indeed have been equal). The bug reproduces both on alphaev56 and on alphaev68 (where math-emu should not be relevant, or so I'm told), both with CONFIG_MATHEMU=y.
Where I wrote 2-149, it's 2^-149. Damn mail client...
Created attachment 14469 [details] fix conversion from denormal float to double Good catch, thanks Paolo. Here is a fix.
Are you sure you don't have to check that the number *is* a denormal? Especially for older hardware where more math instructions trap to the emulation.
Yes, I am. cvtst/s would never trap with finite values. And for NaNs and Infs the patched conversion works correctly.
Thanks!
The fix is in main line, I suppose the bug can be closed. Thanks.