Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3785bba

Browse files
committedDec 15, 2023
Add #[rustc_intrinsic_const_vector_arg] to allow vectors to be passed as constants
This allows constant vectors using a repr(simd) type to be propagated through to the backend by reusing the functionality used to do a similar thing for the simd_shuffle intrinsic. fix #118209
1 parent 96df494 commit 3785bba

File tree

24 files changed

+460
-33
lines changed

24 files changed

+460
-33
lines changed
 

‎Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3496,6 +3496,7 @@ dependencies = [
34963496
"either",
34973497
"itertools",
34983498
"polonius-engine",
3499+
"rustc_ast",
34993500
"rustc_data_structures",
35003501
"rustc_errors",
35013502
"rustc_fluent_macro",

‎compiler/rustc_borrowck/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
either = "1.5.0"
99
itertools = "0.11"
1010
polonius-engine = "0.13.0"
11+
rustc_ast = { path = "../rustc_ast" }
1112
rustc_data_structures = { path = "../rustc_data_structures" }
1213
rustc_errors = { path = "../rustc_errors" }
1314
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

‎compiler/rustc_borrowck/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ borrowck_higher_ranked_lifetime_error =
7171
borrowck_higher_ranked_subtype_error =
7272
higher-ranked subtype error
7373
74+
borrowck_intrinsic_const_vector_arg_non_const = argument at index {$index} must be a constant
75+
7476
borrowck_lifetime_constraints_error =
7577
lifetime may not live long enough
7678

‎compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,3 +459,11 @@ pub(crate) struct SimdShuffleLastConst {
459459
#[primary_span]
460460
pub span: Span,
461461
}
462+
463+
#[derive(Diagnostic)]
464+
#[diag(borrowck_intrinsic_const_vector_arg_non_const)]
465+
pub(crate) struct IntrinsicConstVectorArgNonConst {
466+
#[primary_span]
467+
pub span: Span,
468+
pub index: u128,
469+
}

‎compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
4949
use rustc_mir_dataflow::move_paths::MoveData;
5050
use rustc_mir_dataflow::ResultsCursor;
5151

52-
use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst};
52+
use crate::session_diagnostics::{
53+
IntrinsicConstVectorArgNonConst, MoveUnsized, SimdShuffleLastConst,
54+
};
5355
use crate::{
5456
borrow_set::BorrowSet,
5557
constraints::{OutlivesConstraint, OutlivesConstraintSet},
@@ -1579,6 +1581,35 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
15791581
}
15801582
_ => {}
15811583
}
1584+
} else if let Some(attr) =
1585+
self.tcx().get_attr(def_id, sym::rustc_intrinsic_const_vector_arg)
1586+
{
1587+
match attr.meta_item_list() {
1588+
Some(items) => {
1589+
items.into_iter().for_each(|item: rustc_ast::NestedMetaItem| match item {
1590+
rustc_ast::NestedMetaItem::Lit(rustc_ast::MetaItemLit {
1591+
kind: rustc_ast::LitKind::Int(index, _),
1592+
..
1593+
}) => {
1594+
if index >= args.len() as u128 {
1595+
span_mirbug!(self, term, "index out of bounds");
1596+
} else {
1597+
if !matches!(args[index as usize], Operand::Constant(_)) {
1598+
self.tcx().sess.emit_err(IntrinsicConstVectorArgNonConst {
1599+
span: term.source_info.span,
1600+
index,
1601+
});
1602+
}
1603+
}
1604+
}
1605+
_ => {
1606+
span_mirbug!(self, term, "invalid index");
1607+
}
1608+
});
1609+
}
1610+
// Error is reported by `rustc_attr!`
1611+
None => (),
1612+
}
15821613
}
15831614
}
15841615
debug!(?func_ty);

‎compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
159159
self.context.new_struct_constructor(None, struct_type.as_type(), None, values)
160160
}
161161

162+
fn const_vector(&self, values: &[RValue<'gcc>]) -> RValue<'gcc> {
163+
let typ = self.type_vector(values[0].get_type(), values.len() as u64);
164+
self.context.new_rvalue_from_vector(None, typ, values)
165+
}
166+
162167
fn const_to_opt_uint(&self, _v: RValue<'gcc>) -> Option<u64> {
163168
// TODO(antoyo)
164169
None

‎compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,6 @@ impl<'ll> CodegenCx<'ll, '_> {
9898
unsafe { llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint) }
9999
}
100100

101-
pub fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
102-
unsafe { llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint) }
103-
}
104-
105101
pub fn const_bytes(&self, bytes: &[u8]) -> &'ll Value {
106102
bytes_in_context(self.llcx, bytes)
107103
}
@@ -217,6 +213,10 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
217213
struct_in_context(self.llcx, elts, packed)
218214
}
219215

216+
fn const_vector(&self, elts: &[&'ll Value]) -> &'ll Value {
217+
unsafe { llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint) }
218+
}
219+
220220
fn const_to_opt_uint(&self, v: &'ll Value) -> Option<u64> {
221221
try_as_const_integral(v).and_then(|v| unsafe {
222222
let mut i = 0u64;

‎compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ codegen_ssa_cgu_not_recorded =
1616
1717
codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
1818
19+
codegen_ssa_const_vector_evaluation = could not evaluate constant vector at compile time
20+
1921
codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error}
2022
2123
codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error}

‎compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,13 @@ pub struct ShuffleIndicesEvaluation {
663663
pub span: Span,
664664
}
665665

666+
#[derive(Diagnostic)]
667+
#[diag(codegen_ssa_const_vector_evaluation)]
668+
pub struct ConstVectorEvaluation {
669+
#[primary_span]
670+
pub span: Span,
671+
}
672+
666673
#[derive(Diagnostic)]
667674
#[diag(codegen_ssa_missing_memory_ordering)]
668675
pub struct MissingMemoryOrdering;

‎compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ use super::{CachedLlbb, FunctionCx, LocalRef};
55

66
use crate::base;
77
use crate::common::{self, IntPredicate};
8+
use crate::errors;
89
use crate::meth;
910
use crate::traits::*;
1011
use crate::MemFlags;
1112

1213
use rustc_ast as ast;
13-
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
14+
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece, LitKind, MetaItemLit, NestedMetaItem};
1415
use rustc_hir::lang_items::LangItem;
1516
use rustc_middle::mir::{self, AssertKind, SwitchTargets, UnwindTerminateReason};
1617
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
@@ -864,7 +865,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
864865
// promotes any complex rvalues to constants.
865866
if i == 2 && intrinsic == sym::simd_shuffle {
866867
if let mir::Operand::Constant(constant) = arg {
867-
let (llval, ty) = self.simd_shuffle_indices(bx, constant);
868+
let (llval, ty) = self.early_evaluate_const_vector(bx, constant);
869+
let llval = llval.unwrap_or_else(|| {
870+
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation {
871+
span: constant.span,
872+
});
873+
// We've errored, so we don't have to produce working code.
874+
let llty = bx.backend_type(bx.layout_of(ty));
875+
bx.const_undef(llty)
876+
});
868877
return OperandRef {
869878
val: Immediate(llval),
870879
layout: bx.layout_of(ty),
@@ -908,9 +917,49 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
908917
(args, None)
909918
};
910919

920+
let const_vec_arg_indexes = (|| {
921+
if let Some(def) = def
922+
&& let Some(attr) =
923+
bx.tcx().get_attr(def.def_id(), sym::rustc_intrinsic_const_vector_arg)
924+
{
925+
attr.meta_item_list()
926+
.iter()
927+
.flatten()
928+
.map(|item: &NestedMetaItem| match item {
929+
NestedMetaItem::Lit(MetaItemLit {
930+
kind: LitKind::Int(index, _), ..
931+
}) => *index as usize,
932+
_ => span_bug!(item.span(), "attribute argument must be an integer"),
933+
})
934+
.collect()
935+
} else {
936+
Vec::<usize>::new()
937+
}
938+
})();
939+
911940
let mut copied_constant_arguments = vec![];
912941
'make_args: for (i, arg) in first_args.iter().enumerate() {
913-
let mut op = self.codegen_operand(bx, arg);
942+
let mut op = if const_vec_arg_indexes.contains(&i) {
943+
// Force the specified argument to be constant by using const-qualification to promote any complex rvalues to constant.
944+
if let mir::Operand::Constant(constant) = arg
945+
&& constant.ty().is_simd()
946+
{
947+
let (llval, ty) = self.early_evaluate_const_vector(bx, &constant);
948+
let llval = llval.unwrap_or_else(|| {
949+
bx.tcx()
950+
.sess
951+
.emit_err(errors::ConstVectorEvaluation { span: constant.span });
952+
// We've errored, so we don't have to produce working code.
953+
let llty = bx.backend_type(bx.layout_of(ty));
954+
bx.const_undef(llty)
955+
});
956+
OperandRef { val: Immediate(llval), layout: bx.layout_of(ty) }
957+
} else {
958+
span_bug!(span, "argument at {i} must be a constant vector");
959+
}
960+
} else {
961+
self.codegen_operand(bx, arg)
962+
};
914963

915964
if let (0, Some(ty::InstanceDef::Virtual(_, idx))) = (i, def) {
916965
match op.val {

‎compiler/rustc_codegen_ssa/src/mir/constant.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::errors;
21
use crate::mir::operand::OperandRef;
32
use crate::traits::*;
43
use rustc_middle::mir;
@@ -28,7 +27,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2827
.expect("erroneous constant not captured by required_consts")
2928
}
3029

31-
/// This is a convenience helper for `simd_shuffle_indices`. It has the precondition
30+
/// This is a convenience helper for `early_evaluate_const_vector`. It has the precondition
3231
/// that the given `constant` is an `Const::Unevaluated` and must be convertible to
3332
/// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
3433
///
@@ -63,19 +62,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
6362
)
6463
}
6564

66-
/// process constant containing SIMD shuffle indices
67-
pub fn simd_shuffle_indices(
65+
/// process constant SIMD vector or constant containing SIMD shuffle indices
66+
pub fn early_evaluate_const_vector(
6867
&mut self,
6968
bx: &Bx,
7069
constant: &mir::ConstOperand<'tcx>,
71-
) -> (Bx::Value, Ty<'tcx>) {
70+
) -> (Option<Bx::Value>, Ty<'tcx>) {
7271
let ty = self.monomorphize(constant.ty());
73-
let val = self
74-
.eval_unevaluated_mir_constant_to_valtree(constant)
75-
.ok()
76-
.flatten()
77-
.map(|val| {
78-
let field_ty = ty.builtin_index().unwrap();
72+
let field_ty = if ty.is_simd() {
73+
ty.simd_size_and_type(bx.tcx()).1
74+
} else {
75+
ty.builtin_index().unwrap()
76+
};
77+
let val =
78+
self.eval_unevaluated_mir_constant_to_valtree(constant).ok().flatten().map(|val| {
7979
let values: Vec<_> = val
8080
.unwrap_branch()
8181
.iter()
@@ -87,17 +87,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
8787
};
8888
bx.scalar_to_backend(prim, scalar, bx.immediate_backend_type(layout))
8989
} else {
90-
bug!("simd shuffle field {:?}", field)
90+
bug!("field is not a scalar {:?}", field)
9191
}
9292
})
9393
.collect();
94-
bx.const_struct(&values, false)
95-
})
96-
.unwrap_or_else(|| {
97-
bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span: constant.span });
98-
// We've errored, so we don't have to produce working code.
99-
let llty = bx.backend_type(bx.layout_of(ty));
100-
bx.const_undef(llty)
94+
if ty.is_simd() {
95+
bx.const_vector(&values)
96+
} else {
97+
bx.const_struct(&values, false)
98+
}
10199
});
102100
(val, ty)
103101
}

‎compiler/rustc_codegen_ssa/src/traits/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
2828

2929
fn const_str(&self, s: &str) -> (Self::Value, Self::Value);
3030
fn const_struct(&self, elts: &[Self::Value], packed: bool) -> Self::Value;
31+
fn const_vector(&self, elts: &[Self::Value]) -> Self::Value;
3132

3233
fn const_to_opt_uint(&self, v: Self::Value) -> Option<u64>;
3334
fn const_to_opt_u128(&self, v: Self::Value, sign_ext: bool) -> Option<u128>;

‎compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
652652
rustc_attr!(
653653
rustc_const_panic_str, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE
654654
),
655+
rustc_attr!(
656+
rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg1_index, arg2_index, ..."), ErrorFollowing, INTERNAL_UNSTABLE
657+
),
655658

656659
// ==========================================================================
657660
// Internal attributes, Layout related:

‎compiler/rustc_passes/messages.ftl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,18 @@ passes_rustc_allow_const_fn_unstable =
604604
passes_rustc_dirty_clean =
605605
attribute requires -Z query-dep-graph to be enabled
606606
607+
passes_rustc_intrinsic_const_vector_arg =
608+
attribute should be applied to functions in `extern "unadjusted"` modules
609+
.label = not a function in an `extern "unadjusted"` module
610+
611+
passes_rustc_intrinsic_const_vector_arg_invalid = attribute requires a parameter index
612+
613+
passes_rustc_intrinsic_const_vector_arg_non_vector = parameter at index {$index} must be a simd type
614+
.label = parameter is a non-simd type
615+
616+
passes_rustc_intrinsic_const_vector_arg_out_of_bounds = function does not have a parameter at index {$index}
617+
.label = function has {$arg_count} arguments
618+
607619
passes_rustc_layout_scalar_valid_range_arg =
608620
expected exactly one integer literal argument
609621

‎compiler/rustc_passes/src/check_attr.rs

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ use rustc_data_structures::fx::FxHashMap;
1010
use rustc_errors::{Applicability, IntoDiagnosticArg, MultiSpan};
1111
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
1212
use rustc_hir as hir;
13-
use rustc_hir::def_id::LocalModDefId;
13+
use rustc_hir::def::Res;
14+
use rustc_hir::def_id::{DefId, LocalModDefId};
1415
use rustc_hir::intravisit::{self, Visitor};
1516
use rustc_hir::{
16-
self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
17+
self, FnSig, ForeignItem, HirId, Item, ItemKind, Path, PathSegment, QPath, TraitItem, TyKind,
18+
CRATE_HIR_ID, CRATE_OWNER_ID,
1719
};
1820
use rustc_hir::{MethodKind, Target, Unsafety};
1921
use rustc_macros::LintDiagnostic;
@@ -198,6 +200,9 @@ impl CheckAttrVisitor<'_> {
198200
sym::rustc_safe_intrinsic => {
199201
self.check_rustc_safe_intrinsic(hir_id, attr, span, target)
200202
}
203+
sym::rustc_intrinsic_const_vector_arg => {
204+
self.check_rustc_intrinsic_const_vector_arg(hir_id, attr, span, target)
205+
}
201206
_ => true,
202207
};
203208

@@ -2083,6 +2088,89 @@ impl CheckAttrVisitor<'_> {
20832088
false
20842089
}
20852090

2091+
fn check_rustc_intrinsic_const_vector_arg(
2092+
&self,
2093+
hir_id: HirId,
2094+
attr: &Attribute,
2095+
span: Span,
2096+
target: Target,
2097+
) -> bool {
2098+
let hir = self.tcx.hir();
2099+
2100+
if let Target::ForeignFn = target
2101+
&& let Some(parent) = hir.opt_parent_id(hir_id)
2102+
&& let hir::Node::Item(Item {
2103+
kind: ItemKind::ForeignMod { abi: Abi::Unadjusted, .. },
2104+
..
2105+
}) = self.tcx.hir_node(parent)
2106+
{
2107+
let Some(list) = attr.meta_item_list() else {
2108+
// The attribute form is validated on AST.
2109+
return false;
2110+
};
2111+
2112+
let Some(decl) = self.tcx.hir_node(hir_id).fn_decl() else {
2113+
bug!("should be a function declaration");
2114+
};
2115+
2116+
let arg_count = decl.inputs.len() as u128;
2117+
for meta in list {
2118+
if let Some(LitKind::Int(val, _)) = meta.lit().map(|lit| &lit.kind) {
2119+
if *val >= arg_count {
2120+
self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgOutOfBounds {
2121+
attr_span: attr.span,
2122+
span: span,
2123+
index: *val,
2124+
arg_count: decl.inputs.len(),
2125+
});
2126+
return false;
2127+
}
2128+
2129+
let param_ty = decl.inputs[*val as usize];
2130+
let type_id: Option<DefId> = match param_ty.kind {
2131+
TyKind::Path(path) => match path {
2132+
QPath::Resolved(_, Path { res: Res::Def(_, id), .. }) => Some(*id),
2133+
QPath::TypeRelative(_, PathSegment { res: Res::Def(_, id), .. }) => {
2134+
Some(*id)
2135+
}
2136+
_ => None,
2137+
},
2138+
_ => None,
2139+
};
2140+
2141+
let is_simd = if let Some(type_id) = type_id {
2142+
self.tcx
2143+
.get_attrs(type_id, sym::repr)
2144+
.filter_map(|attr| attr.meta_item_list())
2145+
.flatten()
2146+
.any(|hint: NestedMetaItem| hint.name_or_empty() == sym::simd)
2147+
} else {
2148+
false
2149+
};
2150+
if !is_simd {
2151+
self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgNonVector {
2152+
attr_span: attr.span,
2153+
param_span: param_ty.span,
2154+
index: *val,
2155+
});
2156+
return false;
2157+
}
2158+
} else {
2159+
self.tcx.sess.emit_err(errors::RustcIntrinsicConstVectorArgInvalid {
2160+
span: meta.span(),
2161+
});
2162+
return false;
2163+
}
2164+
}
2165+
} else {
2166+
self.tcx
2167+
.sess
2168+
.emit_err(errors::RustcIntrinsicConstVectorArg { attr_span: attr.span, span });
2169+
return false;
2170+
}
2171+
true
2172+
}
2173+
20862174
fn check_rustc_std_internal_symbol(
20872175
&self,
20882176
attr: &Attribute,

‎compiler/rustc_passes/src/errors.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,43 @@ pub struct RustcSafeIntrinsic {
636636
pub span: Span,
637637
}
638638

639+
#[derive(Diagnostic)]
640+
#[diag(passes_rustc_intrinsic_const_vector_arg_out_of_bounds)]
641+
pub(crate) struct RustcIntrinsicConstVectorArgOutOfBounds {
642+
#[primary_span]
643+
pub attr_span: Span,
644+
#[label]
645+
pub span: Span,
646+
pub index: u128,
647+
pub arg_count: usize,
648+
}
649+
650+
#[derive(Diagnostic)]
651+
#[diag(passes_rustc_intrinsic_const_vector_arg_non_vector)]
652+
pub(crate) struct RustcIntrinsicConstVectorArgNonVector {
653+
#[primary_span]
654+
pub attr_span: Span,
655+
#[label]
656+
pub param_span: Span,
657+
pub index: u128,
658+
}
659+
660+
#[derive(Diagnostic)]
661+
#[diag(passes_rustc_intrinsic_const_vector_arg_invalid)]
662+
pub(crate) struct RustcIntrinsicConstVectorArgInvalid {
663+
#[primary_span]
664+
pub span: Span,
665+
}
666+
667+
#[derive(Diagnostic)]
668+
#[diag(passes_rustc_intrinsic_const_vector_arg)]
669+
pub struct RustcIntrinsicConstVectorArg {
670+
#[primary_span]
671+
pub attr_span: Span,
672+
#[label]
673+
pub span: Span,
674+
}
675+
639676
#[derive(Diagnostic)]
640677
#[diag(passes_rustc_std_internal_symbol)]
641678
pub struct RustcStdInternalSymbol {

‎compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,7 @@ symbols! {
14031403
rustc_if_this_changed,
14041404
rustc_inherit_overflow_checks,
14051405
rustc_insignificant_dtor,
1406+
rustc_intrinsic_const_vector_arg,
14061407
rustc_layout,
14071408
rustc_layout_scalar_valid_range_end,
14081409
rustc_layout_scalar_valid_range_start,

‎src/tools/rust-analyzer/crates/hir-def/src/attr/builtin.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
488488
rustc_attr!(
489489
rustc_do_not_const_check, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE
490490
),
491+
rustc_attr!(rustc_intrinsic_const_vector_arg, Normal, template!(List: "arg_index1, arg_index2, ..."), ErrorFollowing, INTERNAL_UNSTABLE),
491492

492493
// ==========================================================================
493494
// Internal attributes, Layout related:
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// compile-flags: -Z unstable-options
2+
#![feature(abi_unadjusted)]
3+
#![feature(inline_const)]
4+
#![feature(intrinsics)]
5+
#![allow(non_camel_case_types)]
6+
#![feature(repr_simd)]
7+
#![feature(rustc_attrs)]
8+
#![feature(simd_ffi)]
9+
#![allow(unused)]
10+
11+
#[repr(simd)]
12+
#[derive(Clone)]
13+
pub struct i8x2(i8, i8);
14+
15+
extern "unadjusted" {
16+
#[rustc_intrinsic_const_vector_arg] //~ ERROR malformed `rustc_intrinsic_const_vector_arg` attribute input
17+
fn foo1(a: i8x2, b: i8);
18+
}
19+
20+
extern "unadjusted" {
21+
#[rustc_intrinsic_const_vector_arg = "1"] //~ ERROR malformed `rustc_intrinsic_const_vector_arg` attribute input
22+
fn foo2(a: i8x2, b: i8);
23+
}
24+
25+
#[rustc_intrinsic_const_vector_arg(0)] //~ ERROR attribute should be applied to functions in `extern "unadjusted"` modules
26+
pub struct foo3(i8x2);
27+
28+
extern "C" {
29+
#[rustc_intrinsic_const_vector_arg(0)] //~ ERROR attribute should be applied to functions in `extern "unadjusted"` modules
30+
fn foo4(a: i8x2);
31+
}
32+
33+
extern "unadjusted" {
34+
#[rustc_intrinsic_const_vector_arg(0)] //~ ERROR function does not have a parameter at index 0
35+
fn foo5();
36+
}
37+
38+
extern "unadjusted" {
39+
#[rustc_intrinsic_const_vector_arg(1)] //~ ERROR function does not have a parameter at index 1
40+
fn foo6(a: i8x2);
41+
}
42+
43+
extern "unadjusted" {
44+
#[rustc_intrinsic_const_vector_arg("bar")] //~ ERROR attribute requires a parameter index
45+
fn foo7(a: i8x2);
46+
}
47+
48+
extern "unadjusted" {
49+
#[rustc_intrinsic_const_vector_arg(0,2)] //~ ERROR function does not have a parameter at index 2
50+
fn foo8(a: i8x2, b: i8);
51+
}
52+
53+
extern "unadjusted" {
54+
#[rustc_intrinsic_const_vector_arg(0)] //~ ERROR parameter at index 0 must be a simd type
55+
fn foo9(a: i8);
56+
}
57+
58+
fn main() {}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error: malformed `rustc_intrinsic_const_vector_arg` attribute input
2+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:16:5
3+
|
4+
LL | #[rustc_intrinsic_const_vector_arg]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]`
6+
7+
error: malformed `rustc_intrinsic_const_vector_arg` attribute input
8+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:21:5
9+
|
10+
LL | #[rustc_intrinsic_const_vector_arg = "1"]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_intrinsic_const_vector_arg(arg1_index, arg2_index, ...)]`
12+
13+
error: attribute should be applied to functions in `extern "unadjusted"` modules
14+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:25:1
15+
|
16+
LL | #[rustc_intrinsic_const_vector_arg(0)]
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
LL | pub struct foo3(i8x2);
19+
| ---------------------- not a function in an `extern "unadjusted"` module
20+
21+
error: attribute should be applied to functions in `extern "unadjusted"` modules
22+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:29:5
23+
|
24+
LL | #[rustc_intrinsic_const_vector_arg(0)]
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
26+
LL | fn foo4(a: i8x2);
27+
| ----------------- not a function in an `extern "unadjusted"` module
28+
29+
error: function does not have a parameter at index 0
30+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:34:5
31+
|
32+
LL | #[rustc_intrinsic_const_vector_arg(0)]
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
LL | fn foo5();
35+
| ---------- function has 0 arguments
36+
37+
error: function does not have a parameter at index 1
38+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:39:5
39+
|
40+
LL | #[rustc_intrinsic_const_vector_arg(1)]
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42+
LL | fn foo6(a: i8x2);
43+
| ----------------- function has 1 arguments
44+
45+
error: attribute requires a parameter index
46+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:44:40
47+
|
48+
LL | #[rustc_intrinsic_const_vector_arg("bar")]
49+
| ^^^^^
50+
51+
error: function does not have a parameter at index 2
52+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:49:5
53+
|
54+
LL | #[rustc_intrinsic_const_vector_arg(0,2)]
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56+
LL | fn foo8(a: i8x2, b: i8);
57+
| ------------------------ function has 2 arguments
58+
59+
error: parameter at index 0 must be a simd type
60+
--> $DIR/rustc_intrinsic_const_vector_arg.rs:54:5
61+
|
62+
LL | #[rustc_intrinsic_const_vector_arg(0)]
63+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
64+
LL | fn foo9(a: i8);
65+
| -- parameter is a non-simd type
66+
67+
error: aborting due to 9 previous errors
68+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// compile-flags: -Z unstable-options
2+
#![feature(abi_unadjusted)]
3+
#![feature(inline_const)]
4+
#![feature(intrinsics)]
5+
#![allow(non_camel_case_types)]
6+
#![feature(repr_simd)]
7+
#![feature(rustc_attrs)]
8+
#![feature(simd_ffi)]
9+
#![allow(unused)]
10+
11+
#[repr(simd)]
12+
#[derive(Clone)]
13+
pub struct i8x2(i8, i8);
14+
15+
extern "unadjusted" {
16+
#[rustc_intrinsic_const_vector_arg(0)] // OK
17+
fn foo1(a: i8x2);
18+
}
19+
20+
extern "unadjusted" {
21+
#[rustc_intrinsic_const_vector_arg(0,1)] // OK
22+
fn foo2(a: i8x2, b: i8x2);
23+
}
24+
25+
fn main() {
26+
unsafe {
27+
foo1(i8x2(0,1)); //~ ERROR argument at index 0 must be a constant
28+
foo1({ i8x2(0,1) }); //~ ERROR argument at index 0 must be a constant
29+
foo1(const { i8x2(0,1) }); // OK
30+
31+
foo2(const { i8x2(0,1) }, { i8x2(2,3) }); //~ ERROR argument at index 1 must be a constant
32+
foo2(const { i8x2(0,1) }, const { i8x2(2,3) }); // OK
33+
}
34+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: argument at index 0 must be a constant
2+
--> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:27:9
3+
|
4+
LL | foo1(i8x2(0,1));
5+
| ^^^^^^^^^^^^^^^
6+
7+
error: argument at index 0 must be a constant
8+
--> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:28:9
9+
|
10+
LL | foo1({ i8x2(0,1) });
11+
| ^^^^^^^^^^^^^^^^^^^
12+
13+
error: argument at index 1 must be a constant
14+
--> $DIR/rustc_intrinsic_const_vector_arg_calls.rs:31:9
15+
|
16+
LL | foo2(const { i8x2(0,1) }, { i8x2(2,3) });
17+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
18+
19+
error: aborting due to 3 previous errors
20+

‎tests/ui/simd/intrinsic/inlining-issue67557-ice.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// This used to cause an ICE for an internal index out of range due to simd_shuffle_indices being
2-
// passed the wrong Instance, causing issues with inlining. See #67557.
1+
// This used to cause an ICE for an internal index out of range due to early_evaluate_const_vector
2+
// being passed the wrong Instance, causing issues with inlining. See #67557.
33
//
44
// run-pass
55
// compile-flags: -Zmir-opt-level=4

‎tests/ui/simd/intrinsic/inlining-issue67557.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// This used to cause assert_10_13 to unexpectingly fail, due to simd_shuffle_indices being passed
2-
// the wrong Instance, causing issues with inlining. See #67557.
1+
// This used to cause assert_10_13 to unexpectingly fail, due to early_evaluate_const_vector
2+
// being passed the wrong Instance, causing issues with inlining. See #67557.
33
//
44
// run-pass
55
// compile-flags: -Zmir-opt-level=4

0 commit comments

Comments
 (0)
Please sign in to comment.