Skip to content

Commit 06b02da

Browse files
committed
Merge from rustc
2 parents 82ffedc + 7a1301b commit 06b02da

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

src/shims/intrinsics/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
6060
}
6161

6262
// The rest jumps to `ret` immediately.
63-
this.emulate_intrinsic_by_name(intrinsic_name, args, dest)?;
63+
this.emulate_intrinsic_by_name(intrinsic_name, instance.args, args, dest)?;
6464

6565
trace!("{:?}", this.dump_place(dest));
6666
this.go_to_block(ret);
@@ -71,6 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
7171
fn emulate_intrinsic_by_name(
7272
&mut self,
7373
intrinsic_name: &str,
74+
generic_args: ty::GenericArgsRef<'tcx>,
7475
args: &[OpTy<'tcx, Provenance>],
7576
dest: &PlaceTy<'tcx, Provenance>,
7677
) -> InterpResult<'tcx> {
@@ -80,7 +81,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
8081
return this.emulate_atomic_intrinsic(name, args, dest);
8182
}
8283
if let Some(name) = intrinsic_name.strip_prefix("simd_") {
83-
return this.emulate_simd_intrinsic(name, args, dest);
84+
return this.emulate_simd_intrinsic(name, generic_args, args, dest);
8485
}
8586

8687
match intrinsic_name {

src/shims/intrinsics/simd.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1212
fn emulate_simd_intrinsic(
1313
&mut self,
1414
intrinsic_name: &str,
15+
generic_args: ty::GenericArgsRef<'tcx>,
1516
args: &[OpTy<'tcx, Provenance>],
1617
dest: &PlaceTy<'tcx, Provenance>,
1718
) -> InterpResult<'tcx> {
@@ -488,6 +489,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
488489
this.write_immediate(*val, &dest)?;
489490
}
490491
}
492+
"shuffle_generic" => {
493+
let [left, right] = check_arg_count(args)?;
494+
let (left, left_len) = this.operand_to_simd(left)?;
495+
let (right, right_len) = this.operand_to_simd(right)?;
496+
let (dest, dest_len) = this.place_to_simd(dest)?;
497+
498+
let index = generic_args[2].expect_const().eval(*this.tcx, this.param_env(), Some(this.tcx.span)).unwrap().unwrap_branch();
499+
let index_len = index.len();
500+
501+
assert_eq!(left_len, right_len);
502+
assert_eq!(index_len as u64, dest_len);
503+
504+
for i in 0..dest_len {
505+
let src_index: u64 = index[i as usize].unwrap_leaf()
506+
.try_to_u32().unwrap()
507+
.into();
508+
let dest = this.project_index(&dest, i)?;
509+
510+
let val = if src_index < left_len {
511+
this.read_immediate(&this.project_index(&left, src_index)?)?
512+
} else if src_index < left_len.checked_add(right_len).unwrap() {
513+
let right_idx = src_index.checked_sub(left_len).unwrap();
514+
this.read_immediate(&this.project_index(&right, right_idx)?)?
515+
} else {
516+
span_bug!(
517+
this.cur_span(),
518+
"simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
519+
);
520+
};
521+
this.write_immediate(*val, &dest)?;
522+
}
523+
}
491524
"shuffle" => {
492525
let [left, right, index] = check_arg_count(args)?;
493526
let (left, left_len) = this.operand_to_simd(left)?;

tests/pass/portable-simd.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//@compile-flags: -Zmiri-strict-provenance
2-
#![feature(portable_simd, platform_intrinsics)]
2+
#![feature(portable_simd, platform_intrinsics, adt_const_params, inline_const)]
3+
#![allow(incomplete_features)]
34
use std::simd::*;
45

56
extern "platform-intrinsic" {
@@ -390,6 +391,8 @@ fn simd_intrinsics() {
390391
fn simd_reduce_any<T>(x: T) -> bool;
391392
fn simd_reduce_all<T>(x: T) -> bool;
392393
fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
394+
fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
395+
fn simd_shuffle<T, IDX, U>(x: T, y: T, idx: IDX) -> U;
393396
}
394397
unsafe {
395398
// Make sure simd_eq returns all-1 for `true`
@@ -413,6 +416,22 @@ fn simd_intrinsics() {
413416
simd_select(i8x4::from_array([0, -1, -1, 0]), b, a),
414417
i32x4::from_array([10, 2, 10, 10])
415418
);
419+
assert_eq!(
420+
simd_shuffle_generic::<_, i32x4, {&[3, 1, 0, 2]}>(a, b),
421+
a,
422+
);
423+
assert_eq!(
424+
simd_shuffle::<_, _, i32x4>(a, b, const {[3, 1, 0, 2]}),
425+
a,
426+
);
427+
assert_eq!(
428+
simd_shuffle_generic::<_, i32x4, {&[7, 5, 4, 6]}>(a, b),
429+
i32x4::from_array([4, 2, 1, 10]),
430+
);
431+
assert_eq!(
432+
simd_shuffle::<_, _, i32x4>(a, b, const {[7, 5, 4, 6]}),
433+
i32x4::from_array([4, 2, 1, 10]),
434+
);
416435
}
417436
}
418437

0 commit comments

Comments
 (0)