Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c024d8c

Browse filesBrowse files
committed
Make s390x non-clobber-only vector register support unstable
1 parent 2c8f6de commit c024d8c
Copy full SHA for c024d8c

File tree

Expand file treeCollapse file tree

21 files changed

+822
-145
lines changed
Filter options
Expand file treeCollapse file tree

21 files changed

+822
-145
lines changed

‎compiler/rustc_ast_lowering/messages.ftl

Copy file name to clipboardExpand all lines: compiler/rustc_ast_lowering/messages.ftl
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ ast_lowering_register2 = register `{$reg2_name}`
152152
153153
ast_lowering_register_class_only_clobber =
154154
register class `{$reg_class_name}` can only be used as a clobber, not as an input or output
155+
ast_lowering_register_class_only_clobber_stable =
156+
register class `{$reg_class_name}` can only be used as a clobber in stable
155157
156158
ast_lowering_register_conflict =
157159
register `{$reg1_name}` conflicts with register `{$reg2_name}`

‎compiler/rustc_ast_lowering/src/asm.rs

Copy file name to clipboardExpand all lines: compiler/rustc_ast_lowering/src/asm.rs
+26-6Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use super::errors::{
1717
InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
1818
InvalidAsmTemplateModifierLabel, InvalidAsmTemplateModifierRegClass,
1919
InvalidAsmTemplateModifierRegClassSub, InvalidAsmTemplateModifierSym, InvalidRegister,
20-
InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict,
20+
InvalidRegisterClass, RegisterClassOnlyClobber, RegisterClassOnlyClobberStable,
21+
RegisterConflict,
2122
};
2223
use crate::{
2324
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode,
@@ -61,6 +62,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6162
.emit();
6263
}
6364
}
65+
let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
6466
if asm.options.contains(InlineAsmOptions::ATT_SYNTAX)
6567
&& !matches!(asm_arch, Some(asm::InlineAsmArch::X86 | asm::InlineAsmArch::X86_64))
6668
&& !self.tcx.sess.opts.actually_rustdoc
@@ -333,11 +335,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
333335
// means that we disallow passing a value in/out of the asm and
334336
// require that the operand name an explicit register, not a
335337
// register class.
336-
if reg_class.is_clobber_only(asm_arch.unwrap()) && !op.is_clobber() {
337-
self.dcx().emit_err(RegisterClassOnlyClobber {
338-
op_span: op_sp,
339-
reg_class_name: reg_class.name(),
340-
});
338+
if reg_class.is_clobber_only(asm_arch.unwrap(), allow_experimental_reg)
339+
&& !op.is_clobber()
340+
{
341+
if allow_experimental_reg || reg_class.is_clobber_only(asm_arch.unwrap(), true)
342+
{
343+
// always clobber-only
344+
self.dcx().emit_err(RegisterClassOnlyClobber {
345+
op_span: op_sp,
346+
reg_class_name: reg_class.name(),
347+
});
348+
} else {
349+
// clobber-only in stable
350+
self.tcx
351+
.sess
352+
.create_feature_err(
353+
RegisterClassOnlyClobberStable {
354+
op_span: op_sp,
355+
reg_class_name: reg_class.name(),
356+
},
357+
sym::asm_experimental_reg,
358+
)
359+
.emit();
360+
}
341361
continue;
342362
}
343363

‎compiler/rustc_ast_lowering/src/errors.rs

Copy file name to clipboardExpand all lines: compiler/rustc_ast_lowering/src/errors.rs
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,14 @@ pub(crate) struct RegisterClassOnlyClobber {
279279
pub reg_class_name: Symbol,
280280
}
281281

282+
#[derive(Diagnostic)]
283+
#[diag(ast_lowering_register_class_only_clobber_stable)]
284+
pub(crate) struct RegisterClassOnlyClobberStable {
285+
#[primary_span]
286+
pub op_span: Span,
287+
pub reg_class_name: Symbol,
288+
}
289+
282290
#[derive(Diagnostic)]
283291
#[diag(ast_lowering_register_conflict)]
284292
pub(crate) struct RegisterConflict<'a> {

‎compiler/rustc_codegen_cranelift/src/inline_asm.rs

Copy file name to clipboardExpand all lines: compiler/rustc_codegen_cranelift/src/inline_asm.rs
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
462462
let mut slots_output = vec![None; self.operands.len()];
463463

464464
let new_slot_fn = |slot_size: &mut Size, reg_class: InlineAsmRegClass| {
465-
let reg_size =
466-
reg_class.supported_types(self.arch).iter().map(|(ty, _)| ty.size()).max().unwrap();
465+
let reg_size = reg_class
466+
.supported_types(self.arch, true)
467+
.iter()
468+
.map(|(ty, _)| ty.size())
469+
.max()
470+
.unwrap();
467471
let align = rustc_abi::Align::from_bytes(reg_size.bytes()).unwrap();
468472
let offset = slot_size.align_to(align);
469473
*slot_size = offset + reg_size;

‎compiler/rustc_codegen_gcc/src/asm.rs

Copy file name to clipboardExpand all lines: compiler/rustc_codegen_gcc/src/asm.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
186186
// `clobber_abi` can add lots of clobbers that are not supported by the target,
187187
// such as AVX-512 registers, so we just ignore unsupported registers
188188
let is_target_supported =
189-
reg.reg_class().supported_types(asm_arch).iter().any(
189+
reg.reg_class().supported_types(asm_arch, true).iter().any(
190190
|&(_, feature)| {
191191
if let Some(feature) = feature {
192192
self.tcx

‎compiler/rustc_codegen_llvm/src/asm.rs

Copy file name to clipboardExpand all lines: compiler/rustc_codegen_llvm/src/asm.rs
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
4545
match *op {
4646
InlineAsmOperandRef::Out { reg, late, place } => {
4747
let is_target_supported = |reg_class: InlineAsmRegClass| {
48-
for &(_, feature) in reg_class.supported_types(asm_arch) {
48+
for &(_, feature) in reg_class.supported_types(asm_arch, true) {
4949
if let Some(feature) = feature {
5050
if self
5151
.tcx
@@ -85,7 +85,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
8585
}
8686
continue;
8787
} else if !is_target_supported(reg.reg_class())
88-
|| reg.reg_class().is_clobber_only(asm_arch)
88+
|| reg.reg_class().is_clobber_only(asm_arch, true)
8989
{
9090
// We turn discarded outputs into clobber constraints
9191
// if the target feature needed by the register class is

‎compiler/rustc_feature/src/unstable.rs

Copy file name to clipboardExpand all lines: compiler/rustc_feature/src/unstable.rs
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,8 @@ declare_features! (
376376
(unstable, arbitrary_self_types_pointers, "1.83.0", Some(44874)),
377377
/// Enables experimental inline assembly support for additional architectures.
378378
(unstable, asm_experimental_arch, "1.58.0", Some(93335)),
379+
/// Enables experimental register support in inline assembly.
380+
(unstable, asm_experimental_reg, "CURRENT_RUSTC_VERSION", Some(133416)),
379381
/// Allows using `label` operands in inline assembly.
380382
(unstable, asm_goto, "1.78.0", Some(119364)),
381383
/// Allows the `may_unwind` option in inline assembly.

‎compiler/rustc_hir_analysis/messages.ftl

Copy file name to clipboardExpand all lines: compiler/rustc_hir_analysis/messages.ftl
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is
424424
hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
425425
.note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
426426
427+
hir_analysis_register_type_unstable =
428+
type `{$ty}` cannot be used with this register class in stable
429+
427430
hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
428431
429432
hir_analysis_return_type_notation_equality_bound =

‎compiler/rustc_hir_analysis/src/check/intrinsicck.rs

Copy file name to clipboardExpand all lines: compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+27-11Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ use rustc_hir::{self as hir, LangItem};
77
use rustc_middle::bug;
88
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
99
use rustc_session::lint;
10-
use rustc_span::Symbol;
1110
use rustc_span::def_id::LocalDefId;
11+
use rustc_span::{Symbol, sym};
1212
use rustc_target::asm::{
1313
InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType, ModifierInfo,
1414
};
1515

16+
use crate::errors::RegisterTypeUnstable;
17+
1618
pub struct InlineAsmCtxt<'a, 'tcx> {
1719
tcx: TyCtxt<'tcx>,
1820
typing_env: ty::TypingEnv<'tcx>,
@@ -218,17 +220,29 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
218220
// Check the type against the list of types supported by the selected
219221
// register class.
220222
let asm_arch = self.tcx.sess.asm_arch.unwrap();
223+
let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
221224
let reg_class = reg.reg_class();
222-
let supported_tys = reg_class.supported_types(asm_arch);
225+
let supported_tys = reg_class.supported_types(asm_arch, allow_experimental_reg);
223226
let Some((_, feature)) = supported_tys.iter().find(|&&(t, _)| t == asm_ty) else {
224-
let msg = format!("type `{ty}` cannot be used with this register class");
225-
let mut err = self.tcx.dcx().struct_span_err(expr.span, msg);
226-
let supported_tys: Vec<_> = supported_tys.iter().map(|(t, _)| t.to_string()).collect();
227-
err.note(format!(
228-
"register class `{}` supports these types: {}",
229-
reg_class.name(),
230-
supported_tys.join(", "),
231-
));
227+
let mut err = if !allow_experimental_reg
228+
&& reg_class.supported_types(asm_arch, true).iter().any(|&(t, _)| t == asm_ty)
229+
{
230+
self.tcx.sess.create_feature_err(
231+
RegisterTypeUnstable { span: expr.span, ty },
232+
sym::asm_experimental_reg,
233+
)
234+
} else {
235+
let msg = format!("type `{ty}` cannot be used with this register class");
236+
let mut err = self.tcx.dcx().struct_span_err(expr.span, msg);
237+
let supported_tys: Vec<_> =
238+
supported_tys.iter().map(|(t, _)| t.to_string()).collect();
239+
err.note(format!(
240+
"register class `{}` supports these types: {}",
241+
reg_class.name(),
242+
supported_tys.join(", "),
243+
));
244+
err
245+
};
232246
if let Some(suggest) = reg_class.suggest_class(asm_arch, asm_ty) {
233247
err.help(format!("consider using the `{}` register class instead", suggest.name()));
234248
}
@@ -313,6 +327,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
313327
self.tcx.dcx().delayed_bug("target architecture does not support asm");
314328
return;
315329
};
330+
let allow_experimental_reg = self.tcx.features().asm_experimental_reg();
316331
for (idx, (op, op_sp)) in asm.operands.iter().enumerate() {
317332
// Validate register classes against currently enabled target
318333
// features. We check that at least one type is available for
@@ -352,7 +367,8 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
352367
if let InlineAsmRegClass::Err = reg_class {
353368
continue;
354369
}
355-
for &(_, feature) in reg_class.supported_types(asm_arch) {
370+
for &(_, feature) in reg_class.supported_types(asm_arch, allow_experimental_reg)
371+
{
356372
match feature {
357373
Some(feature) => {
358374
if target_features.contains(&feature) {

‎compiler/rustc_hir_analysis/src/errors.rs

Copy file name to clipboardExpand all lines: compiler/rustc_hir_analysis/src/errors.rs
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,3 +1685,11 @@ pub(crate) struct CmseEntryGeneric {
16851685
#[primary_span]
16861686
pub span: Span,
16871687
}
1688+
1689+
#[derive(Diagnostic)]
1690+
#[diag(hir_analysis_register_type_unstable)]
1691+
pub(crate) struct RegisterTypeUnstable<'a> {
1692+
#[primary_span]
1693+
pub span: Span,
1694+
pub ty: Ty<'a>,
1695+
}

‎compiler/rustc_span/src/symbol.rs

Copy file name to clipboardExpand all lines: compiler/rustc_span/src/symbol.rs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ symbols! {
416416
asm,
417417
asm_const,
418418
asm_experimental_arch,
419+
asm_experimental_reg,
419420
asm_goto,
420421
asm_sym,
421422
asm_unwind,

‎compiler/rustc_target/src/asm/mod.rs

Copy file name to clipboardExpand all lines: compiler/rustc_target/src/asm/mod.rs
+10-3Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,9 +604,13 @@ impl InlineAsmRegClass {
604604

605605
/// Returns a list of supported types for this register class, each with an
606606
/// options target feature required to use this type.
607+
///
608+
/// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`,
609+
/// since all the stability checking will have been done in prior stages.
607610
pub fn supported_types(
608611
self,
609612
arch: InlineAsmArch,
613+
allow_experimental_reg: bool,
610614
) -> &'static [(InlineAsmType, Option<Symbol>)] {
611615
match self {
612616
Self::X86(r) => r.supported_types(arch),
@@ -618,7 +622,7 @@ impl InlineAsmRegClass {
618622
Self::Hexagon(r) => r.supported_types(arch),
619623
Self::LoongArch(r) => r.supported_types(arch),
620624
Self::Mips(r) => r.supported_types(arch),
621-
Self::S390x(r) => r.supported_types(arch),
625+
Self::S390x(r) => r.supported_types(arch, allow_experimental_reg),
622626
Self::Sparc(r) => r.supported_types(arch),
623627
Self::SpirV(r) => r.supported_types(arch),
624628
Self::Wasm(r) => r.supported_types(arch),
@@ -696,8 +700,11 @@ impl InlineAsmRegClass {
696700

697701
/// Returns whether registers in this class can only be used as clobbers
698702
/// and not as inputs/outputs.
699-
pub fn is_clobber_only(self, arch: InlineAsmArch) -> bool {
700-
self.supported_types(arch).is_empty()
703+
///
704+
/// At the codegen stage, it is fine to always pass true for `allow_experimental_reg`,
705+
/// since all the stability checking will have been done in prior stages.
706+
pub fn is_clobber_only(self, arch: InlineAsmArch, allow_experimental_reg: bool) -> bool {
707+
self.supported_types(arch, allow_experimental_reg).is_empty()
701708
}
702709
}
703710

‎compiler/rustc_target/src/asm/s390x.rs

Copy file name to clipboardExpand all lines: compiler/rustc_target/src/asm/s390x.rs
+12-4Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,22 @@ impl S390xInlineAsmRegClass {
3838
pub fn supported_types(
3939
self,
4040
_arch: InlineAsmArch,
41+
allow_experimental_reg: bool,
4142
) -> &'static [(InlineAsmType, Option<Symbol>)] {
4243
match self {
4344
Self::reg | Self::reg_addr => types! { _: I8, I16, I32, I64; },
4445
Self::freg => types! { _: F32, F64; },
45-
Self::vreg => types! {
46-
vector: I32, F32, I64, F64, I128, F128,
47-
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
48-
},
46+
Self::vreg => {
47+
if allow_experimental_reg {
48+
// non-clobber-only vector register support is unstable.
49+
types! {
50+
vector: I32, F32, I64, F64, I128, F128,
51+
VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
52+
}
53+
} else {
54+
&[]
55+
}
56+
}
4957
Self::areg => &[],
5058
}
5159
}
+40Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# `asm_experimental_arch`
2+
3+
The tracking issue for this feature is: [#133416]
4+
5+
[#133416]: https://github.com/rust-lang/rust/issues/133416
6+
7+
------------------------
8+
9+
This tracks support for additional registers in architectures where inline assembly is already stable.
10+
11+
## Register classes
12+
13+
| Architecture | Register class | Registers | LLVM constraint code |
14+
| ------------ | -------------- | --------- | -------------------- |
15+
| s390x | `vreg` | `v[0-31]` | `v` |
16+
17+
> **Notes**:
18+
> - s390x `vreg` is clobber-only in stable.
19+
20+
## Register class supported types
21+
22+
| Architecture | Register class | Target feature | Allowed types |
23+
| ------------ | -------------- | -------------- | ------------- |
24+
| s390x | `vreg` | `vector` | `i32`, `f32`, `i64`, `f64`, `i128`, `f128`, `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
25+
26+
## Register aliases
27+
28+
| Architecture | Base register | Aliases |
29+
| ------------ | ------------- | ------- |
30+
31+
## Unsupported registers
32+
33+
| Architecture | Unsupported register | Reason |
34+
| ------------ | -------------------- | ------ |
35+
36+
## Template modifiers
37+
38+
| Architecture | Register class | Modifier | Example output | LLVM modifier |
39+
| ------------ | -------------- | -------- | -------------- | ------------- |
40+
| s390x | `vreg` | None | `%v0` | None |

‎tests/assembly/asm/s390x-types.rs

Copy file name to clipboardExpand all lines: tests/assembly/asm/s390x-types.rs
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//@ compile-flags: -Zmerge-functions=disabled
88

99
#![feature(no_core, lang_items, rustc_attrs, repr_simd, f128)]
10+
#![cfg_attr(s390x_vector, feature(asm_experimental_reg))]
1011
#![crate_type = "rlib"]
1112
#![no_core]
1213
#![allow(asm_sub_register, non_camel_case_types)]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.