[Issue 15573] -O -inline causes wrong code with idiv instruction
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Thu Jan 21 15:53:58 PST 2016
https://issues.dlang.org/show_bug.cgi?id=15573
--- Comment #29 from hsteoh at quickfur.ath.cx ---
Alright, I think I found the real culprit now.
Still referencing the asm dump I posted, the problematic spot is here:
...
438cb8: 31 f6 xor %esi,%esi
438cba: 64 48 8b 0c 25 00 00 mov %fs:0x0,%rcx
438cc1: 00 00
438cc3: 48 8b 15 66 91 24 00 mov 0x249166(%rip),%rdx #
681e30 <_DYNAMIC+0x258>
438cca: 89 34 11 mov %esi,(%rcx,%rdx,1)
***** PROBLEM: rdx at this point contains -288 (0xfffffee0)
438ccd: 38 75 f8 cmp %dh,-0x8(%rbp)
438cd0: 41 0f 94 c6 sete %r14b
...
I'm not exactly sure what exactly is the load from 0x249166(%rip) for, or why
the compiler would want to emit such a thing here, because this part of the
code is computing the value of "(right == 0)" (from the top of the safeDiv
function, here inlined). The corresponding part of the good (unoptimized)
version of the code reads:
... (NOTE: from a different disassembly)
438bb1: 89 7d f0 mov %edi,-0x10(%rbp)
438bb4: 89 75 f8 mov %esi,-0x8(%rbp)
// right == 0
438bb7: 80 7d f0 00 cmpb $0x0,-0x10(%rbp)
438bbb: 0f 94 c0 sete %al
...
Here, %edi contains the parameter 'right', which is stored in the local stack
variable -0x10(%rbp) and then compared against 0.
In the bad (optimized) version at the top, however, it's comparing the local
variable `m` (which, from an earlier part of the dump, can be seen to be stored
in -0x8(%rbp)) against %dh, which doesn't seem to make sense. Why does the
compiler emit a comparison agains %dh instead of 0x0? Is it assuming that %dh
is zero? Why would it make such as assumption?
After this point, the value of div0 is wrong, and the code proceeds down a
different path than it should.
--
More information about the Digitalmars-d-bugs
mailing list