Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 31, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 Manu <turkeyman@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |C++, industry -- |
May 31, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #1 from Manu <turkeyman@gmail.com> --- I'm suspecting an issue with RVO. I think the MSC ABI has changed to guarantee RVO at some point in the last few years... but I'm not sure why the static call and virtual call appear to be called using different calling convention. -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #2 from Walter Bright <bugzilla@digitalmars.com> --- Can you please post an example that doesn't require the IDDE? Just show the disassembly where the code is wrong, please. -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #3 from Manu <turkeyman@gmail.com> --- You'll have to relate these 2 lines to the .cpp file (attached) in main() Calling code in main(): // static call... auto x = addUser(test, "test"); 00007FF74843C587 lea rdx,[string "test" (07FF748448D44h)] 00007FF74843C58E mov rcx,qword ptr [test] 00007FF74843C592 call addUser (07FF74840C735h) 00007FF74843C597 mov dword ptr [rbp+104h],eax 00007FF74843C59D mov eax,dword ptr [rbp+104h] 00007FF74843C5A3 mov dword ptr [x],eax // virtual call... x = test->addUser("test"); 00007FF74843C5A6 mov rax,qword ptr [test] 00007FF74843C5AA mov rax,qword ptr [rax] 00007FF74843C5AD lea r8,[string "test" (07FF748448D44h)] 00007FF74843C5B4 lea rdx,[rbp+124h] // what is? RVO return address? 00007FF74843C5BB mov rcx,qword ptr [test] 00007FF74843C5BF call qword ptr [rax] 00007FF74843C5C1 mov eax,dword ptr [rax] 00007FF74843C5C3 mov dword ptr [x],eax This is the C++ code calling into D; it appears C++ makes a static call differently to a virtual call? I suspect RDX in the virtual call is the RVO return address? I wonder why the static-call doesn't follow the same call convention? I can attach the DMD disassembly? But it's probably easier to build that yourself. This might reveal that the VC ABI has RVO rules that we don't understand? -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #4 from Manu <turkeyman@gmail.com> --- If you look at the disassembly of userdatabase.d, you'll see that the virtual function is not expecting the string in R8 where VC is putting it. It also doesn't appear to return via the RVO pointer(?) in RDX. The static call matches D's expectations. -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 kinke@gmx.net changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |kinke@gmx.net --- Comment #5 from kinke@gmx.net --- (In reply to Manu from comment #3) > This might reveal that the VC ABI has RVO rules that we don't understand? Or rather that their C++ ABI apparently enforces sret/RVO for methods returning structs, even such trivial 32-bit PODs, but doesn't for normal functions. Interesting findings; I'll verify them. -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #6 from Manu <turkeyman@gmail.com> --- I recall a few years ago reading some article about MSVC breaking their ABI to guarantee RVO, because C++11 and move semantics and all that. I guess it needed to be efficient and therefore justified guaranteeing RVO where previously it was an optimisation. It's probably the case that extern(C++) was implemented before C++11 made it to MSVC. -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #7 from kinke@gmx.net --- Well it doesn't make too much sense, and even less so to do it for methods only; I rather think this is some legacy COM compatibility stuff. I did a few tests, and it really seems to be specific to methods (instance member functions), which return every struct via sret/RVO, not just non-PODs as regular functions, incl. class member functions. So this is essentially a duplicate of https://issues.dlang.org/show_bug.cgi?id=16987; I thought it was COM-specific back then. I tried fixing it for LDC, but that's sadly not trivial, as the ABI stuff doesn't operate on FuncDeclaration but on TypeFunction, which contains the calling convention but not whether it's a method. -- |
June 01, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #8 from Manu <turkeyman@gmail.com> --- So, probability of a prompt fix? Is this just a matter of not having correct information up front, or is the fix complicated by some issue? We have an evaluation here that's kinda been shattered by this, but a fast fix would really help recover the situation if it's possible. -- |
June 02, 2018 [Issue 18928] extern(C++) bad codegen, wrong calling convention | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=18928 --- Comment #9 from kinke@gmx.net --- Well I gave it a shot and came up with an ugly hack which might just work, the first test results are promising: https://github.com/ldc-developers/ldc/pull/2720 -- |
Copyright © 1999-2021 by the D Language Foundation