Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bootstrap.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
# the resulting rustc being unable to compile for the disabled architectures.
#
# To add support for new targets, see https://rustc-dev-guide.rust-lang.org/building/new-target.html.
#llvm.targets = "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
#llvm.targets = "AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SPIRV;SystemZ;WebAssembly;X86"

# LLVM experimental targets to build support for. These targets are specified in
# the same format as above, but since these targets are experimental, they are
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const OPTIONAL_COMPONENTS: &[&str] = &[
"csky",
"mips",
"powerpc",
"spirv",
"systemz",
"webassembly",
"msp430",
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,13 @@ pub fn initialize_available_targets() {
LLVMInitializePowerPCAsmPrinter,
LLVMInitializePowerPCAsmParser
);
init_target!(
llvm_component = "spirv",
LLVMInitializeSPIRVTargetInfo,
LLVMInitializeSPIRVTarget,
LLVMInitializeSPIRVTargetMC,
LLVMInitializeSPIRVAsmPrinter
);
init_target!(
llvm_component = "systemz",
LLVMInitializeSystemZTargetInfo,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mod riscv;
mod s390x;
mod sparc;
mod sparc64;
mod spirv;
mod wasm;
mod x86;
mod x86_64;
Expand Down Expand Up @@ -703,7 +704,8 @@ impl<'a, Ty> FnAbi<'a, Ty> {
Arch::RiscV32 | Arch::RiscV64 => riscv::compute_abi_info(cx, self),
Arch::Wasm32 | Arch::Wasm64 => wasm::compute_abi_info(cx, self),
Arch::Bpf => bpf::compute_abi_info(cx, self),
arch @ (Arch::PowerPC64LE | Arch::SpirV | Arch::Other(_)) => {
Arch::SpirV => spirv::compute_abi_info(cx, self),
arch @ (Arch::PowerPC64LE | Arch::Other(_)) => {
panic!("no lowering implemented for {arch}")
}
}
Expand Down
40 changes: 40 additions & 0 deletions compiler/rustc_target/src/callconv/spirv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use rustc_abi::{HasDataLayout, TyAbiInterface};

use crate::callconv::{ArgAbi, FnAbi};

fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
ret.extend_integer_width_to(32);
}

fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
arg.make_indirect();
return;
}
arg.extend_integer_width_to(32);
}

pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if !fn_abi.ret.is_ignore() {
classify_ret(cx, &mut fn_abi.ret);
}

for arg in fn_abi.args.iter_mut() {
if arg.is_ignore() {
continue;
}
classify_arg(cx, arg);
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,8 @@ supported_targets! {

("amdgcn-amd-amdhsa", amdgcn_amd_amdhsa),

("spirv-unknown-vulkan1.3", spirv_unknown_vulkan1_3),

("xtensa-esp32-none-elf", xtensa_esp32_none_elf),
("xtensa-esp32-espidf", xtensa_esp32_espidf),
("xtensa-esp32s2-none-elf", xtensa_esp32s2_none_elf),
Expand Down Expand Up @@ -1990,6 +1992,7 @@ crate::target_spec_enum! {
VexOs = "vexos",
VisionOs = "visionos",
Vita = "vita",
Vulkan = "vulkan",
VxWorks = "vxworks",
Wasi = "wasi",
WatchOs = "watchos",
Expand Down
37 changes: 37 additions & 0 deletions compiler/rustc_target/src/spec/targets/spirv_unknown_vulkan1_3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use crate::spec::{
Arch, LinkerFlavor, Os, PanicStrategy, Target, TargetMetadata, TargetOptions
};

pub(crate) fn target() -> Target {
Target {
llvm_target: "spirv-unknown-vulkan1.3".into(),
metadata: TargetMetadata {
description: Some("Vulkan 1.3".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(false),
},
pointer_width: 64,
data_layout: "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G10".into(),
arch: Arch::SpirV,
options: TargetOptions {
os: Os::Vulkan,
vendor: "unknown".into(),
linker_flavor: LinkerFlavor::Llbc,
max_atomic_width: Some(32),
panic_strategy: PanicStrategy::Abort,
// Allow `cdylib` crate type.
dynamic_linking: true,
obj_is_bitcode: true,
only_cdylib: true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should also set is_like_gpu: true?

dll_prefix: "".into(),
dll_suffix: ".spvt".into(),
// The LLVM backend does not support stack canaries for this target
supports_stack_protector: false,

// Static initializers must not have cycles on this target
static_initializer_must_be_acyclic: true,
..Default::default()
},
}
}
3 changes: 2 additions & 1 deletion library/compiler-builtins/compiler-builtins/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ fn main() {
|| (target.triple.contains("sgx") && target.triple.contains("fortanix"))
|| target.triple.contains("-none")
|| target.triple.contains("nvptx")
|| target.triple.contains("spirv")
|| target.triple.contains("uefi")
|| target.triple.contains("xous")
{
Expand Down Expand Up @@ -67,7 +68,7 @@ fn main() {
// Don't use a C compiler for these targets:
//
// * nvptx - everything is bitcode, not compatible with mixed C/Rust
if !target.arch.contains("nvptx") {
if !target.arch.contains("nvptx") && !target.arch.contains("spirv") {
#[cfg(feature = "c")]
c::compile(&llvm_target, &target);
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/ffi/va_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ impl<'f> Drop for VaList<'f> {

// Checks (via an assert in `compiler/rustc_ty_utils/src/abi.rs`) that the C ABI for the current
// target correctly implements `rustc_pass_indirectly_in_non_rustic_abis`.
#[cfg(not(target_arch = "spirv"))]
const _: () = {
#[repr(C)]
#[rustc_pass_indirectly_in_non_rustic_abis]
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ impl Step for Llvm {
Some(s) => s,
None => {
"AArch64;AMDGPU;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
Sparc;SystemZ;WebAssembly;X86"
Sparc;SPIRV;SystemZ;WebAssembly;X86"
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/src/core/builder/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ impl Cargo {
fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
let target = self.target;
let compiler = self.compiler;

if target.contains("spirv") {
return self;
}

// Dealing with rpath here is a little special, so let's go into some
// detail. First off, `-rpath` is a linker option on Unix platforms
Expand Down
7 changes: 6 additions & 1 deletion src/bootstrap/src/core/sanity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct Finder {
const STAGE0_MISSING_TARGETS: &[&str] = &[
// just a dummy comment so the list doesn't get onelined
"riscv64im-unknown-none-elf",
"spirv-unknown-vulkan1.3",
];

/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
Expand Down Expand Up @@ -244,6 +245,10 @@ than building it.
continue;
}

if target.contains("spirv") {
continue;
}

// skip check for cross-targets
if skip_target_sanity && target != &build.host_target {
continue;
Expand Down Expand Up @@ -352,7 +357,7 @@ than building it.
}
}

if (target.contains("-none-") || target.contains("nvptx"))
if (target.contains("-none-") || target.contains("nvptx") || target.contains("spirv"))
&& build.no_std(*target) == Some(false)
{
panic!("All the *-none-* and nvptx* targets are no-std targets")
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/src/utils/cc_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ pub fn fill_target_compiler(build: &mut Build, target: TargetSelection) {
cfg.compiler(cc);
}

if target.contains("spirv") {
return;
}

let compiler = cfg.get_compiler();
let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) {
ar
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/src/utils/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ pub fn use_host_linker(target: TargetSelection) -> bool {
!(target.contains("emscripten")
|| target.contains("wasm32")
|| target.contains("nvptx")
|| target.contains("spirv")
|| target.contains("fortanix")
|| target.contains("fuchsia")
|| target.contains("bpf")
Expand Down
3 changes: 2 additions & 1 deletion src/build_helper/src/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
pub fn target_supports_std(target_tuple: &str) -> bool {
!(target_tuple.contains("-none")
|| target_tuple.contains("nvptx")
|| target_tuple.contains("switch"))
|| target_tuple.contains("switch")
|| target_tuple.contains("spirv"))
}
29 changes: 29 additions & 0 deletions tests/assembly-llvm/targets/targets-spirv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// @ add-minicore
//@ assembly-output: emit-asm
//@ revisions: spirv_unknown_vulkan1_3
//@ [spirv_unknown_vulkan1_3] compile-flags: --target spirv-unknown-vulkan1.3
//@ [spirv_unknown_vulkan1_3] needs-llvm-components: spirv

// Sanity-check that each target can produce assembly code.

#![feature(no_core, lang_items, never_type)]
#![no_std]
// #![no_core]
#![crate_type = "lib"]

pub enum A {
Foo(u8),
Bar(u32),
}

// extern crate minicore;
// use minicore::*;
#[unsafe(no_mangle)]
pub fn test(x: &mut A) -> u8 {
match x {
A::Foo(x) => *x,
A::Bar(b) => *b as u8 + 2,
}
}

// CHECK: what
Loading