Skip to content

Commit 2005e08

Browse files
authored
Rollup merge of rust-lang#134740 - Flakebi:amdgpu-target, r=workingjubilee
Add amdgpu target Add amdgpu target to rustc and enable the LLVM target. Fix compiling `core` with the amdgpu: The amdgpu backend makes heavy use of different address spaces. This leads to situations, where a pointer in one addrspace needs to be casted to a pointer in a different addrspace. `bitcast` is invalid for this case, `addrspacecast` needs to be used. Fix compilation failures that created bitcasts for such cases by creating pointer casts (which creates an `addrspacecast` under the hood) instead. MCP: rust-lang/compiler-team#823 Tracking issue: rust-lang#135024 Kinda related to the original amdgpu tracking issue rust-lang#51575 (though that one has been closed for a while).
2 parents 134b37c + 56795fb commit 2005e08

16 files changed

+220
-10
lines changed

compiler/rustc_target/src/spec/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,8 @@ supported_targets! {
19081908

19091909
("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
19101910

1911+
("amdgcn-amd-amdhsa", amdgcn_amd_amdhsa),
1912+
19111913
("xtensa-esp32-none-elf", xtensa_esp32_none_elf),
19121914
("xtensa-esp32-espidf", xtensa_esp32_espidf),
19131915
("xtensa-esp32s2-none-elf", xtensa_esp32s2_none_elf),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, Target, TargetOptions};
2+
3+
pub(crate) fn target() -> Target {
4+
Target {
5+
arch: "amdgpu".into(),
6+
data_layout: "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9".into(),
7+
llvm_target: "amdgcn-amd-amdhsa".into(),
8+
metadata: crate::spec::TargetMetadata {
9+
description: Some("AMD GPU".into()),
10+
tier: Some(3),
11+
host_tools: Some(false),
12+
std: Some(false),
13+
},
14+
pointer_width: 64,
15+
16+
options: TargetOptions {
17+
os: "amdhsa".into(),
18+
vendor: "amd".into(),
19+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
20+
linker: Some("rust-lld".into()),
21+
22+
// There are many CPUs, one for each hardware generation.
23+
// Require to set one explicitly as there is no good default.
24+
need_explicit_cpu: true,
25+
26+
max_atomic_width: Some(64),
27+
28+
// Unwinding on GPUs is not useful.
29+
panic_strategy: PanicStrategy::Abort,
30+
31+
// amdgpu backend does not support libcalls.
32+
no_builtins: true,
33+
simd_types_indirect: false,
34+
35+
// Allow `cdylib` crate type.
36+
dynamic_linking: true,
37+
only_cdylib: true,
38+
executables: false,
39+
dll_prefix: "".into(),
40+
dll_suffix: ".elf".into(),
41+
42+
// The LLVM backend does not support stack canaries for this target
43+
supports_stack_protector: false,
44+
45+
// Force LTO, object linking does not yet work with amdgpu.
46+
requires_lto: true,
47+
48+
..Default::default()
49+
},
50+
}
51+
}

config.example.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
# the resulting rustc being unable to compile for the disabled architectures.
109109
#
110110
# To add support for new targets, see https://rustc-dev-guide.rust-lang.org/building/new-target.html.
111-
#targets = "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
111+
#targets = "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
112112

113113
# LLVM experimental targets to build support for. These targets are specified in
114114
# the same format as above, but since these targets are experimental, they are

src/bootstrap/download-ci-llvm-stamp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
Change this file to make users of the `download-ci-llvm` configuration download
22
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
33

4-
Last change is for: https://github.com/rust-lang/rust/pull/129788
4+
Last change is for: https://github.com/rust-lang/rust/pull/134740

src/bootstrap/src/core/build_steps/llvm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ impl Step for Llvm {
331331
let llvm_targets = match &builder.config.llvm_targets {
332332
Some(s) => s,
333333
None => {
334-
"AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
334+
"AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
335335
Sparc;SystemZ;WebAssembly;X86"
336336
}
337337
};

src/doc/rustc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- [\*-apple-watchos](platform-support/apple-watchos.md)
3030
- [\*-apple-visionos](platform-support/apple-visionos.md)
3131
- [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
32+
- [amdgcn-amd-amdhsa](platform-support/amdgcn-amd-amdhsa.md)
3233
- [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
3334
- [arm-none-eabi](platform-support/arm-none-eabi.md)
3435
- [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)

src/doc/rustc/src/platform-support.md

+2
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ target | std | host | notes
272272
`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
273273
`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
274274
[`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian)
275+
[`amdgcn-amd-amdhsa`](platform-support/amdgcn-amd-amdhsa.md) | * | | `-Ctarget-cpu=gfx...` to specify [the AMD GPU] to compile for
275276
[`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers
276277
[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin
277278
[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
@@ -432,3 +433,4 @@ target | std | host | notes
432433
[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3
433434

434435
[runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets
436+
[the AMD GPU]: https://llvm.org/docs/AMDGPUUsage.html#processors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# `amdgcn-amd-amdhsa`
2+
3+
**Tier: 3**
4+
5+
AMD GPU target for compute/HSA (Heterogeneous System Architecture).
6+
7+
## Target maintainers
8+
9+
- [@Flakebi](https://github.com/Flakebi)
10+
11+
## Requirements
12+
13+
AMD GPUs can be targeted via cross-compilation.
14+
Supported GPUs depend on the LLVM version that is used by Rust.
15+
In general, most GPUs starting from gfx7 (Sea Islands/CI) are supported as compilation targets, though older GPUs are not supported by the latest host runtime.
16+
Details about supported GPUs can be found in [LLVM’s documentation] and [ROCm documentation].
17+
18+
Binaries can be loaded by [HIP] or by the HSA runtime implemented in [ROCR-Runtime].
19+
The format of binaries is a linked ELF.
20+
21+
Binaries must be built with no-std.
22+
They can use `core` and `alloc` (`alloc` only if an allocator is supplied).
23+
At least one function needs to use the `"gpu-kernel"` calling convention and should be marked with `no_mangle` for simplicity.
24+
Functions using the `"gpu-kernel"` calling convention are kernel entrypoints and can be used from the host runtime.
25+
26+
## Building the target
27+
28+
The target is included in rustc.
29+
30+
## Building Rust programs
31+
32+
The amdgpu target supports many hardware generations, which need different binaries.
33+
The generations are exposed as different target-cpus in the backend.
34+
As there are many, Rust does not ship pre-compiled libraries for this target.
35+
Therefore, you have to build your own copy of `core` by using `cargo -Zbuild-std=core` or similar.
36+
37+
To build a binary, create a no-std library:
38+
```rust,ignore (platform-specific)
39+
// src/lib.rs
40+
#![feature(abi_gpu_kernel)]
41+
#![no_std]
42+
43+
#[panic_handler]
44+
fn panic(_: &core::panic::PanicInfo) -> ! {
45+
loop {}
46+
}
47+
48+
#[no_mangle]
49+
pub extern "gpu-kernel" fn kernel(/* Arguments */) {
50+
// Code
51+
}
52+
```
53+
54+
Build the library as `cdylib`:
55+
```toml
56+
# Cargo.toml
57+
[lib]
58+
crate-type = ["cdylib"]
59+
60+
[profile.dev]
61+
lto = true # LTO must be explicitly enabled for now
62+
[profile.release]
63+
lto = true
64+
```
65+
66+
The target-cpu must be from the list [supported by LLVM] (or printed with `rustc --target amdgcn-amd-amdhsa --print target-cpus`).
67+
The GPU version on the current system can be found e.g. with [`rocminfo`].
68+
69+
Example `.cargo/config.toml` file to set the target and GPU generation:
70+
```toml
71+
# .cargo/config.toml
72+
[build]
73+
target = "amdgcn-amd-amdhsa"
74+
rustflags = ["-Ctarget-cpu=gfx1100"]
75+
76+
[unstable]
77+
build-std = ["core"] # Optional: "alloc"
78+
```
79+
80+
## Running Rust programs
81+
82+
To run a binary on an AMD GPU, a host runtime is needed.
83+
On Linux and Windows, [HIP] can be used to load and run binaries.
84+
Example code on how to load a compiled binary and run it is available in [ROCm examples].
85+
86+
On Linux, binaries can also run through the HSA runtime as implemented in [ROCR-Runtime].
87+
88+
<!-- Mention an allocator once a suitable one exists for amdgpu -->
89+
90+
<!--
91+
## Testing
92+
93+
Does the target support running binaries, or do binaries have varying
94+
expectations that prevent having a standard way to run them? If users can run
95+
binaries, can they do so in some common emulator, or do they need native
96+
hardware? Does the target support running the Rust testsuite?
97+
98+
-->
99+
100+
## Additional information
101+
102+
More information can be found on the [LLVM page for amdgpu].
103+
104+
[LLVM’s documentation]: https://llvm.org/docs/AMDGPUUsage.html#processors
105+
[ROCm documentation]: https://rocmdocs.amd.com
106+
[HIP]: https://rocm.docs.amd.com/projects/HIP/
107+
[ROCR-Runtime]: https://github.com/ROCm/ROCR-Runtime
108+
[supported by LLVM]: https://llvm.org/docs/AMDGPUUsage.html#processors
109+
[LLVM page for amdgpu]: https://llvm.org/docs/AMDGPUUsage.html
110+
[`rocminfo`]: https://github.com/ROCm/rocminfo
111+
[ROCm examples]: https://github.com/ROCm/rocm-examples/tree/ca8ef5b6f1390176616cd1c18fbc98785cbc73f6/HIP-Basic/module_api

src/tools/build-manifest/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static TARGETS: &[&str] = &[
6767
"aarch64-unknown-none-softfloat",
6868
"aarch64-unknown-redox",
6969
"aarch64-unknown-uefi",
70+
"amdgcn-amd-amdhsa",
7071
"arm64e-apple-darwin",
7172
"arm64e-apple-ios",
7273
"arm64e-apple-tvos",
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ assembly-output: emit-asm
2+
// ignore-tidy-linelength
3+
//@ revisions: amdgcn_amd_amdhsa
4+
//@ [amdgcn_amd_amdhsa] compile-flags: --target amdgcn-amd-amdhsa -Ctarget-cpu=gfx900
5+
//@ [amdgcn_amd_amdhsa] needs-llvm-components: amdgpu
6+
7+
// Sanity-check that each target can produce assembly code.
8+
9+
#![feature(no_core, lang_items)]
10+
#![no_std]
11+
#![no_core]
12+
#![crate_type = "lib"]
13+
14+
#[lang = "sized"]
15+
trait Sized {}
16+
17+
pub fn test() -> u8 {
18+
42
19+
}
20+
21+
// CHECK: .version
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: target requires explicitly specifying a cpu with `-C target-cpu`
2+
3+
error: aborting due to 1 previous error
4+
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//@ revisions: nocpu cpu
2+
//@ no-prefer-dynamic
3+
//@ compile-flags: --crate-type=cdylib --target=amdgcn-amd-amdhsa
4+
//@ needs-llvm-components: amdgpu
5+
//@ needs-rust-lld
6+
//@[nocpu] error-pattern: target requires explicitly specifying a cpu
7+
//@[nocpu] build-fail
8+
//@[cpu] compile-flags: -Ctarget-cpu=gfx900
9+
//@[cpu] build-pass
10+
11+
#![feature(no_core, lang_items)]
12+
#![no_core]
13+
14+
#[lang="sized"]
15+
trait Sized {}
16+
17+
pub fn foo() {}

tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ warning: unexpected `cfg` condition value: `value`
1414
LL | #[cfg(target_vendor = "value")]
1515
| ^^^^^^^^^^^^^^^^^^^^^^^
1616
|
17-
= note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
17+
= note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
1818
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1919

2020
warning: unexpected `cfg` condition name: `feature`

tests/ui/check-cfg/exhaustive-names-values.feature.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value`
1515
LL | #[cfg(target_vendor = "value")]
1616
| ^^^^^^^^^^^^^^^^^^^^^^^
1717
|
18-
= note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
18+
= note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
1919
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
2020

2121
warning: unexpected `cfg` condition value: `unk`

tests/ui/check-cfg/exhaustive-names-values.full.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ warning: unexpected `cfg` condition value: `value`
1515
LL | #[cfg(target_vendor = "value")]
1616
| ^^^^^^^^^^^^^^^^^^^^^^^
1717
|
18-
= note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
18+
= note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
1919
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
2020

2121
warning: unexpected `cfg` condition value: `unk`

tests/ui/check-cfg/well-known-values.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
138138
LL | target_arch = "_UNEXPECTED_VALUE",
139139
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
140140
|
141-
= note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
141+
= note: expected values for `target_arch` are: `aarch64`, `amdgpu`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`, and `xtensa`
142142
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
143143

144144
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -201,7 +201,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
201201
LL | target_os = "_UNEXPECTED_VALUE",
202202
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
203203
|
204-
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
204+
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
205205
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
206206

207207
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -230,7 +230,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
230230
LL | target_vendor = "_UNEXPECTED_VALUE",
231231
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
232232
|
233-
= note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
233+
= note: expected values for `target_vendor` are: `amd`, `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `mti`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, and `wrs`
234234
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
235235

236236
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -274,7 +274,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
274274
| |
275275
| help: there is a expected value with a similar name: `"linux"`
276276
|
277-
= note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
277+
= note: expected values for `target_os` are: `aix`, `amdhsa`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
278278
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
279279

280280
warning: 28 warnings emitted

0 commit comments

Comments
 (0)