diff --git a/compiler/rustc_target/src/callconv/bpf.rs b/compiler/rustc_target/src/callconv/bpf.rs index f958aeb9bb654..ec5c1c2cf6860 100644 --- a/compiler/rustc_target/src/callconv/bpf.rs +++ b/compiler/rustc_target/src/callconv/bpf.rs @@ -29,3 +29,9 @@ pub(crate) fn compute_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { classify_arg(arg); } } + +pub(crate) fn compute_rust_abi_info(fn_abi: &mut FnAbi<'_, Ty>) { + if !fn_abi.ret.is_ignore() { + classify_ret(&mut fn_abi.ret); + } +} diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index c59af581a1fe4..3f7382ee0e2b5 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -715,6 +715,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { "riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self), "loongarch32" | "loongarch64" => loongarch::compute_rust_abi_info(cx, self), "aarch64" => aarch64::compute_rust_abi_info(cx, self), + "bpf" => bpf::compute_rust_abi_info(self), _ => {} }; diff --git a/tests/codegen-llvm/bpf-abi-indirect-return.rs b/tests/codegen-llvm/bpf-abi-indirect-return.rs new file mode 100644 index 0000000000000..b5787cc83a2b4 --- /dev/null +++ b/tests/codegen-llvm/bpf-abi-indirect-return.rs @@ -0,0 +1,43 @@ +// Checks that results larger than one register are returned indirectly +//@ only-bpf +//@ needs-llvm-components: bpf +//@ compile-flags: --target bpfel-unknown-none + +#![no_std] +#![no_main] + +#[no_mangle] +fn outer(a: u64) -> u64 { + let v = match inner_res(a) { + Ok(v) => v, + Err(()) => 0, + }; + + inner_big(v).a[0] as u64 +} + +// CHECK-LABEL: define {{.*}} @_ZN{{.*}}inner_res{{.*}}E( +// CHECK-SAME: ptr{{[^,]*}}, +// CHECK-SAME: i64{{[^)]*}} +#[inline(never)] +fn inner_res(a: u64) -> Result { + if a == 0 { Err(()) } else { Ok(a + 1) } +} + +struct Big { + a: [u16; 32], + b: u64, +} + +// CHECK-LABEL: define {{.*}} @_ZN{{.*}}inner_big{{.*}}E( +// CHECK-SAME: ptr{{[^,]*}}, +// CHECK-SAME: i64{{[^)]*}} +#[inline(never)] +fn inner_big(a: u64) -> Big { + Big { a: [a as u16; 32], b: 42 } +} + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +}