Skip to content

Commit 52dba5f

Browse files
committed
Auto merge of rust-lang#121225 - RalfJung:simd-extract-insert-const-idx, r=oli-obk,Amanieu
require simd_insert, simd_extract indices to be constants As discussed in rust-lang#77477 (see in particular [here](rust-lang#77477 (comment))). This PR doesn't touch codegen yet -- the first step is to ensure that the indices are always constants; the second step is to then make use of this fact in backends. Blocked on rust-lang/stdarch#1530 propagating to the rustc repo.
2 parents f70f19f + e19f89b commit 52dba5f

File tree

8 files changed

+37
-89
lines changed

8 files changed

+37
-89
lines changed

compiler/rustc_borrowck/messages.ftl

+7-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,13 @@ borrowck_returned_lifetime_wrong =
163163
borrowck_returned_ref_escaped =
164164
returns a reference to a captured variable which escapes the closure body
165165
166-
borrowck_simd_shuffle_last_const = last argument of `simd_shuffle` is required to be a `const` item
166+
borrowck_simd_intrinsic_arg_const =
167+
{$arg ->
168+
[1] 1st
169+
[2] 2nd
170+
[3] 3rd
171+
*[other] {$arg}th
172+
} argument of `{$intrinsic}` is required to be a `const` item
167173
168174
borrowck_suggest_create_freash_reborrow =
169175
consider reborrowing the `Pin` instead of moving it

compiler/rustc_borrowck/src/session_diagnostics.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,10 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> {
454454
}
455455

456456
#[derive(Diagnostic)]
457-
#[diag(borrowck_simd_shuffle_last_const)]
458-
pub(crate) struct SimdShuffleLastConst {
457+
#[diag(borrowck_simd_intrinsic_arg_const)]
458+
pub(crate) struct SimdIntrinsicArgConst {
459459
#[primary_span]
460460
pub span: Span,
461+
pub arg: usize,
462+
pub intrinsic: String,
461463
}

compiler/rustc_borrowck/src/type_check/mod.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ 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::{MoveUnsized, SimdIntrinsicArgConst};
5353
use crate::{
5454
borrow_set::BorrowSet,
5555
constraints::{OutlivesConstraint, OutlivesConstraintSet},
@@ -1664,9 +1664,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16641664

16651665
let func_ty = func.ty(body, self.infcx.tcx);
16661666
if let ty::FnDef(def_id, _) = *func_ty.kind() {
1667-
if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) {
1668-
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
1669-
self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span });
1667+
// Some of the SIMD intrinsics are special: they need a particular argument to be a constant.
1668+
// (Eventually this should use const-generics, but those are not up for the task yet:
1669+
// https://github.com/rust-lang/rust/issues/85229.)
1670+
if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) =
1671+
self.tcx().intrinsic(def_id)
1672+
{
1673+
let idx = match name {
1674+
sym::simd_shuffle => 2,
1675+
_ => 1,
1676+
};
1677+
if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) {
1678+
self.tcx().dcx().emit_err(SimdIntrinsicArgConst {
1679+
span: term.source_info.span,
1680+
arg: idx + 1,
1681+
intrinsic: name.to_string(),
1682+
});
16701683
}
16711684
}
16721685
}

compiler/rustc_codegen_ssa/src/mir/block.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -864,8 +864,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
864864
.map(|(i, arg)| {
865865
// The indices passed to simd_shuffle in the
866866
// third argument must be constant. This is
867-
// checked by const-qualification, which also
868-
// promotes any complex rvalues to constants.
867+
// checked by the type-checker.
869868
if i == 2 && intrinsic == sym::simd_shuffle {
870869
if let mir::Operand::Constant(constant) = &arg.node {
871870
let (llval, ty) = self.simd_shuffle_indices(bx, constant);

tests/codegen/simd-intrinsic/simd-intrinsic-generic-extract-insert.rs

-47
This file was deleted.

tests/ui/simd/array-trait.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,7 @@ extern "platform-intrinsic" {
3333
pub fn main() {
3434
let mut t = T::<i32x4>([0; 4]);
3535
unsafe {
36-
for i in 0_i32..4 {
37-
t = simd_insert(t, i as u32, i);
38-
}
39-
for i in 0_i32..4 {
40-
assert_eq!(i, simd_extract(t, i as u32));
41-
//~^ ERROR: use of moved value: `t`
42-
}
36+
t = simd_insert(t, 3, 3);
37+
assert_eq!(3, simd_extract(t, 3));
4338
}
4439
}

tests/ui/simd/array-trait.stderr

+2-14
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,6 @@ LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
2323
= help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
2424
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
2525

26-
error[E0382]: use of moved value: `t`
27-
--> $DIR/array-trait.rs:40:40
28-
|
29-
LL | let mut t = T::<i32x4>([0; 4]);
30-
| ----- move occurs because `t` has type `T<i32x4>`, which does not implement the `Copy` trait
31-
...
32-
LL | for i in 0_i32..4 {
33-
| ----------------- inside of this loop
34-
LL | assert_eq!(i, simd_extract(t, i as u32));
35-
| ^ value moved here, in previous iteration of loop
36-
37-
error: aborting due to 4 previous errors
26+
error: aborting due to 3 previous errors
3827

39-
Some errors have detailed explanations: E0077, E0382.
40-
For more information about an error, try `rustc --explain E0077`.
28+
For more information about this error, try `rustc --explain E0077`.

tests/ui/simd/array-type.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,13 @@ pub fn main() {
2222
let mut s = S([0; 4]);
2323

2424
unsafe {
25-
for i in 0_i32..4 {
26-
s = simd_insert(s, i as u32, i);
27-
}
28-
for i in 0_i32..4 {
29-
assert_eq!(i, simd_extract(s, i as u32));
30-
}
25+
s = simd_insert(s, 3, 3);
26+
assert_eq!(3, simd_extract(s, 3));
3127
}
3228

3329
let mut t = T::<4>([0; 4]);
3430
unsafe {
35-
for i in 0_i32..4 {
36-
t = simd_insert(t, i as u32, i);
37-
}
38-
for i in 0_i32..4 {
39-
assert_eq!(i, simd_extract(t, i as u32));
40-
}
31+
t = simd_insert(t, 3, 3);
32+
assert_eq!(3, simd_extract(t, 3));
4133
}
4234
}

0 commit comments

Comments
 (0)