Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 15, 2013 Floating point constant folding bug? | ||||
---|---|---|---|---|
| ||||
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? |
March 15, 2013 Re: Floating point constant folding bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau Attachments:
| 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'; |
March 15, 2013 Re: Floating point constant folding bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | 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) |
March 15, 2013 Re: Floating point constant folding bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau Attachments:
| 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'; |
March 15, 2013 Re: Floating point constant folding bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Iain Buclaw | 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: > > > 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. > > 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...) |
March 15, 2013 Re: Floating point constant folding bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Johannes Pfau Attachments:
| 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>: > > > 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. > > > > > > 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...) > 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'; |
Copyright © 1999-2021 by the D Language Foundation