Bug 12989 – Wrong x86_64 code for delegate return when compiled as lib (-lib)

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-06-25T13:07:00Z
Last change time
2014-08-22T08:04:26Z
Keywords
wrong-code
Assigned to
nobody
Creator
dragoscarp

Attachments

IDFilenameSummaryContent-TypeSize
1365delegatereturnbug.tar.gzexpose bug by running ./runme.shapplication/gzip837
1368issue12989.dSimplified testtext/x-dsrc607

Comments

Comment #0 by dragoscarp — 2014-06-25T13:07:29Z
Created attachment 1365 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.
Comment #1 by dragoscarp — 2014-07-08T11:13:13Z
Created attachment 1368 Simplified test Compile it with dmd -m64 -gc -O issue12989.d
Comment #2 by dragoscarp — 2014-07-08T11:22:21Z
With dmd2.066.0-b1 it always generates wrong code and the workaround (compile it as .o file) doesn't work anymore, thus rated to "regression". As side note: the 32bit binary is 317KB and the 64bit, with 2.4MB, is 7.5X larger.
Comment #3 by bugzilla — 2014-07-08T21:32:44Z
// Attachment 1368 is small enough to inline here: alias Action = void delegate(); class A { invariant() { } public Action foo(Action a) { synchronized { B elements = new B; Action[] actions = [a]; elements.bar(actions); if (actions.length > 1) elements.bar(actions); return actions[0]; } return null; } } class B { public bool bar(ref Action[]) { return false; } } class D { void baz() { } } void main() { auto a = new A; auto d = new D; assert(a.foo(&d.baz) == &d.baz); }
Comment #4 by bugzilla — 2014-07-09T05:06:55Z
Can confirm on -m64 Linux.
Comment #5 by bugzilla — 2014-07-10T08:00:30Z
Comment #6 by github-bugzilla — 2014-07-10T08:37:54Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/be3426c4744b8391b75bad1bcbb97492d451e7ce fix Issue 12989 - Wrong x86_64 code for delegate return when compiled as lib https://github.com/D-Programming-Language/dmd/commit/3cb35fe75c9e4c16828b8d09b3e564712112652e Merge pull request #3735 from WalterBright/fix12989 fix Issue 12989 - Wrong x86_64 code for delegate return when compiled as...
Comment #7 by github-bugzilla — 2014-07-14T19:41:25Z
Comment #8 by github-bugzilla — 2014-07-15T10:26:18Z
Commits pushed to 2.066 at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/cf55d684e39e959e449c02258d945225d56063b8 Merge pull request #3735 from WalterBright/fix12989 fix Issue 12989 - Wrong x86_64 code for delegate return when compiled as... https://github.com/D-Programming-Language/dmd/commit/e7c1ba5a75d09945bd3be3cbe185e816a7fd6283 Merge pull request #3739 from WalterBright/fix12989-2 2nd try at fix Issue 12989
Comment #9 by github-bugzilla — 2014-08-22T08:04:26Z