Fix RISC-V C function ABI when passing/returning structs containing floats #139340
+514
−130
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 arest_offset
field toCastTarget
that can be used to explicitly specify at what offset therest
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 @toppercr? @workingjubilee