Skip to content

Commit 75029dc

Browse files
authored
Rollup merge of rust-lang#135047 - Flakebi:amdgpu-kernel-cc, r=workingjubilee
Add gpu-kernel calling convention The amdgpu-kernel calling convention was reverted in commit f6b21e9 (rust-lang#120495 and rust-lang/rust-analyzer#16463) due to inactivity in the amdgpu target. Introduce a `gpu-kernel` calling convention that translates to `ptx_kernel` or `amdgpu_kernel`, depending on the target that rust compiles for. Tracking issue: rust-lang#135467 amdgpu target tracking issue: rust-lang#135024
2 parents 603fdb9 + 68b2639 commit 75029dc

File tree

29 files changed

+440
-175
lines changed

29 files changed

+440
-175
lines changed

compiler/rustc_abi/src/extern_abi/mod.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ pub enum ExternAbi {
4545
PtxKernel,
4646
Msp430Interrupt,
4747
X86Interrupt,
48+
/// An entry-point function called by the GPU's host
49+
// FIXME: should not be callable from Rust on GPU targets, is for host's use only
50+
GpuKernel,
4851
EfiApi,
4952
AvrInterrupt,
5053
AvrNonBlockingInterrupt,
@@ -122,6 +125,7 @@ const AbiDatas: &[AbiData] = &[
122125
AbiData { abi: Abi::PtxKernel, name: "ptx-kernel" },
123126
AbiData { abi: Abi::Msp430Interrupt, name: "msp430-interrupt" },
124127
AbiData { abi: Abi::X86Interrupt, name: "x86-interrupt" },
128+
AbiData { abi: Abi::GpuKernel, name: "gpu-kernel" },
125129
AbiData { abi: Abi::EfiApi, name: "efiapi" },
126130
AbiData { abi: Abi::AvrInterrupt, name: "avr-interrupt" },
127131
AbiData { abi: Abi::AvrNonBlockingInterrupt, name: "avr-non-blocking-interrupt" },
@@ -239,6 +243,10 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
239243
feature: sym::abi_x86_interrupt,
240244
explain: "x86-interrupt ABI is experimental and subject to change",
241245
}),
246+
"gpu-kernel" => Err(AbiDisabled::Unstable {
247+
feature: sym::abi_gpu_kernel,
248+
explain: "gpu-kernel ABI is experimental and subject to change",
249+
}),
242250
"avr-interrupt" | "avr-non-blocking-interrupt" => Err(AbiDisabled::Unstable {
243251
feature: sym::abi_avr_interrupt,
244252
explain: "avr-interrupt and avr-non-blocking-interrupt ABIs are experimental and subject to change",
@@ -293,20 +301,21 @@ impl Abi {
293301
PtxKernel => 19,
294302
Msp430Interrupt => 20,
295303
X86Interrupt => 21,
296-
EfiApi => 22,
297-
AvrInterrupt => 23,
298-
AvrNonBlockingInterrupt => 24,
299-
CCmseNonSecureCall => 25,
300-
CCmseNonSecureEntry => 26,
304+
GpuKernel => 22,
305+
EfiApi => 23,
306+
AvrInterrupt => 24,
307+
AvrNonBlockingInterrupt => 25,
308+
CCmseNonSecureCall => 26,
309+
CCmseNonSecureEntry => 27,
301310
// Cross-platform ABIs
302-
System { unwind: false } => 27,
303-
System { unwind: true } => 28,
304-
RustIntrinsic => 29,
305-
RustCall => 30,
306-
Unadjusted => 31,
307-
RustCold => 32,
308-
RiscvInterruptM => 33,
309-
RiscvInterruptS => 34,
311+
System { unwind: false } => 28,
312+
System { unwind: true } => 29,
313+
RustIntrinsic => 30,
314+
RustCall => 31,
315+
Unadjusted => 32,
316+
RustCold => 33,
317+
RiscvInterruptM => 34,
318+
RiscvInterruptS => 35,
310319
};
311320
debug_assert!(
312321
AbiDatas

compiler/rustc_codegen_cranelift/src/abi/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ pub(crate) fn conv_to_call_conv(sess: &Session, c: Conv, default_call_conv: Call
6565
sess.dcx().fatal("C-cmse-nonsecure-entry call conv is not yet implemented");
6666
}
6767

68-
Conv::Msp430Intr | Conv::PtxKernel | Conv::AvrInterrupt | Conv::AvrNonBlockingInterrupt => {
68+
Conv::Msp430Intr
69+
| Conv::PtxKernel
70+
| Conv::GpuKernel
71+
| Conv::AvrInterrupt
72+
| Conv::AvrNonBlockingInterrupt => {
6973
unreachable!("tried to use {c:?} call conv which only exists on an unsupported target");
7074
}
7175
}

compiler/rustc_codegen_llvm/src/abi.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Borrow;
12
use std::cmp;
23

34
use libc::c_uint;
@@ -312,7 +313,7 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
312313
pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
313314
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
314315
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
315-
fn llvm_cconv(&self) -> llvm::CallConv;
316+
fn llvm_cconv(&self, cx: &CodegenCx<'ll, 'tcx>) -> llvm::CallConv;
316317

317318
/// Apply attributes to a function declaration/definition.
318319
fn apply_attrs_llfn(
@@ -404,8 +405,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
404405
cx.type_ptr_ext(cx.data_layout().instruction_address_space)
405406
}
406407

407-
fn llvm_cconv(&self) -> llvm::CallConv {
408-
self.conv.into()
408+
fn llvm_cconv(&self, cx: &CodegenCx<'ll, 'tcx>) -> llvm::CallConv {
409+
llvm::CallConv::from_conv(self.conv, cx.tcx.sess.target.arch.borrow())
409410
}
410411

411412
fn apply_attrs_llfn(
@@ -617,7 +618,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
617618
}
618619
}
619620

620-
let cconv = self.llvm_cconv();
621+
let cconv = self.llvm_cconv(&bx.cx);
621622
if cconv != llvm::CCallConv {
622623
llvm::SetInstructionCallConv(callsite, cconv);
623624
}
@@ -655,8 +656,8 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
655656
}
656657
}
657658

658-
impl From<Conv> for llvm::CallConv {
659-
fn from(conv: Conv) -> Self {
659+
impl llvm::CallConv {
660+
pub fn from_conv(conv: Conv, arch: &str) -> Self {
660661
match conv {
661662
Conv::C
662663
| Conv::Rust
@@ -666,6 +667,15 @@ impl From<Conv> for llvm::CallConv {
666667
Conv::Cold => llvm::ColdCallConv,
667668
Conv::PreserveMost => llvm::PreserveMost,
668669
Conv::PreserveAll => llvm::PreserveAll,
670+
Conv::GpuKernel => {
671+
if arch == "amdgpu" {
672+
llvm::AmdgpuKernel
673+
} else if arch == "nvptx64" {
674+
llvm::PtxKernel
675+
} else {
676+
panic!("Architecture {arch} does not support GpuKernel calling convention");
677+
}
678+
}
669679
Conv::AvrInterrupt => llvm::AvrInterrupt,
670680
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
671681
Conv::ArmAapcs => llvm::ArmAapcsCallConv,

compiler/rustc_codegen_llvm/src/context.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,10 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
741741
if self.get_declared_value(entry_name).is_none() {
742742
Some(self.declare_entry_fn(
743743
entry_name,
744-
self.sess().target.entry_abi.into(),
744+
llvm::CallConv::from_conv(
745+
self.sess().target.entry_abi,
746+
self.sess().target.arch.borrow(),
747+
),
745748
llvm::UnnamedAddr::Global,
746749
fn_type,
747750
))

compiler/rustc_codegen_llvm/src/declare.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
125125
let llfn = declare_raw_fn(
126126
self,
127127
name,
128-
fn_abi.llvm_cconv(),
128+
fn_abi.llvm_cconv(self),
129129
llvm::UnnamedAddr::Global,
130130
llvm::Visibility::Default,
131131
fn_abi.llvm_type(self),

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ pub enum CallConv {
120120
X86_Intr = 83,
121121
AvrNonBlockingInterrupt = 84,
122122
AvrInterrupt = 85,
123+
AmdgpuKernel = 91,
123124
}
124125

125126
/// Must match the layout of `LLVMLinkage`.

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,8 @@ declare_features! (
361361
(unstable, abi_avr_interrupt, "1.45.0", Some(69664)),
362362
/// Allows `extern "C-cmse-nonsecure-call" fn()`.
363363
(unstable, abi_c_cmse_nonsecure_call, "1.51.0", Some(81391)),
364+
/// Allows `extern "gpu-kernel" fn()`.
365+
(unstable, abi_gpu_kernel, "CURRENT_RUSTC_VERSION", Some(135467)),
364366
/// Allows `extern "msp430-interrupt" fn()`.
365367
(unstable, abi_msp430_interrupt, "1.16.0", Some(38487)),
366368
/// Allows `extern "ptx-*" fn()`.

compiler/rustc_middle/src/ty/layout.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
12411241
PtxKernel
12421242
| Msp430Interrupt
12431243
| X86Interrupt
1244+
| GpuKernel
12441245
| EfiApi
12451246
| AvrInterrupt
12461247
| AvrNonBlockingInterrupt

compiler/rustc_smir/src/rustc_internal/internal.rs

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ impl RustcInternal for Abi {
472472
Abi::PtxKernel => rustc_abi::ExternAbi::PtxKernel,
473473
Abi::Msp430Interrupt => rustc_abi::ExternAbi::Msp430Interrupt,
474474
Abi::X86Interrupt => rustc_abi::ExternAbi::X86Interrupt,
475+
Abi::GpuKernel => rustc_abi::ExternAbi::GpuKernel,
475476
Abi::EfiApi => rustc_abi::ExternAbi::EfiApi,
476477
Abi::AvrInterrupt => rustc_abi::ExternAbi::AvrInterrupt,
477478
Abi::AvrNonBlockingInterrupt => rustc_abi::ExternAbi::AvrNonBlockingInterrupt,

compiler/rustc_smir/src/rustc_smir/convert/abi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ impl<'tcx> Stable<'tcx> for callconv::Conv {
113113
Conv::X86VectorCall => CallConvention::X86VectorCall,
114114
Conv::X86_64SysV => CallConvention::X86_64SysV,
115115
Conv::X86_64Win64 => CallConvention::X86_64Win64,
116+
Conv::GpuKernel => CallConvention::GpuKernel,
116117
Conv::AvrInterrupt => CallConvention::AvrInterrupt,
117118
Conv::AvrNonBlockingInterrupt => CallConvention::AvrNonBlockingInterrupt,
118119
Conv::RiscvInterrupt { .. } => CallConvention::RiscvInterrupt,

compiler/rustc_smir/src/rustc_smir/convert/ty.rs

+1
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
911911
ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
912912
ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
913913
ExternAbi::PtxKernel => Abi::PtxKernel,
914+
ExternAbi::GpuKernel => Abi::GpuKernel,
914915
ExternAbi::Msp430Interrupt => Abi::Msp430Interrupt,
915916
ExternAbi::X86Interrupt => Abi::X86Interrupt,
916917
ExternAbi::EfiApi => Abi::EfiApi,

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ symbols! {
379379
abi_avr_interrupt,
380380
abi_c_cmse_nonsecure_call,
381381
abi_efiapi,
382+
abi_gpu_kernel,
382383
abi_msp430_interrupt,
383384
abi_ptx,
384385
abi_riscv_interrupt,

compiler/rustc_target/src/callconv/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ pub enum Conv {
546546

547547
PtxKernel,
548548

549+
GpuKernel,
550+
549551
X86Fastcall,
550552
X86Intr,
551553
X86Stdcall,
@@ -865,6 +867,7 @@ impl FromStr for Conv {
865867
"X86VectorCall" => Ok(Conv::X86VectorCall),
866868
"X86_64SysV" => Ok(Conv::X86_64SysV),
867869
"X86_64Win64" => Ok(Conv::X86_64Win64),
870+
"GpuKernel" => Ok(Conv::GpuKernel),
868871
"AvrInterrupt" => Ok(Conv::AvrInterrupt),
869872
"AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
870873
"RiscvInterrupt(machine)" => {

compiler/rustc_target/src/json.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ impl ToJson for crate::abi::call::Conv {
113113
Self::X86VectorCall => "X86VectorCall",
114114
Self::X86_64SysV => "X86_64SysV",
115115
Self::X86_64Win64 => "X86_64Win64",
116+
Self::GpuKernel => "GpuKernel",
116117
Self::AvrInterrupt => "AvrInterrupt",
117118
Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
118119
Self::RiscvInterrupt { kind } => {

compiler/rustc_target/src/spec/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2860,6 +2860,7 @@ impl Target {
28602860
}
28612861
Win64 { .. } | SysV64 { .. } => self.arch == "x86_64",
28622862
PtxKernel => self.arch == "nvptx64",
2863+
GpuKernel => ["amdgpu", "nvptx64"].contains(&&self.arch[..]),
28632864
Msp430Interrupt => self.arch == "msp430",
28642865
RiscvInterruptM | RiscvInterruptS => ["riscv32", "riscv64"].contains(&&self.arch[..]),
28652866
AvrInterrupt | AvrNonBlockingInterrupt => self.arch == "avr",

compiler/rustc_ty_utils/src/abi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv
293293
PtxKernel => Conv::PtxKernel,
294294
Msp430Interrupt => Conv::Msp430Intr,
295295
X86Interrupt => Conv::X86Intr,
296+
GpuKernel => Conv::GpuKernel,
296297
AvrInterrupt => Conv::AvrInterrupt,
297298
AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt,
298299
RiscvInterruptM => Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine },

compiler/stable_mir/src/abi.rs

+2
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ pub enum CallConvention {
442442

443443
PtxKernel,
444444

445+
GpuKernel,
446+
445447
X86Fastcall,
446448
X86Intr,
447449
X86Stdcall,

compiler/stable_mir/src/ty.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,7 @@ pub enum Abi {
10771077
PtxKernel,
10781078
Msp430Interrupt,
10791079
X86Interrupt,
1080+
GpuKernel,
10801081
EfiApi,
10811082
AvrInterrupt,
10821083
AvrNonBlockingInterrupt,

tests/codegen/gpu-kernel-abi.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Checks that the gpu-kernel calling convention correctly translates to LLVM calling conventions.
2+
3+
//@ revisions: amdgpu nvptx
4+
//@ [amdgpu] compile-flags: --crate-type=rlib --target=amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
5+
//@ [amdgpu] needs-llvm-components: amdgpu
6+
// amdgpu target is not yet merged
7+
//@ [amdgpu] should-fail
8+
//@ [nvptx] compile-flags: --crate-type=rlib --target=nvptx64-nvidia-cuda
9+
//@ [nvptx] needs-llvm-components: nvptx
10+
#![feature(no_core, lang_items, abi_gpu_kernel)]
11+
#![no_core]
12+
13+
#[lang = "sized"]
14+
trait Sized {}
15+
#[lang = "freeze"]
16+
trait Freeze {}
17+
#[lang = "copy"]
18+
trait Copy {}
19+
20+
// amdgpu: define amdgpu_kernel void @fun(i32
21+
// nvptx: define ptx_kernel void @fun(i32
22+
#[no_mangle]
23+
pub extern "gpu-kernel" fn fun(_: i32) {}

0 commit comments

Comments
 (0)