digitalmars.D - Optimizing with dmd disables floating point exceptions
- Jens Mueller (26/26) Apr 28 2011 Hi,
- Walter Bright (2/27) Apr 28 2011 That's because the a/=1.0L; is a dead assignment and is removed by the o...
- KennyTM~ (18/20) Apr 28 2011 I'd say it's a wrong-code bug.
- Jens Mueller (11/33) Apr 29 2011 I think the compiler performs that floating point division at compile
- KennyTM~ (7/18) Apr 29 2011 [snip]
- Jens Mueller (3/26) Apr 29 2011 Yeah. Looks like a bug to me as well.
Hi, checking whether a floating point exception occurred is good coding practice for me. I discovered a strange behavior using dmd. divByZero.d: import std.math; unittest { auto a = 1.0L; assert(!ieeeFlags.divByZero); a /= 0.0L; assert(ieeeFlags.divByZero); } $ rdmd --main -unittest divByZero.d passes, but $ rdmd -O --main -unittest divByZero.d makes the second assert fail. Similar behavior if I enable floating point exceptions FloatingPointControl fpctrl; fpctrl.enableExceptions(FloatingPointControl.severeExceptions); Without optimization I get a floating point exception. With optimization the code passes even though it shouldn't. In sum neither floating point exceptions nor status flags are working when optimizations are turned on. $ dmd | head -1 Digital Mars D Compiler v2.052 Jens
Apr 28 2011
On 4/28/2011 3:02 PM, Jens Mueller wrote:Hi, checking whether a floating point exception occurred is good coding practice for me. I discovered a strange behavior using dmd. divByZero.d: import std.math; unittest { auto a = 1.0L; assert(!ieeeFlags.divByZero); a /= 0.0L; assert(ieeeFlags.divByZero); } $ rdmd --main -unittest divByZero.d passes, but $ rdmd -O --main -unittest divByZero.d makes the second assert fail. Similar behavior if I enable floating point exceptions FloatingPointControl fpctrl; fpctrl.enableExceptions(FloatingPointControl.severeExceptions); Without optimization I get a floating point exception. With optimization the code passes even though it shouldn't. In sum neither floating point exceptions nor status flags are working when optimizations are turned on. $ dmd | head -1 Digital Mars D Compiler v2.052That's because the a/=1.0L; is a dead assignment and is removed by the optimizer.
Apr 28 2011
On Apr 29, 11 14:27, Walter Bright wrote:That's because the a/=1.0L; is a dead assignment and is removed by the optimizer.I'd say it's a wrong-code bug. ------------------------------------- import std.math, std.stdio; void main() { auto a = 1.0, b = 0.0; writeln(a); writeln(ieeeFlags.divByZero); auto c = a / b; // <-- this is no longer dead right? writeln(c); writeln(ieeeFlags.divByZero); } ------------------------------------- 1 false 9.50035e-306 false -------------------------------------
Apr 28 2011
KennyTM~ wrote:On Apr 29, 11 14:27, Walter Bright wrote:I think the compiler performs that floating point division at compile time. I should look at the assembly. So the floating point exception happens at that point. Shouldn't the compiler tell me this somehow? Ask differently how do I get to know when my compile time function causes floating point exceptions? Interestingly the results are not the same. Shouldn't in both cases assert(a == real.infinity, to!(string)(a)); hold. Without optimization it holds. Why does it not hold with optimizations? JensThat's because the a/=1.0L; is a dead assignment and is removed by the optimizer.I'd say it's a wrong-code bug. ------------------------------------- import std.math, std.stdio; void main() { auto a = 1.0, b = 0.0; writeln(a); writeln(ieeeFlags.divByZero); auto c = a / b; // <-- this is no longer dead right? writeln(c); writeln(ieeeFlags.divByZero); } ------------------------------------- 1 false 9.50035e-306 false -------------------------------------
Apr 29 2011
(It seems the message is lost. Let me try again.) On Apr 29, 11 15:10, Jens Mueller wrote:KennyTM~ wrote:[snip]I think the compiler performs that floating point division at compile time. I should look at the assembly. So the floating point exception happens at that point. Shouldn't the compiler tell me this somehow? Ask differently how do I get to know when my compile time function causes floating point exceptions? Interestingly the results are not the same. Shouldn't in both cases assert(a == real.infinity, to!(string)(a)); hold. Without optimization it holds. Why does it not hold with optimizations? JensThe compiler (optimizer) recognizes you have provided only constants and try to do constant folding. But the backend (evalu8.c) did not treat the divide-by-zero case correctly and yields a garbage value. See bug 5908 (http://d.puremagic.com/issues/show_bug.cgi?id=5908).
Apr 29 2011
KennyTM~ wrote:(It seems the message is lost. Let me try again.) On Apr 29, 11 15:10, Jens Mueller wrote:Yeah. Looks like a bug to me as well. JensKennyTM~ wrote:[snip]I think the compiler performs that floating point division at compile time. I should look at the assembly. So the floating point exception happens at that point. Shouldn't the compiler tell me this somehow? Ask differently how do I get to know when my compile time function causes floating point exceptions? Interestingly the results are not the same. Shouldn't in both cases assert(a == real.infinity, to!(string)(a)); hold. Without optimization it holds. Why does it not hold with optimizations? JensThe compiler (optimizer) recognizes you have provided only constants and try to do constant folding. But the backend (evalu8.c) did not treat the divide-by-zero case correctly and yields a garbage value. See bug 5908 (http://d.puremagic.com/issues/show_bug.cgi?id=5908).
Apr 29 2011