Skip to content

Commit f456ebf

Browse files
committed
Merge branch 'fix_ptx_kernel_abi' into HEAD
2 parents e1f75dd + 0a44f67 commit f456ebf

File tree

3 files changed

+49
-44
lines changed

3 files changed

+49
-44
lines changed

compiler/rustc_target/src/callconv/nvptx64.rs

+30-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::{ArgAttribute, ArgAttributes, ArgExtension, CastTarget};
2-
use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform};
2+
use crate::abi::call::{ArgAbi, FnAbi, Reg, Size, Uniform};
33
use crate::abi::{HasDataLayout, TyAbiInterface};
44

55
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
@@ -53,21 +53,37 @@ where
5353
Ty: TyAbiInterface<'a, C> + Copy,
5454
C: HasDataLayout,
5555
{
56-
if matches!(arg.mode, PassMode::Pair(..)) && (arg.layout.is_adt() || arg.layout.is_tuple()) {
57-
let align_bytes = arg.layout.align.abi.bytes();
56+
match arg.mode {
57+
super::PassMode::Ignore | super::PassMode::Direct(_) => return,
58+
super::PassMode::Pair(_, _) => {}
59+
super::PassMode::Cast { .. } => unreachable!(),
60+
super::PassMode::Indirect { .. } => {}
61+
}
62+
63+
// FIXME only allow structs and wide pointers here
64+
// panic!(
65+
// "`extern \"ptx-kernel\"` doesn't allow passing types other than primitives and structs"
66+
// );
67+
68+
let align_bytes = arg.layout.align.abi.bytes();
5869

59-
let unit = match align_bytes {
60-
1 => Reg::i8(),
61-
2 => Reg::i16(),
62-
4 => Reg::i32(),
63-
8 => Reg::i64(),
64-
16 => Reg::i128(),
65-
_ => unreachable!("Align is given as power of 2 no larger than 16 bytes"),
66-
};
67-
arg.cast_to(Uniform::new(unit, Size::from_bytes(2 * align_bytes)));
70+
let unit = match align_bytes {
71+
1 => Reg::i8(),
72+
2 => Reg::i16(),
73+
4 => Reg::i32(),
74+
8 => Reg::i64(),
75+
16 => Reg::i128(),
76+
_ => unreachable!("Align is given as power of 2 no larger than 16 bytes"),
77+
};
78+
if arg.layout.size.bytes() / align_bytes == 1 {
79+
// Make sure we pass the struct as array at the LLVM IR level and not as a single integer.
80+
arg.cast_to(CastTarget {
81+
prefix: [Some(unit), None, None, None, None, None, None, None],
82+
rest: Uniform::new(unit, Size::ZERO),
83+
attrs: ArgAttributes::new(),
84+
});
6885
} else {
69-
// FIXME: find a better way to do this. See https://github.com/rust-lang/rust/issues/117271.
70-
arg.make_direct_deprecated();
86+
arg.cast_to(Uniform::new(unit, arg.layout.size));
7187
}
7288
}
7389

compiler/rustc_ty_utils/src/abi.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -473,20 +473,25 @@ fn fn_abi_sanity_check<'tcx>(
473473
// This really shouldn't happen even for sized aggregates, since
474474
// `immediate_llvm_type` will use `layout.fields` to turn this Rust type into an
475475
// LLVM type. This means all sorts of Rust type details leak into the ABI.
476-
// However wasm sadly *does* currently use this mode so we have to allow it --
477-
// but we absolutely shouldn't let any more targets do that.
478-
// (Also see <https://github.com/rust-lang/rust/issues/115666>.)
476+
// However wasm sadly *does* currently use this mode for it's "C" ABI so we
477+
// have to allow it -- but we absolutely shouldn't let any more targets do
478+
// that. (Also see <https://github.com/rust-lang/rust/issues/115666>.)
479479
//
480-
// The unstable abi `PtxKernel` also uses Direct for now.
481-
// It needs to switch to something else before stabilization can happen.
482-
// (See issue: https://github.com/rust-lang/rust/issues/117271)
483-
assert!(
484-
matches!(&*tcx.sess.target.arch, "wasm32" | "wasm64")
485-
|| matches!(spec_abi, ExternAbi::PtxKernel | ExternAbi::Unadjusted),
486-
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\" and \"ptx-kernel\" functions and on wasm\n\
487-
Problematic type: {:#?}",
488-
arg.layout,
489-
);
480+
// The unadjusted ABI also uses Direct for all args and is ill-specified,
481+
// but unfortunately we need it for calling certain LLVM intrinsics.
482+
483+
match spec_abi {
484+
ExternAbi::Unadjusted => {}
485+
ExternAbi::C { unwind: _ }
486+
if matches!(&*tcx.sess.target.arch, "wasm32" | "wasm64") => {}
487+
_ => {
488+
panic!(
489+
"`PassMode::Direct` for aggregates only allowed for \"unadjusted\" functions and on wasm\n\
490+
Problematic type: {:#?}",
491+
arg.layout,
492+
);
493+
}
494+
}
490495
}
491496
}
492497
}

tests/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs

+1-17
Original file line numberDiff line numberDiff line change
@@ -242,22 +242,6 @@ pub unsafe extern "ptx-kernel" fn f_float_array_arg(_a: [f32; 5]) {}
242242
//pub unsafe extern "ptx-kernel" fn f_u128_array_arg(_a: [u128; 5]) {}
243243

244244
// CHECK: .visible .entry f_u32_slice_arg(
245-
// CHECK: .param .u64 f_u32_slice_arg_param_0
246-
// CHECK: .param .u64 f_u32_slice_arg_param_1
245+
// CHECK: .param .align 8 .b8 f_u32_slice_arg_param_0[16]
247246
#[no_mangle]
248247
pub unsafe extern "ptx-kernel" fn f_u32_slice_arg(_a: &[u32]) {}
249-
250-
// CHECK: .visible .entry f_tuple_u8_u8_arg(
251-
// CHECK: .param .align 1 .b8 f_tuple_u8_u8_arg_param_0[2]
252-
#[no_mangle]
253-
pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_arg(_a: (u8, u8)) {}
254-
255-
// CHECK: .visible .entry f_tuple_u32_u32_arg(
256-
// CHECK: .param .align 4 .b8 f_tuple_u32_u32_arg_param_0[8]
257-
#[no_mangle]
258-
pub unsafe extern "ptx-kernel" fn f_tuple_u32_u32_arg(_a: (u32, u32)) {}
259-
260-
// CHECK: .visible .entry f_tuple_u8_u8_u32_arg(
261-
// CHECK: .param .align 4 .b8 f_tuple_u8_u8_u32_arg_param_0[8]
262-
#[no_mangle]
263-
pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_u32_arg(_a: (u8, u8, u32)) {}

0 commit comments

Comments
 (0)