Skip to content

Commit 1a6a667

Browse files
committed
rustc_target: don't limit SPIR-V inline asm! types to a fixed subset.
1 parent 7d747db commit 1a6a667

File tree

12 files changed

+68
-74
lines changed

12 files changed

+68
-74
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -1396,17 +1396,22 @@ impl<'hir> LoweringContext<'_, 'hir> {
13961396
// features. We check that at least one type is available for
13971397
// the current target.
13981398
let reg_class = reg.reg_class();
1399-
for &(_, feature) in reg_class.supported_types(asm_arch) {
1400-
if let Some(feature) = feature {
1401-
if self.sess.target_features.contains(&Symbol::intern(feature)) {
1402-
required_features.clear();
1403-
break;
1404-
} else {
1405-
required_features.push(feature);
1399+
match reg_class.supported_types(asm_arch) {
1400+
asm::InlineAsmSupportedTypes::Any => {}
1401+
asm::InlineAsmSupportedTypes::OneOf(types) => {
1402+
for &(_, feature) in types {
1403+
if let Some(feature) = feature {
1404+
if self.sess.target_features.contains(&Symbol::intern(feature)) {
1405+
required_features.clear();
1406+
break;
1407+
} else {
1408+
required_features.push(feature);
1409+
}
1410+
} else {
1411+
required_features.clear();
1412+
break;
1413+
}
14061414
}
1407-
} else {
1408-
required_features.clear();
1409-
break;
14101415
}
14111416
}
14121417
// We are sorting primitive strs here and can use unstable sort here

compiler/rustc_codegen_cranelift/src/inline_asm.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ pub(crate) fn codegen_inline_asm<'tcx>(
2828
let mut outputs = Vec::new();
2929

3030
let mut new_slot = |reg_class: InlineAsmRegClass| {
31-
let reg_size = reg_class
32-
.supported_types(InlineAsmArch::X86_64)
33-
.iter()
34-
.map(|(ty, _)| ty.size())
35-
.max()
36-
.unwrap();
31+
let reg_size = match reg_class.supported_types(InlineAsmArch::X86_64) {
32+
InlineAsmSupportedTypes::OneOf(supported_tys) => {
33+
supported_tys.iter().map(|(ty, _)| ty.size()).max().unwrap()
34+
}
35+
_ => unreachable!(),
36+
};
3737
let align = rustc_target::abi::Align::from_bytes(reg_size.bytes()).unwrap();
3838
slot_size = slot_size.align_to(align);
3939
let offset = slot_size;

compiler/rustc_passes/src/intrinsicck.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
1111
use rustc_session::lint;
1212
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
1313
use rustc_target::abi::{Pointer, VariantIdx};
14-
use rustc_target::asm::{InlineAsmRegOrRegClass, InlineAsmType};
14+
use rustc_target::asm::{InlineAsmRegOrRegClass, InlineAsmSupportedTypes, InlineAsmType};
1515
use rustc_target::spec::abi::Abi::RustIntrinsic;
1616

1717
fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
@@ -255,10 +255,18 @@ impl ExprVisitor<'tcx> {
255255
// register class.
256256
let asm_arch = self.tcx.sess.asm_arch.unwrap();
257257
let reg_class = reg.reg_class();
258-
let supported_tys = reg_class.supported_types(asm_arch);
259-
let feature = match supported_tys.iter().find(|&&(t, _)| t == asm_ty) {
260-
Some((_, feature)) => feature,
261-
None => {
258+
let found_supported_ty = match reg_class.supported_types(asm_arch) {
259+
// FIXME(eddyb) consider skipping the "cannot use value of type" error
260+
// above, letting the codegen backend handle non-scalar/vector types.
261+
InlineAsmSupportedTypes::Any => Ok((asm_ty, None)),
262+
263+
InlineAsmSupportedTypes::OneOf(supported_tys) => {
264+
supported_tys.iter().find(|&&(t, _)| t == asm_ty).copied().ok_or(supported_tys)
265+
}
266+
};
267+
let feature = match found_supported_ty {
268+
Ok((_, feature)) => feature,
269+
Err(supported_tys) => {
262270
let msg = &format!("type `{}` cannot be used with this register class", ty);
263271
let mut err = self.tcx.sess.struct_span_err(expr.span, msg);
264272
let supported_tys: Vec<_> =

compiler/rustc_target/src/asm/aarch64.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use rustc_macros::HashStable_Generic;
33
use std::fmt;
44

@@ -50,10 +50,7 @@ impl AArch64InlineAsmRegClass {
5050
}
5151
}
5252

53-
pub fn supported_types(
54-
self,
55-
_arch: InlineAsmArch,
56-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
53+
pub fn supported_types(self, _arch: InlineAsmArch) -> InlineAsmSupportedTypes {
5754
match self {
5855
Self::reg => types! { _: I8, I16, I32, I64, F32, F64; },
5956
Self::vreg | Self::vreg_low16 => types! {

compiler/rustc_target/src/asm/arm.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use crate::spec::Target;
33
use rustc_macros::HashStable_Generic;
44
use std::fmt;
@@ -42,10 +42,7 @@ impl ArmInlineAsmRegClass {
4242
None
4343
}
4444

45-
pub fn supported_types(
46-
self,
47-
_arch: InlineAsmArch,
48-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
45+
pub fn supported_types(self, _arch: InlineAsmArch) -> InlineAsmSupportedTypes {
4946
match self {
5047
Self::reg | Self::reg_thumb => types! { _: I8, I16, I32, F32; },
5148
Self::sreg | Self::sreg_low16 => types! { "vfp2": I32, F32; },

compiler/rustc_target/src/asm/hexagon.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use rustc_macros::HashStable_Generic;
33
use std::fmt;
44

@@ -29,10 +29,7 @@ impl HexagonInlineAsmRegClass {
2929
None
3030
}
3131

32-
pub fn supported_types(
33-
self,
34-
_arch: InlineAsmArch,
35-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
32+
pub fn supported_types(self, _arch: InlineAsmArch) -> InlineAsmSupportedTypes {
3633
match self {
3734
Self::reg => types! { _: I8, I16, I32, F32; },
3835
}

compiler/rustc_target/src/asm/mips.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use rustc_macros::HashStable_Generic;
33
use std::fmt;
44

@@ -30,10 +30,7 @@ impl MipsInlineAsmRegClass {
3030
None
3131
}
3232

33-
pub fn supported_types(
34-
self,
35-
arch: InlineAsmArch,
36-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
33+
pub fn supported_types(self, arch: InlineAsmArch) -> InlineAsmSupportedTypes {
3734
match (self, arch) {
3835
(Self::reg, InlineAsmArch::Mips64) => types! { _: I8, I16, I32, I64, F32, F64; },
3936
(Self::reg, _) => types! { _: I8, I16, I32, F32; },

compiler/rustc_target/src/asm/mod.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ macro_rules! types {
137137
) => {
138138
{
139139
use super::InlineAsmType::*;
140-
&[
140+
super::InlineAsmSupportedTypes::OneOf(&[
141141
$($(
142142
($ty, None),
143143
)*)?
144144
$($(
145145
($ty2, Some($feature)),
146146
)*)*
147-
]
147+
])
148148
}
149149
};
150150
}
@@ -389,12 +389,10 @@ impl InlineAsmRegClass {
389389
}
390390
}
391391

392-
/// Returns a list of supported types for this register class, each with a
393-
/// options target feature required to use this type.
394-
pub fn supported_types(
395-
self,
396-
arch: InlineAsmArch,
397-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
392+
/// Returns either `InlineAsmSupportedTypes::OneOf`, containing a list of
393+
/// supported types for this register class, each with an optional target
394+
/// feature required to use that type, or `InlineAsmSupportedTypes::Any`.
395+
pub fn supported_types(self, arch: InlineAsmArch) -> InlineAsmSupportedTypes {
398396
match self {
399397
Self::X86(r) => r.supported_types(arch),
400398
Self::Arm(r) => r.supported_types(arch),
@@ -473,6 +471,17 @@ impl fmt::Display for InlineAsmRegOrRegClass {
473471
}
474472
}
475473

474+
/// Type constrains for a particular register class.
475+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
476+
pub enum InlineAsmSupportedTypes {
477+
/// Any type is allowed.
478+
Any,
479+
480+
/// Only the listed types are supported, and each is paired with
481+
/// an optional target feature required to use that type.
482+
OneOf(&'static [(InlineAsmType, Option<&'static str>)]),
483+
}
484+
476485
/// Set of types which can be used with a particular register class.
477486
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
478487
pub enum InlineAsmType {

compiler/rustc_target/src/asm/nvptx.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use rustc_macros::HashStable_Generic;
33

44
def_reg_class! {
@@ -30,10 +30,7 @@ impl NvptxInlineAsmRegClass {
3030
None
3131
}
3232

33-
pub fn supported_types(
34-
self,
35-
_arch: InlineAsmArch,
36-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
33+
pub fn supported_types(self, _arch: InlineAsmArch) -> InlineAsmSupportedTypes {
3734
match self {
3835
Self::reg16 => types! { _: I8, I16; },
3936
Self::reg32 => types! { _: I8, I16, I32, F32; },

compiler/rustc_target/src/asm/riscv.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use crate::spec::Target;
33
use rustc_macros::HashStable_Generic;
44
use std::fmt;
@@ -31,10 +31,7 @@ impl RiscVInlineAsmRegClass {
3131
None
3232
}
3333

34-
pub fn supported_types(
35-
self,
36-
arch: InlineAsmArch,
37-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
34+
pub fn supported_types(self, arch: InlineAsmArch) -> InlineAsmSupportedTypes {
3835
match self {
3936
Self::reg => {
4037
if arch == InlineAsmArch::RiscV64 {

compiler/rustc_target/src/asm/spirv.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use rustc_macros::HashStable_Generic;
33

44
def_reg_class! {
@@ -28,15 +28,8 @@ impl SpirVInlineAsmRegClass {
2828
None
2929
}
3030

31-
pub fn supported_types(
32-
self,
33-
_arch: InlineAsmArch,
34-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
35-
match self {
36-
Self::reg => {
37-
types! { _: I8, I16, I32, I64, F32, F64; }
38-
}
39-
}
31+
pub fn supported_types(self, _arch: InlineAsmArch) -> InlineAsmSupportedTypes {
32+
InlineAsmSupportedTypes::Any
4033
}
4134
}
4235

compiler/rustc_target/src/asm/x86.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::{InlineAsmArch, InlineAsmType};
1+
use super::{InlineAsmArch, InlineAsmSupportedTypes, InlineAsmType};
22
use crate::spec::Target;
33
use rustc_macros::HashStable_Generic;
44
use std::fmt;
@@ -93,10 +93,7 @@ impl X86InlineAsmRegClass {
9393
}
9494
}
9595

96-
pub fn supported_types(
97-
self,
98-
arch: InlineAsmArch,
99-
) -> &'static [(InlineAsmType, Option<&'static str>)] {
96+
pub fn supported_types(self, arch: InlineAsmArch) -> InlineAsmSupportedTypes {
10097
match self {
10198
Self::reg | Self::reg_abcd => {
10299
if arch == InlineAsmArch::X86_64 {

0 commit comments

Comments
 (0)