Skip to content

Lower x86-interrupt byval first argument as pointer#893

Open
Dnreikronos wants to merge 8 commits into
rust-lang:masterfrom
Dnreikronos:x86-interrupt-non-pointer-first-arg
Open

Lower x86-interrupt byval first argument as pointer#893
Dnreikronos wants to merge 8 commits into
rust-lang:masterfrom
Dnreikronos:x86-interrupt-non-pointer-first-arg

Conversation

@Dnreikronos

@Dnreikronos Dnreikronos commented May 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #833

An extern "x86-interrupt" function can have a by-value first Rust argument, such as i64 or a by-value struct. rustc's LLVM backend lowers that first byval stack argument to a pointer-shaped backend parameter for x86_intrcc.

GCC's interrupt attribute expects the same pointer-shaped first parameter. Without that lowering, libgccjit reports interrupt service routine should have a pointer as the first argument and 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-interrupt byval 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.

…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.
@Dnreikronos

Copy link
Copy Markdown
Contributor Author

@antoyo, hi mate!
can you help me with this, please?

@antoyo

antoyo commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Sorry for the delay.
I'll try to review this in the following days.

@Dnreikronos

Copy link
Copy Markdown
Contributor Author

Sorry for the delay. I'll try to review this in the following days.

all good!
ty!

@antoyo

antoyo commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

LLVM only warns on the same code.

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?

@Dnreikronos

Copy link
Copy Markdown
Contributor Author

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.

@Dnreikronos Dnreikronos changed the title abi: Emit a clean error for non-pointer x86-interrupt first argument Lower x86-interrupt byval first argument as pointer Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

interrupt service routine should have a pointer as the first argument

2 participants