This patch adds CC_M68kRTD to model llvm::CallingConv::M68k_RTD if either __attribute__((m68k_rtd)) is presented on a function or -mrtd flag is given.
Details
Diff Detail
Event Timeline
clang/test/CodeGen/mrtd.c | ||
---|---|---|
9 | I guess this involves more work ? |
clang/test/CodeGen/mrtd.c | ||
---|---|---|
9 |
Yes because it requires changes to (LLVM IR's) AsmReader/Writer. But it's not hard and I can do that. The reason I didn't do that was simply because this CC is rare so the arcane name's impact on (our) productivity will be low. |
I didn't see any issue here. Let's wait for the approval from other (more senior) reviewers.
So GCC gives me:
warning: ‘stdcall’ attribute directive ignored [-Wattributes]
when trying to use __attribute__((stdcall)) on m68k, which matches the fact it's only mentioned in the manage for the x86 option.
Interestingly it seems to ICE during expand when I use -mrtd though...
clang/lib/Basic/Targets/M68k.cpp | ||
---|---|---|
258 | Uhh | |
clang/lib/CodeGen/CGCall.cpp | ||
51 | Ditto... | |
clang/test/CodeGen/mrtd.c | ||
4 | Ew... this should be using -verify and // expected-warning {{...}}, then the line number is relative to the comment's location. Or, really, it should be in the Sema test... Plus is it correct to call this stdcall on m68k? The GCC manpage only mentions it in the x86 option description, not the m68k one. |
In principal, I wanted to reuse as much existing code path as possible to handle -mrtd, primarily because these two calling conventions are basically identical and I didn't want to create too much churn. Reusing both DCC_StdCall and CC_X86StdCall serves that purpose. Making __attribute__((stdcall)) available to m68k is just a side effect that I felt harmless.
I'm fine to create a separate CC_M68kRTDCall or even DCC_RTDCall. What do you think @jrtc27 ?
Interestingly it seems to ICE during expand when I use -mrtd though...
I guess you're referring to GCC? I'm curious which snippet you used.
Though creating our own calling convention is better, I think Min's path is correct at this moment given that m68k is still an experimental target. We can reignite this discussion once we're ready to becoming a offiical target.
@myhsu could you open an issue to cite this problem ?
I disagree. Being experimental doesn't mean you should do the wrong thing. Reusing stdcall in the frontend is ugly, pollutes non-m68k code paths (doing your own thing _avoids_ that and makes the experimental backend get out of the way, even) and introduces a bug where you can write garbage code and have it compile rather than be rejected like it should be.
Add your own calling convention like everyone else.
Maybe we can get the TLS stuff merged first before dealing with this more complex change?
They're totally independent, so nothing's blocking that being merged. Plus this isn't a complex change to make, just a bunch of copy pasta.
Use a new CC, CC_M68kRTD, to model llvm::CallingConv::M68k_RTD instead of using X86StdCall
clang/test/CodeGen/mrtd.c | ||
---|---|---|
4 | Now this check is moved to test/Sema/m68k-mrtd.c |
This should also come with a release note for the changes.
clang/lib/AST/ASTContext.cpp | ||
---|---|---|
11998–11999 | This looks wrong to me -- if the language option is calling for stdcall, saying "here's m68k_rtd instead" does not match caller expectations. | |
clang/lib/Frontend/CompilerInvocation.cpp | ||
559 | Maybe it's too early in the morning for me to be thinking clearly, but this is wrong for m68k, isn't it? If the default calling convention is stdcall and the architecture is m68k, we want to emit the error, don't we? I don't see test coverage for the change. | |
clang/lib/Sema/SemaType.cpp | ||
7960–7961 | Missing test coverage, but also, MSVC supports m68k RTD? I would assume we'd error on this situation given how we document the attribute as not supporting this. | |
clang/test/CodeGen/mrtd.c | ||
4 | This check should be removed here -- we don't typically test diagnostic behavior from codegen tests unless the diagnostic is only emitted during codegen. | |
clang/test/Sema/m68k-mrtd.c | ||
4–9 | A better way to do this is to use -verify=mrtd on the line enabling rtd, and using // rtd-error {{whatever}} on the line being diagnosed. (Same comment applies throughout the file.) Huh, I was unaware that implicit function declarations are using something other than the default calling convention (which is C, not m68k_rtd). Is this intentional? | |
45 | Missing tests for:
|
- Add a new default calling convention -fdefault-calling-conv=rtdcall to model using m68k_rtdcc globally
- Add documents for rtdcall
- Add more tests on __attribute__((m68k_rtd))
clang/lib/Frontend/CompilerInvocation.cpp | ||
---|---|---|
559 | The idea was to use our new RTD CC whenever -mrtd is given to either the driver or the frontend. Due to some historical reasons -mrtd has been taken by i386 to specify stdcall. Specifically, DefaultCallingConvention will be set to DCC_StdCall when -mrtd is present. My original approach was to reuse this workflow and the DCC_StdCall, then translate to either CC_X86StdCall or CC_M68kRTD later in ASTContext. Since there are many concerns on reusing DCC_StdCall, I will create another DCC enum value instead. | |
clang/test/Sema/m68k-mrtd.c | ||
4–9 |
I'm not sure if I understand you correctly, but this diagnostic is emitted if the CC does not support variadic function call. | |
45 |
I thought the first check was testing function without a prototype.
I believe we don't have any special handling for C++. I addressed rest of the bullet items you mentioned, please take a look. |
Sorry for the long delay in review on this, it slipped through the cracks for me.
clang/lib/AST/TypePrinter.cpp | ||
---|---|---|
1835 | ||
clang/test/Sema/m68k-mrtd.c | ||
4–9 | bar is not declared, in C89 this causes an implicit function declaration to be generated with the signature: extern int ident(); What surprised me is that we seem to be generating something more like this instead: __attribute__((m68k_rtd)) int ident(); despite that not being valid. | |
45 |
Nope, I meant something more like this: __attribute__((m68k_rtd)) void foo(); // Should error __attribute__((m68k_rtd)) void bar(a, b) int a, b; {} // Should error
Test coverage should still exist to ensure the behavior is what you'd expect when adding the calling convention to a member function and a lambda, for example. (Both Sema and CodeGen tests for this) Also missing coverage for the changes to -fdefault-calling-conv= I'm also still wondering whether there's a way to use m68k with a Windows ABI triple (basically, do we need changes in MicrosoftMangle.cpp?) |
Also, it looks like precommit CI found a relevant failure that should be investigated.
Sorry I was busy on my phd defense (which I passed!) in the past month. I'll get back to this next week.
- Rebase
- Add more C++ tests for m68k_rtd, both Sema and CodeGen ones
- Addressed other comments
clang/test/Sema/m68k-mrtd.c | ||
---|---|---|
4–9 | I understand what you meant, but the standard only says that using implicit declared identifier is as if extern int ident(); appears in the source code. My interpretation is that in this case since the very source code is compiled with -mrtd, every functions use m68k_rtd rather than C calling convention. Another example is stdcall: i386 Clang emits a similar warning ("function with no prototype cannot use the stdcall calling convention") when -mrtd is used (to set default CC to stdcall) on the same snippet. Should bar was not called with stdcall under the influence of -mrtd, the aforementioned message would not be emitted in the first place. | |
45 |
Right now Clang only gives a warning about potential behavior change after C23, rather than an error for this kind of syntax. Because it seems like Clang doesn't check this situation against unsupported calling convention. I'm not sure if we should throw the same error as __attribute__((m68k_rtd)) void foo().
I don't think it's worth it to support m68k with Windows ABI as this combination never existed (and unlikely to happen in the future) |
Congratulations!! 🎉
LGTM!
clang/test/Sema/m68k-mrtd.c | ||
---|---|---|
4–9 | Ahhh okay, this makes more sense now -- this matches other ways in which we set the default calling convention, it's just a bit more hidden from view. Here's a more obvious example: https://godbolt.org/z/sboxf83s6 | |
45 |
It looks like this is an existing Clang bug: https://godbolt.org/z/WcYbcEhde
SGTM! |
Addressed comments in test/CodeGen/mrtd.c
clang/test/CodeGen/mrtd.c | ||
---|---|---|
12 | Thanks for pointing out. I'll put the changes to using DefineStd in a separate patch. |
Any news on this? I guess it would be nice to get the remaining m68k patches merged before the Phrabricator shutdown.
Maybe these patches need to be reposted to Github as they seem to be ignored here now after the swtich from Phabricator.
Posting on GitHub loses all context; please don't do that. Whose review are you looking for? You've addressed my feedback and you had approval from Aaron on the prior version, with the latest version just being a few minor tweaks to address the couple of comments I had left on the approved version.
This looks wrong to me -- if the language option is calling for stdcall, saying "here's m68k_rtd instead" does not match caller expectations.