www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12989] New: Wrong x86_64 code for delegate return when

https://issues.dlang.org/show_bug.cgi?id=12989

          Issue ID: 12989
           Summary: Wrong x86_64 code for delegate return when compiled as
                    lib (-lib)
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: critical
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: dragoscarp gmail.com

Created attachment 1365
  --> https://issues.dlang.org/attachment.cgi?id=1365&action=edit
expose bug by running ./runme.sh

Wrong code for returning a delegate from a synchronized method of a class with
invariants.

Compiling it as library with -lib (2.065) following code is generated at the
end of the method A.foo (see the comments inline):

 102:48 8b 45 c8          mov    -0x38(%rbp),%rax   <-- $rax contains the
address of the delegate
 106:    48 8b 48 08              mov    0x8(%rax),%rcx     <-- $rcx contains
the delegate function pointer
 10a:    48 8b 30                 mov    (%rax),%rsi        <-- $rsi contains
the context pointer
 10d:    48 83 ec 08              sub    $0x8,%rsp
 111:    e8 15 00 00 00           callq  12b
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x12b>
 116:    48 83 c4 08              add    $0x8,%rsp
 11a:    eb 23                    jmp    13f
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x13f>
 11c:    48 83 ec 08              sub    $0x8,%rsp
 120:    e8 06 00 00 00           callq  12b
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x12b>
 125:    48 83 c4 08              add    $0x8,%rsp
 129:    eb 10                    jmp    13b
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x13b>
 12b:    48 bf 00 00 00 00 00     movabs $0x0,%rdi
 132:    00 00 00 
 135:    e8 00 00 00 00           callq  13a
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x13a>
 13a:    c3                       retq   
 13b:    31 f6                    xor    %esi,%esi
 13d:    31 c9                    xor    %ecx,%ecx
 13f:    48 89 75 d0              mov    %rsi,-0x30(%rbp)   <-- try to save
delegate pointer and context on stack, but they are
 143:    48 89 4d d8              mov    %rcx,-0x28(%rbp)   <-- already
overwritten by the previous monitor_unlock call
 147:    48 83 7d e0 00           cmpq   $0x0,-0x20(%rbp)
 14c:    75 07                    jne    155
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x155>
 14e:    31 ff                    xor    %edi,%edi
 150:    e8 00 00 00 00           callq  155
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x155>
 155:    48 8b 7d e0              mov    -0x20(%rbp),%rdi
 159:    e8 00 00 00 00           callq  15e
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x15e>
 15e:    48 8b 55 d8              mov    -0x28(%rbp),%rdx
 162:    48 8b 45 d0              mov    -0x30(%rbp),%rax
 166:    41 5f                    pop    %r15
 168:    41 5e                    pop    %r14
 16a:    41 5d                    pop    %r13
 16c:    41 5c                    pop    %r12
 16e:    5b                       pop    %rbx
 16f:    48 8b e5                 mov    %rbp,%rsp
 172:    5d                       pop    %rbp
 173:    c3                       retq   
 174:    0f 1f 40 00              nopl   0x0(%rax)

Strangely compiling the object file with -c (2.065) generates right code:

 102:    48 8b 45 c8              mov    -0x38(%rbp),%rax   <-- $rax contains
the address of the delegate
 106:    48 8b 50 08              mov    0x8(%rax),%rdx     <-- $rdx contains
the delegate function pointer
 10a:    48 8b 00                 mov    (%rax),%rax        <-- $rax contains
the context pointer
 10d:    48 89 45 d0              mov    %rax,-0x30(%rbp)   <-- save them on
stack
 111:    48 89 55 d8              mov    %rdx,-0x28(%rbp)   <-- save them on
stack
 115:    48 83 ec 08              sub    $0x8,%rsp
 119:    e8 15 00 00 00           callq  133
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x133>
 11e:    48 83 c4 08              add    $0x8,%rsp
 122:    eb 2f                    jmp    153
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x153>
 124:    48 83 ec 08              sub    $0x8,%rsp
 128:    e8 06 00 00 00           callq  133
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x133>
 12d:    48 83 c4 08              add    $0x8,%rsp
 131:    eb 10                    jmp    143
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x143>
 133:    48 bf 00 00 00 00 00     movabs $0x0,%rdi
 13a:    00 00 00 
 13d:    e8 00 00 00 00           callq  142
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x142>
 142:    c3                       retq   
 143:    48 c7 45 d0 00 00 00     movq   $0x0,-0x30(%rbp)
 14a:    00 
 14b:    48 c7 45 d8 00 00 00     movq   $0x0,-0x28(%rbp)
 152:    00 
 153:    48 83 7d e0 00           cmpq   $0x0,-0x20(%rbp)
 158:    75 07                    jne    161
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x161>
 15a:    31 ff                    xor    %edi,%edi
 15c:    e8 00 00 00 00           callq  161
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x161>
 161:    48 8b 7d e0              mov    -0x20(%rbp),%rdi
 165:    e8 00 00 00 00           callq  16a
<_D17delegatereturnbug1A3fooMFDFZvZDFZv+0x16a>
 16a:    48 8b 55 d8              mov    -0x28(%rbp),%rdx
 16e:    48 8b 45 d0              mov    -0x30(%rbp),%rax
 172:    41 5f                    pop    %r15
 174:    41 5e                    pop    %r14
 176:    41 5d                    pop    %r13
 178:    41 5c                    pop    %r12
 17a:    5b                       pop    %rbx
 17b:    48 8b e5                 mov    %rbp,%rsp
 17e:    5d                       pop    %rbp
 17f:    c3                       retq   


DMD ~master/HEAD generates wrong code for both -c and -lib.

--
Jun 25 2014