ITADN

Kernel arguments with `#[repr(align(16))]` cause misaligned access / `IllegalAddress`

#361ClosedSnehal-Reddy 创建于 2026-02-10
S
Snehal-Reddycommented
### Summary I encountered runtime `IllegalAddress` errors when passing 16-byte aligned structs (e.g., structs containing `u128` or `#[repr(align(16))]`) by value to CUDA kernels. The root cause is in `rustc_codegen_nvvm/src/abi.rs`. The current logic forces `PassMode::Direct` for all ADTs. However, for the NVPTX target, LLVM often defaults to 8-byte alignment for generic structs passed directly, even if the Rust type requires 16-byte alignment. This results in the Host packing arguments at 16-byte boundaries, but the Device (PTX) reading them at 8-byte boundaries, leading to misaligned reads and crashes. ### Reproduction Case Define a struct with 16-byte alignment and pass it to a kernel: ``` #[repr(C, align(16))] pub struct AlignedStruct { a: u64, b: u64, } #[cuda_std::kernel] pub unsafe fn my_kernel(input: AlignedStruct) { // Accessing input.a or input.b causes IllegalAddress // because the kernel expects 8-byte alignment but the pointer // generated by the driver is 16-byte aligned (or vice versa depending on padding). } ``` ### Issue In `rustc_codegen_nvvm/src/abi.r`s, the function `readjust_fn_abi` currently does this: ``` // Current logic if arg.layout.ty.is_adt() { // ... arg.mode = PassMode::Direct(ArgAttributes::new()); } ``` This generates PTX kernel parameters like `.param .align 8 .b8 input[16]`. However, because the struct contains aligned data, the kernel code may generate vector loads (e.g.,` ld.global.v2.u64` or 128-bit loads) which trap if the address is not 16-byte aligned.
关闭于 2026-02-26 0 条评论