digitalmars.D - Division by zero
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (78/78) Oct 03 2014 http://dlang.org/expression#MulExpression says:
- David Nadlinger (7/8) Oct 03 2014 Note that they just return whatever is in eax/rax at that time,
- Adam D. Ruppe (6/8) Oct 03 2014 It should probably just say that is implementation defined. I'm
- monarch_dodra (4/10) Oct 03 2014 Technically, the doc is also wrong for windows, since it's an
- Walter Bright (2/12) Oct 03 2014 In any case, a bugzilla issue should be filed for this.
- monarch_dodra (2/3) Oct 03 2014 https://issues.dlang.org/show_bug.cgi?id=13569
- Walter Bright (2/5) Oct 04 2014 Thanks!
- Daniel Murphy (3/6) Oct 03 2014 https://issues.dlang.org/show_bug.cgi?id=5908
- David Nadlinger (12/13) Oct 03 2014 By the way, this (just emitting an x86 idiv even if it the
- Daniel Murphy (4/13) Oct 03 2014 That's annoying, but I guess it makes sense given how much division vari...
http://dlang.org/expression#MulExpression says: "For integral operands of the / and % operators, [...]. If the divisor is zero, an Exception is thrown." However, DMD behaves differently. Consider this simple test program: int test_int() { int x; return x/x; } long test_long() { long x; return x/x; } int test_runtime(int x) { return x/x; } int main() { return test_runtime(0); } When compiled without optimization, the program receives SIGFPE at runtime (i.e. not an exception, but a signal). The generated code for `test_int` and `test_long` looks like this, with the constants returned changing on each compilation: Disassembly of section .text._D2xx8test_intFZi: 0000000000000000 <_D2xx8test_intFZi>: 0: 55 push %rbp 1: 48 8b ec mov %rsp,%rbp 4: b8 80 63 54 02 mov $0x2546380,%eax 9: 5d pop %rbp a: c3 retq b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) Disassembly of section .text._D2xx9test_longFZl: 0000000000000000 <_D2xx9test_longFZl>: 0: 55 push %rbp 1: 48 8b ec mov %rsp,%rbp 4: 48 b8 e0 63 54 02 00 movabs $0x25463e0,%rax b: 00 00 00 e: 5d pop %rbp f: c3 retq When compiled with "-O -inline", it doesn't receive the signal, but returns a nonsense value. This is to be expected, because inlining just propagates the wrong value to the main function. The same exercise for LDC 0.14.0: When run, the program behaves the similarly as with DMD (SIGFPE without optimization, always return value "1" with -O3). The disassembly without optimization: Disassembly of section .text._D2xx8test_intFZi: 0000000000000000 <_D2xx8test_intFZi>: 0: c7 44 24 fc 00 00 00 movl $0x0,-0x4(%rsp) 7: 00 8: 8b 44 24 fc mov -0x4(%rsp),%eax c: 99 cltd d: f7 7c 24 fc idivl -0x4(%rsp) 11: c3 retq Disassembly of section .text._D2xx9test_longFZl: 0000000000000000 <_D2xx9test_longFZl>: 0: 48 c7 44 24 f8 00 00 movq $0x0,-0x8(%rsp) 7: 00 00 9: 48 8b 44 24 f8 mov -0x8(%rsp),%rax e: 48 99 cqto 10: 48 f7 7c 24 f8 idivq -0x8(%rsp) 15: c3 retq However, with -O3, it gets interesting: Disassembly of section .text._D2xx8test_intFZi: 0000000000000000 <_D2xx8test_intFZi>: 0: c3 retq Disassembly of section .text._D2xx9test_longFZl: 0000000000000000 <_D2xx9test_longFZl>: 0: c3 retq Disassembly of section .text._D2xx12test_runtimeFiZi: 0000000000000000 <_D2xx12test_runtimeFiZi>: 0: b8 01 00 00 00 mov $0x1,%eax 5: c3 retq test_int() and test_long() return ...nothing! And test_runtime() always returns 1. Now the big question: How many bugs are there, and where are they? Candidates: The specification, DMD's frontend (in two versions: DMD master, and 2.065 used by LDC), DMD's backend and LDC's backend.
Oct 03 2014
On Friday, 3 October 2014 at 12:31:54 UTC, Marc Schütz wrote:test_int() and test_long() return ...nothing!Note that they just return whatever is in eax/rax at that time, just like DMD returns a garbage value. The fact that integer division by zero is undefined behavior on the LLVM side but defined in the D spec may well be an LDC bug, though. David
Oct 03 2014
On Friday, 3 October 2014 at 12:31:54 UTC, Marc Schütz wrote:"For integral operands of the / and % operators, [...]. If the divisor is zero, an Exception is thrown."It should probably just say that is implementation defined. I'm pretty sure it does throw an exception on Windows (at least 32 bit), but doing that on linux is a pain in the butt since the operating system sends a signal and transformaing that into an exception is hacky.
Oct 03 2014
On Friday, 3 October 2014 at 12:55:35 UTC, Adam D. Ruppe wrote:On Friday, 3 October 2014 at 12:31:54 UTC, Marc Schütz wrote:Technically, the doc is also wrong for windows, since it's an *Error* that is thrown: object.Error (0): Integer Division by 0"For integral operands of the / and % operators, [...]. If the divisor is zero, an Exception is thrown."It should probably just say that is implementation defined. I'm pretty sure it does throw an exception on Windows (at least 32 bit)...
Oct 03 2014
On 10/3/2014 6:11 AM, monarch_dodra wrote:On Friday, 3 October 2014 at 12:55:35 UTC, Adam D. Ruppe wrote:In any case, a bugzilla issue should be filed for this.On Friday, 3 October 2014 at 12:31:54 UTC, Marc Schütz wrote:Technically, the doc is also wrong for windows, since it's an *Error* that is thrown: object.Error (0): Integer Division by 0"For integral operands of the / and % operators, [...]. If the divisor is zero, an Exception is thrown."It should probably just say that is implementation defined. I'm pretty sure it does throw an exception on Windows (at least 32 bit)...
Oct 03 2014
On Friday, 3 October 2014 at 13:29:18 UTC, Walter Bright wrote:In any case, a bugzilla issue should be filed for this.https://issues.dlang.org/show_bug.cgi?id=13569
Oct 03 2014
On 10/3/2014 7:22 AM, monarch_dodra wrote:On Friday, 3 October 2014 at 13:29:18 UTC, Walter Bright wrote:Thanks!In any case, a bugzilla issue should be filed for this.https://issues.dlang.org/show_bug.cgi?id=13569
Oct 04 2014
"Marc Schütz" " wrote in message news:pcvahdmzurxleawafjqs forum.dlang.org...Now the big question: How many bugs are there, and where are they? Candidates: The specification, DMD's frontend (in two versions: DMD master, and 2.065 used by LDC), DMD's backend and LDC's backend.https://issues.dlang.org/show_bug.cgi?id=5908
Oct 03 2014
On Friday, 3 October 2014 at 14:54:17 UTC, Daniel Murphy wrote:https://issues.dlang.org/show_bug.cgi?id=5908By the way, this (just emitting an x86 idiv even if it the operands are known to trap) will likely be a pain to implement for LDC. There has been an (overly aggressive, on the side of two LLVM devs) discussion about this a year ago or so: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/060930.html. Personally, I find their stance highly troublesome, as they have introduced undefined behavior that is hard to circumvent for practically no potential performance gain. I just hope we can somehow avoid emitting a branch on every integer division… Cheers, David
Oct 03 2014
"David Nadlinger" wrote in message news:tqzutmhsvqtjskwvtixq forum.dlang.org...By the way, this (just emitting an x86 idiv even if it the operands are known to trap) will likely be a pain to implement for LDC. There has been an (overly aggressive, on the side of two LLVM devs) discussion about this a year ago or so: http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-April/060930.html. Personally, I find their stance highly troublesome, as they have introduced undefined behavior that is hard to circumvent for practically no potential performance gain. I just hope we can somehow avoid emitting a branch on every integer division…That's annoying, but I guess it makes sense given how much division varies across platforms.
Oct 03 2014