Skip to content

Commit

Permalink
Auto merge of rust-lang#121225 - RalfJung:simd-extract-insert-const-i…
Browse files Browse the repository at this point in the history
…dx, 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.
  • Loading branch information
bors committed Feb 22, 2024
2 parents f70f19f + e19f89b commit 52dba5f
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 89 deletions.
8 changes: 7 additions & 1 deletion compiler/rustc_borrowck/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,13 @@ borrowck_returned_lifetime_wrong =
borrowck_returned_ref_escaped =
returns a reference to a captured variable which escapes the closure body
borrowck_simd_shuffle_last_const = last argument of `simd_shuffle` is required to be a `const` item
borrowck_simd_intrinsic_arg_const =
{$arg ->
[1] 1st
[2] 2nd
[3] 3rd
*[other] {$arg}th
} argument of `{$intrinsic}` is required to be a `const` item
borrowck_suggest_create_freash_reborrow =
consider reborrowing the `Pin` instead of moving it
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_borrowck/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,10 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> {
}

#[derive(Diagnostic)]
#[diag(borrowck_simd_shuffle_last_const)]
pub(crate) struct SimdShuffleLastConst {
#[diag(borrowck_simd_intrinsic_arg_const)]
pub(crate) struct SimdIntrinsicArgConst {
#[primary_span]
pub span: Span,
pub arg: usize,
pub intrinsic: String,
}
21 changes: 17 additions & 4 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::MoveData;
use rustc_mir_dataflow::ResultsCursor;

use crate::session_diagnostics::{MoveUnsized, SimdShuffleLastConst};
use crate::session_diagnostics::{MoveUnsized, SimdIntrinsicArgConst};
use crate::{
borrow_set::BorrowSet,
constraints::{OutlivesConstraint, OutlivesConstraintSet},
Expand Down Expand Up @@ -1664,9 +1664,22 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {

let func_ty = func.ty(body, self.infcx.tcx);
if let ty::FnDef(def_id, _) = *func_ty.kind() {
if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) {
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span });
// Some of the SIMD intrinsics are special: they need a particular argument to be a constant.
// (Eventually this should use const-generics, but those are not up for the task yet:
// https://github.com/rust-lang/rust/issues/85229.)
if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) =
self.tcx().intrinsic(def_id)
{
let idx = match name {
sym::simd_shuffle => 2,
_ => 1,
};
if !matches!(args[idx], Spanned { node: Operand::Constant(_), .. }) {
self.tcx().dcx().emit_err(SimdIntrinsicArgConst {
span: term.source_info.span,
arg: idx + 1,
intrinsic: name.to_string(),
});
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
.map(|(i, arg)| {
// The indices passed to simd_shuffle in the
// third argument must be constant. This is
// checked by const-qualification, which also
// promotes any complex rvalues to constants.
// checked by the type-checker.
if i == 2 && intrinsic == sym::simd_shuffle {
if let mir::Operand::Constant(constant) = &arg.node {
let (llval, ty) = self.simd_shuffle_indices(bx, constant);
Expand Down

This file was deleted.

9 changes: 2 additions & 7 deletions tests/ui/simd/array-trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,7 @@ extern "platform-intrinsic" {
pub fn main() {
let mut t = T::<i32x4>([0; 4]);
unsafe {
for i in 0_i32..4 {
t = simd_insert(t, i as u32, i);
}
for i in 0_i32..4 {
assert_eq!(i, simd_extract(t, i as u32));
//~^ ERROR: use of moved value: `t`
}
t = simd_insert(t, 3, 3);
assert_eq!(3, simd_extract(t, 3));
}
}
16 changes: 2 additions & 14 deletions tests/ui/simd/array-trait.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,6 @@ LL | pub struct T<S: Simd>([S::Lane; S::SIZE]);
= help: try adding a `where` bound using this expression: `where [(); S::SIZE]:`
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0382]: use of moved value: `t`
--> $DIR/array-trait.rs:40:40
|
LL | let mut t = T::<i32x4>([0; 4]);
| ----- move occurs because `t` has type `T<i32x4>`, which does not implement the `Copy` trait
...
LL | for i in 0_i32..4 {
| ----------------- inside of this loop
LL | assert_eq!(i, simd_extract(t, i as u32));
| ^ value moved here, in previous iteration of loop

error: aborting due to 4 previous errors
error: aborting due to 3 previous errors

Some errors have detailed explanations: E0077, E0382.
For more information about an error, try `rustc --explain E0077`.
For more information about this error, try `rustc --explain E0077`.
16 changes: 4 additions & 12 deletions tests/ui/simd/array-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,13 @@ pub fn main() {
let mut s = S([0; 4]);

unsafe {
for i in 0_i32..4 {
s = simd_insert(s, i as u32, i);
}
for i in 0_i32..4 {
assert_eq!(i, simd_extract(s, i as u32));
}
s = simd_insert(s, 3, 3);
assert_eq!(3, simd_extract(s, 3));
}

let mut t = T::<4>([0; 4]);
unsafe {
for i in 0_i32..4 {
t = simd_insert(t, i as u32, i);
}
for i in 0_i32..4 {
assert_eq!(i, simd_extract(t, i as u32));
}
t = simd_insert(t, 3, 3);
assert_eq!(3, simd_extract(t, 3));
}
}

0 comments on commit 52dba5f

Please sign in to comment.