Skip to content

Fix RISC-V C function ABI when passing/returning structs containing floats #139340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 16, 2025

Conversation

beetrees
Copy link
Contributor

@beetrees beetrees commented Apr 3, 2025

RISC-V passes structs containing only one or two floats (or a float and integer pair) in registers, as long as the individual floats/integers fit in a single corresponding register (see the ABI specification for details). Before this PR, Rust would not check what offset the second float/integer was at, instead assuming that it was at the standard offset for its default alignment. However, as the offset can be affected by #[repr(align(N))] and #[repr(packed)], this caused miscompilations (see #115609). To fix this, this PR introduces a rest_offset field to CastTarget that can be used to explicitly specify at what offset the rest part of the cast is located at.

While fixing this, I discovered another bug: the size of the cast target was being used as the size of the MIR return place (when the function was using a PassMode::Cast return type). However, the cast target is allowed to be smaller than the size of the actual type, causing a miscompilation. This PR fixes this issue by using the largest of the size of the type and the size of the cast target as the size of the MIR return place, ensuring all reads/writes will be inbounds.

Fixes the RISC-V part of #115609.

cc target maintainers of riscv64gc-unknown-linux-gnu: @kito-cheng @michaelmaitland @robin-randhawa-sifive @topperc

r? @workingjubilee

@rustbot rustbot added 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 Apr 3, 2025
@rustbot
Copy link
Collaborator

rustbot commented Apr 3, 2025

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

@rust-log-analyzer

This comment has been minimized.

@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 725f521 to 2b5c6a9 Compare April 3, 2025 23:38
@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 2b5c6a9 to 5f18664 Compare April 4, 2025 09:03
@beetrees
Copy link
Contributor Author

Ping reviewer @workingjubilee

@workingjubilee
Copy link
Member

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 3, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 3, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 5f18664 to 86b24b8 Compare June 10, 2025 11:24
@rustbot rustbot added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Jun 10, 2025
@rustbot

This comment has been minimized.

@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 86b24b8 to 5d9726a Compare June 10, 2025 11:53
@beetrees
Copy link
Contributor Author

(I had to rebase to fix a merge conflict.)

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 10, 2025
@rust-log-analyzer

This comment has been minimized.

@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 5d9726a to 65531ad Compare June 10, 2025 13:33
@rust-log-analyzer

This comment has been minimized.

@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 65531ad to 6df68f3 Compare June 10, 2025 15:00
@bors
Copy link
Collaborator

bors commented Jun 16, 2025

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

Copy link
Member

@workingjubilee workingjubilee left a comment

Choose a reason for hiding this comment

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

Thank you, that makes it much easier to see these things.

@workingjubilee
Copy link
Member

r=me once you fix the merge conflicts again (sorry about that!)

@bors delegate+

@bors
Copy link
Collaborator

bors commented Jun 16, 2025

✌️ @beetrees, you can now approve this pull request!

If @workingjubilee told you to "r=me" after making some further change, please make that change, then do @bors r=@workingjubilee

@beetrees beetrees force-pushed the riscv-float-struct-abi branch from 6df68f3 to 5723c99 Compare June 16, 2025 09:19
@beetrees
Copy link
Contributor Author

@bors r=@workingjubilee

@bors
Copy link
Collaborator

bors commented Jun 16, 2025

📌 Commit 5723c99 has been approved by workingjubilee

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 16, 2025
bors added a commit that referenced this pull request Jun 16, 2025
Rollup of 8 pull requests

Successful merges:

 - #139340 (Fix RISC-V C function ABI when passing/returning structs containing floats)
 - #142341 (Don't suggest converting `///` to `//` when expecting `,`)
 - #142414 (ignore `run-make` tests that need `std` on targets without `std`)
 - #142498 (Port `#[rustc_as_ptr]` to the new attribute system)
 - #142554 (Fix `PathSource` lifetimes.)
 - #142562 (Update the `backtrace` submodule)
 - #142565 (Test naked asm for wasm32-unknown-unknown)
 - #142573 (`fn candidate_is_applicable` to method)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 4479d42 into rust-lang:master Jun 16, 2025
10 checks passed
@rustbot rustbot added this to the 1.89.0 milestone Jun 16, 2025
rust-timer added a commit that referenced this pull request Jun 16, 2025
Rollup merge of #139340 - beetrees:riscv-float-struct-abi, r=workingjubilee

Fix RISC-V C function ABI when passing/returning structs containing floats

RISC-V passes structs containing only one or two floats (or a float and integer pair) in registers, as long as the individual floats/integers fit in a single corresponding register (see [the ABI specification](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/releases/download/v1.0/riscv-abi.pdf) for details). Before this PR, Rust would not check what offset the second float/integer was at, instead assuming that it was at the standard offset for its default alignment. However, as the offset can be affected by `#[repr(align(N))]` and `#[repr(packed)]`, this caused miscompilations (see #115609). To fix this, this PR introduces a `rest_offset` field to `CastTarget` that can be used to explicitly specify at what offset the `rest` part of the cast is located at.

While fixing this, I discovered another bug: the size of the cast target was being used as the size of the MIR return place (when the function was using a `PassMode::Cast` return type). However, the cast target is allowed to be smaller than the size of the actual type, causing a miscompilation. This PR fixes this issue by using the largest of the size of the type and the size of the cast target as the size of the MIR return place, ensuring all reads/writes will be inbounds.

Fixes the RISC-V part of #115609.

cc target maintainers of `riscv64gc-unknown-linux-gnu`: `@kito-cheng` `@michaelmaitland` `@robin-randhawa-sifive` `@topperc`

r? `@workingjubilee`
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. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

6 participants