This is an archive of the discontinued LLVM Phabricator instance.

[DRAFT][WebAssembly] Do not support `[[clang::musttail]]` by default
Needs ReviewPublic

Authored by tlively on Aug 16 2022, 12:59 PM.

Details

Reviewers
aaron.ballman
Summary

WebAssembly is not able to emit tail calls unless the tail-call target feature
is enabled and when it is not enabled, trying to compile musttail calls produces
a fatal error in the backend. To reflect this reality, disable support for the
[[clang::musttail]] attribute when targeting WebAssembly without the
tail-call feature.

Marked draft for further discussion because I'm not sure getting this:

test.cpp:10:7: warning: unknown attribute 'musttail' ignored [-Wunknown-attributes]
    [[clang::musttail]] return bar(x * 10);

is actually better developer experience than getting a fatal error with a
description of the WebAssembly-specific problem. Users can also check for the
presence of the __wasm_tail_call__ macro as an alternative to checking
__has_cpp_attribute(clang::musttail) with this patch, but I'm not sure that's
documented anywhere.

Diff Detail

Event Timeline

tlively created this revision.Aug 16 2022, 12:59 PM
Herald added a project: Restricted Project. · View Herald Transcript
tlively requested review of this revision.Aug 16 2022, 12:59 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 16 2022, 12:59 PM
tlively added a comment.EditedAug 16 2022, 3:37 PM

For reference, the existing error from the backend is something like this:

test.cpp:9:5: error: WebAssembly 'tail-call' feature not enabled
int foo(int x) {
    ^

Note that it points to the beginning of the caller rather than the specific line containing the tail call.

Ideally we would get the current fatal error and diagnostic message with the more specific context from this patch.

Marked draft for further discussion because I'm not sure getting this:

test.cpp:10:7: warning: unknown attribute 'musttail' ignored [-Wunknown-attributes]
    [[clang::musttail]] return bar(x * 10);

is actually better developer experience than getting a fatal error with a description of the WebAssembly-specific problem.

FWIW, I think it's vastly better. A fatal error on the backend is a bug in the compiler. Telling the user "this attribute won't do anything for you" is a feature. If we think the "unknown attribute ignored" warning is too generic and we'd rather see something like "attribute 'foo' not supported on this target", that's an improvement but one we should make across all target-specific attributes. (FWIW, I'd be happy to review such a patch if you or anyone else felt like working on it. But I don't think it's a requirement for what you're doing here.)

I think all that's missing from this patch are test cases and a release note.

I agree that the front-end error is preferable. In addition to front-end vs. back-end distinction being important -- it's also ignorable (if someone wants to do that).
Is the goal to also make __has_cpp_attribute(clang::musttail) resolve to 0? I think that's the ideal outcome - it lets users rely on documented ("standard") behavior to make decisions about which attributes to use. As it stands, I have to write my code like this:

#if __has_cpp_attribute(clang::musttail) && !defined(__EMSCRIPTEN__)
  ...

That's brittle, and easy to overlook or forget to update if/when the WASM engines and LLVM code-gen do support musttail in the future.