D.gnu - Floating point constant folding bug?
- Johannes Pfau (12/12) Mar 15 2013 writefln("%f\n%f", cast(float)cast(int)float.infinity, float.infinity);
- Iain Buclaw (5/17) Mar 15 2013 GCC bug, try the same in C and see if it produces the same result.
- Johannes Pfau (19/19) Mar 15 2013 Forget what I've said, I somehow read that code as a bitwise/reinterpret
- Iain Buclaw (12/31) Mar 15 2013 I think the behaviour from DMD is more incidental than intended. They u...
- Johannes Pfau (7/48) Mar 15 2013 I think in this case GCC might intentionally use saturating overflows.
- Iain Buclaw (6/54) Mar 15 2013 It tests an incidental feature of dmd-generated code that got turned int...
writefln("%f\n%f", cast(float)cast(int)float.infinity, float.infinity); writes --- 2147483648.000000 inf --- -fdump-tree-original --- writefln ({.length=5, .ptr="%f\n%f"}, 2.147483647e+9, Inf); --- The same conversion at runtime produces the expected result. Is this a gdc or gcc bug or is this expected?
Mar 15 2013
On 15 March 2013 15:15, Johannes Pfau <nospam example.com> wrote:writefln("%f\n%f", cast(float)cast(int)float.infinity, float.infinity); writes --- 2147483648.000000 inf --- -fdump-tree-original --- writefln ({.length=5, .ptr="%f\n%f"}, 2.147483647e+9, Inf); --- The same conversion at runtime produces the expected result. Is this a gdc or gcc bug or is this expected?GCC bug, try the same in C and see if it produces the same result. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Mar 15 2013
Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)
Mar 15 2013
On 15 March 2013 18:35, Johannes Pfau <nospam example.com> wrote:Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)I think the behaviour from DMD is more incidental than intended. They use C's FLOAT_INFINITY, etc, macros. But because of the way it's written, gcc doesn't optimise the use of the value. Whereas with gdc, because it uses gcc's real_t types, values of extreme numbers may change to be either 2147483647 or -2147483648 depending on whether -O is used. As I said, in most cases you can see the same behaviour in C. I can see if there might be some flag I can set to try and make gcc's codegen more safe for floats, but that might have impact on runtime. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Mar 15 2013
Am Fri, 15 Mar 2013 20:20:14 +0000 schrieb Iain Buclaw <ibuclaw ubuntu.com>:On 15 March 2013 18:35, Johannes Pfau <nospam example.com> wrote:I think in this case GCC might intentionally use saturating overflows. I just found this message: http://gcc.gnu.org/ml/gcc-patches/2003-09/msg02090.html (This doesn't explain though what the test (constfold.d:test2) in the dmd testsuite is actually supposed to test...)Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)I think the behaviour from DMD is more incidental than intended. They use C's FLOAT_INFINITY, etc, macros. But because of the way it's written, gcc doesn't optimise the use of the value. Whereas with gdc, because it uses gcc's real_t types, values of extreme numbers may change to be either 2147483647 or -2147483648 depending on whether -O is used. As I said, in most cases you can see the same behaviour in C. I can see if there might be some flag I can set to try and make gcc's codegen more safe for floats, but that might have impact on runtime.
Mar 15 2013
On 15 March 2013 22:00, Johannes Pfau <nospam example.com> wrote:Am Fri, 15 Mar 2013 20:20:14 +0000 schrieb Iain Buclaw <ibuclaw ubuntu.com>:It tests an incidental feature of dmd-generated code that got turned into a test case. Rather than something defined in the spec. -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';On 15 March 2013 18:35, Johannes Pfau <nospam example.com> wrote:I think in this case GCC might intentionally use saturating overflows. I just found this message: http://gcc.gnu.org/ml/gcc-patches/2003-09/msg02090.html (This doesn't explain though what the test (constfold.d:test2) in the dmd testsuite is actually supposed to test...)Forget what I've said, I somehow read that code as a bitwise/reinterpret cast but of course the code does an integer/float conversion so it's probably OK. This is more interesting: --- float f = float.infinity; float f2 = float.max; int i = cast(int) f; int i2 = cast(int) f2; writefln("0x%x == int.min(0x%x)", i, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.infinity, int.max); writefln("0x%x == int.min(0x%x)", i2, int.min); writefln("0x%x == int.max(0x%x)", cast(int)float.max, int.max); --- const folding expands to int.max, but the same code at runtime expands to int.min. C does not define what happens if too large float values are cast into ints. Do you know if D somehow defines this? (There's a failing test in the test suite which assumes that the result is int.min in all cases above)I think the behaviour from DMD is more incidental than intended. They use C's FLOAT_INFINITY, etc, macros. But because of the way it's written, gcc doesn't optimise the use of the value. Whereas with gdc, because it uses gcc's real_t types, values of extreme numbers may change to be either 2147483647 or -2147483648 depending on whether -O is used. As I said, in most cases you can see the same behaviour in C. I can see if there might be some flag I can set to try and make gcc's codegen more safe for floats, but that might have impact on runtime.
Mar 15 2013