Lower x86-interrupt byval first argument as pointer#893
Conversation
…st argument GCC's `interrupt` attribute requires the first parameter of an `x86-interrupt` function to be a pointer. When it is not (for example a scalar `i64` or a by-value struct), libgccjit aborts codegen with an internal error and leaves no object file behind, which then surfaces as a confusing linker failure. Detect that case and emit a clear diagnostic from `predefine_fn`, while dropping the calling-convention attribute in `declare_fn` so libgccjit does not abort. The detection runs on the already-lowered GCC argument types, so `declare_fn` reuses the single ABI lowering it already performs instead of computing it twice.
Check that an `x86-interrupt` function whose first argument is not a pointer produces a clean compiler error instead of an internal libgccjit error.
|
@antoyo, hi mate! |
|
Sorry for the delay. |
all good! |
What is the warning produced by LLVM? (I don't see it.) One question I have is: is the code in the issue supposed to work correctly, or does Rust also always expect a pointer argument? |
|
yeah, i checked this again and i think the pr description is a bit off here. i don't see an llvm warning either. with rustc 1.96.0 / llvm 22.1.2, the testcase compiles cleanly for me. dumping the llvm ir shows rustc lowers the first arg to a pointer/byval param: define x86_intrcc void ... (ptr byval([8 x i8]) align 8 %_a) so imo rust is not expecting the rust-level arg itself to be a pointer. it accepts something like i64 or a by-value struct, then lowers it into the pointer shape the backend wants. tbh i think the better fix is to mirror that lowering in the gcc backend, instead of rejecting the source signature or dropping the interrupt attr. i'll update the pr in that direction. |
Fixes #833
An
extern "x86-interrupt"function can have a by-value first Rust argument, such asi64or a by-value struct. rustc's LLVM backend lowers that first byval stack argument to a pointer-shaped backend parameter forx86_intrcc.GCC's
interruptattribute expects the same pointer-shaped first parameter. Without that lowering, libgccjit reportsinterrupt service routine should have a pointer as the first argumentand does not write an object file, which then shows up as a confusing follow-up archive/object error.Mirror rustc's lowering in the GCC backend for the first
x86-interruptbyval argument, while keeping the interrupt attribute. This avoids the libgccjit abort without rejecting a Rust signature that rustc accepts.The regression test covers scalar and by-value struct first arguments.