Skip to content
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

[ffi][riscv] CopyFromCompoundToStack and PopFromStackToTypedDataBase confused by struct packing #48645

Closed
rmacnak-google opened this issue Mar 22, 2022 · 2 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi

Comments

@rmacnak-google
Copy link
Contributor

CopyFromCompoundToStack and PopFromStackToTypedDataBase compute a rolling byte offset based on the size of Representations seen so far. This doesn't correctly account for pieces whose Representation is widened compared to the piece's size (because our IL doesn't really support Representations smaller than 32-bit), nor would it account for varying alignments in pieces.

For example, in PassStruct9BytesPackedMixedx10DoubleInt32x2 passing a packed struct { uint8_t, double }

        ;; v49 <- LoadField(v3 T{*} . _typedDataBase@8050071 {final}) T{Object?}
0x7f8f8a2aaf6c    0072be03               ld t3, 7(t0)
        ;; v51 <- LoadUntagged(v49, 8) T{*?}
0x7f8f8a2aaf70    007e3283               ld t0, 7(t3)
        ;; v54 <- LoadIndexed(v51, v53) T{_Double}
0x7f8f8a2aaf74    0042b007               fld ft0, 4(t0)
...
        ;; ParallelMove
0x7f8f8a2ab0de    22000553               fmv.d fa0, ft0

The double is incorrectly loaded from offset 4 instead of offset 1.

It looks like the relevant information is gone by time CopyFromCompoundToStack runs. Even its caller FfiCallConvertCompoundArgumentToNative has only a MultipleNativeLocation that knows the eventual destination is a 8-byte cpu register and a 8-byte fpu register, but doesn't seem to have any description of the struct fields these values are meant to come from.

@vsmenon vsmenon added the area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. label Mar 23, 2022
copybara-service bot pushed a commit that referenced this issue Mar 23, 2022
…time calls.

TEST=ci
Bug: #48645
Change-Id: I3454fa695e98c9bf2de9d32fc8b0f1187281c3d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/238301
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
@sstrickl
Copy link
Contributor

sstrickl commented Aug 23, 2022

As expected re: Ryan's note in the gardening log for yesterday, we saw the following failures on dartkp-linux-release-riscv64-qemu:

ffi_2/function_callbacks_structs_by_value_generated_test/0 RuntimeError (expected Pass)
ffi_2/function_callbacks_structs_by_value_generated_test/1 RuntimeError (expected Pass)
ffi_2/function_callbacks_structs_by_value_generated_test/2 RuntimeError (expected Pass)
ffi_2/function_callbacks_structs_by_value_generated_test/3 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_leaf_test/0 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_leaf_test/1 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_leaf_test/2 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_leaf_test/3 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_test/0 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_test/1 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_test/2 RuntimeError (expected Pass)
ffi_2/function_structs_by_value_generated_test/3 RuntimeError (expected Pass)

@dcharkes dcharkes changed the title FFI's CopyFromCompoundToStack and PopFromStackToTypedDataBase confused by struct packing [ffi][riscv] CopyFromCompoundToStack and PopFromStackToTypedDataBase confused by struct packing Dec 8, 2022
@dcharkes
Copy link
Contributor

dcharkes commented Dec 29, 2022

RepsInFfiCall computes how the splitting is done. The assumptions are the following if I remember correctly:

  • The bytes on the stack should be the same as in the typed data, it's the same struct.
  • The TypedData is overapproximated to word-size. For 9 bytes, 12 or 16 bytes are allocated.

These two assumptions enable copying the chunks in the struct on a word-size basis.
The struct fields itself can be ignored while copying, we're just copying a multiple of of bytes.
Only when copying from the TypedData to the stack we must take care not to write the extra bytes, as we might override other arguments on the stack when tightly packed.

edit:

only a MultipleNativeLocation that knows the eventual destination is a 8-byte cpu register and a 8-byte fpu register

Ah, RISC-V might be the first calling convention which splits packed members out over multiple registers in a way that we can't just treat the bytes as bytes. (All other calling conventions pass structs as fully on stack or as a pointer to a memory location) when they have misaligned members.)

Then, this requires a bit more refactoring.

doesn't seem to have any description of the struct fields these values are meant to come from

MultipleNativeLocation has payload_type which is NativeCompoundType. For structs, this is the subtype NativeCompoundType which as the member member_offsets.

copybara-service bot pushed a commit that referenced this issue Sep 8, 2023
…hanges.

Bug: #48645
Change-Id: I3729c7df81ad2089224bf886a8c5345cc857f026
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324764
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
copybara-service bot pushed a commit that referenced this issue Oct 25, 2023
TEST=ffi/*structs_by_value*
Bug: #48645
Change-Id: I28a139aec3370be9799279325717057d7034b341
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332141
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-ffi
Projects
None yet
Development

No branches or pull requests

4 participants