Skip to content

Conversation

@folkertdev
Copy link
Contributor

tracking issue: #44930

Provide our own implementations in order to guarantee the behavior of va_arg. We will only be able to stabilize c_variadic on targets where we know and guarantee the properties of va_arg.

r? workingjubilee

@folkertdev folkertdev added the F-c_variadic `#![feature(c_variadic)]` label Dec 17, 2025
@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 17, 2025
@rustbot
Copy link
Collaborator

rustbot commented Dec 17, 2025

workingjubilee is currently at their maximum review capacity.
They may take a while to respond.

Copy link
Contributor Author

@folkertdev folkertdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are (or, should be) the straightforward cases where LLVM just calls emitVoidPtrVAArg.

View changes since this review

Comment on lines +968 to +1101
Arch::AmdGpu => emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes4,
AllowHigherAlign::No,
ForceRightAdjust::No,
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just making sure @Flakebi sees this, since we had one platform weirdness and the idea of varargs on a GPU at least feels inherently fishy, but maybe it's like... fine actually? feels like a bad idea performance wise, but

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparing the Rust and clang implementation, this looks fine (thanks for checking).
I wanted to say I never tried varargs on GPUs but I did use printf, so… (GPUs inline everything anyway, so as long as it’s inlined before instruction selection it’s not a problem performance wise)

Comment on lines +977 to +1110
Arch::Nvptx64 => emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes1,
AllowHigherAlign::Yes,
ForceRightAdjust::No,
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @kjetilkjeka for similar reasons: just letting you know about this if you have a comment.

Comment on lines +986 to +1123
Arch::Wasm32 | Arch::Wasm64 => emit_ptr_va_arg(
bx,
addr,
target_ty,
if layout.is_aggregate() || layout.is_zst() || layout.is_1zst() {
PassMode::Indirect
} else {
PassMode::Direct
},
SlotSize::Bytes4,
AllowHigherAlign::Yes,
ForceRightAdjust::No,
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/llvm/llvm-project/blob/c386d6d3bfa400e94ac9cadb85a0b1a72ed54b2b/clang/lib/CodeGen/Targets/WebAssembly.cpp#L163

curiously the slot size is always 4, independent of whether wasm32 or wasm64 is used. I suppose that may change in the future if/when wasm64 gets more attention.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrrm. Should we make this work on wasm64 at all, then, if we expect a change? I don't want to put @alexcrichton and @daxpedda through another round of wasm ABI grief, even if variable arguments are more niche.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anything special in the Wasm tool convention saying that pointers for Varargs are suddenly 32-bit, so this is a bug in LLVM. I've encountered similar bugs around Wasm64 in LLVM already so this tracks.

Alex should confirm though, never touched the internals of Vararg in my life before. In the meantime I will open a PR in LLVM where target maintainers can confirm that as well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks.

Assuming that makes it into llvm 22 (i.e. is merged before late January), what should we do on the rust side until then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is best answered by the compiler team but just wanted to note that wasm64-unknown-unknown is not stable so maybe this doesn't have to be a blocker for anything. I'm also happy to push for backporting this to a LLVM patch version if it helps.

Copy link
Contributor Author

@folkertdev folkertdev Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wanted to note that wasm64-unknown-unknown is not stable so maybe this doesn't have to be a blocker for anything.

It is not a blocker, just a matter of how we do the best thing we can right now and ensure that we circle back to this when the LLVM fix lands and/or when wasm64 becomes more official.

I'm also happy to push for backporting this to a LLVM patch version if it helps.

If this can make it into LLVM 22 then I think that's good enough.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I'm currently on the side of "fatal error or ICE if someone uses wasm64-u-u with varargs and it reaches this actual codegen site" but can be persuaded this is a bad idea.

Comment on lines +999 to +1132
Arch::CSky => emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes4,
AllowHigherAlign::Yes,
ForceRightAdjust::No,
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @Dirreke if there's anything of particular interest here.

@bors
Copy link
Collaborator

bors commented Dec 17, 2025

☔ The latest upstream changes (presumably #150089) made this pull request unmergeable. Please resolve the merge conflicts.

@rustbot
Copy link
Collaborator

rustbot commented Dec 17, 2025

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. F-c_variadic `#![feature(c_variadic)]` S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants