Skip to content

Commit 6ad0e9f

Browse files
committed
Prototype using const generic for simd_shuffle IDX array
1 parent 7d648de commit 6ad0e9f

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
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> {
@@ -490,6 +491,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
490491
this.write_immediate(val, &dest)?;
491492
}
492493
}
494+
"shuffle_generic" => {
495+
let [left, right] = check_arg_count(args)?;
496+
let (left, left_len) = this.operand_to_simd(left)?;
497+
let (right, right_len) = this.operand_to_simd(right)?;
498+
let (dest, dest_len) = this.place_to_simd(dest)?;
499+
500+
let index = generic_args[2].expect_const().eval(*this.tcx, this.param_env(), Some(this.tcx.span)).unwrap().unwrap_branch();
501+
let index_len = index.len();
502+
503+
assert_eq!(left_len, right_len);
504+
assert_eq!(index_len as u64, dest_len);
505+
506+
for i in 0..dest_len {
507+
let src_index: u64 = index[i as usize].unwrap_leaf()
508+
.try_to_u32().unwrap()
509+
.into();
510+
let dest = this.project_index(&dest, i)?;
511+
512+
let val = if src_index < left_len {
513+
this.read_immediate(&this.project_index(&left, src_index)?)?
514+
} else if src_index < left_len.checked_add(right_len).unwrap() {
515+
let right_idx = src_index.checked_sub(left_len).unwrap();
516+
this.read_immediate(&this.project_index(&right, right_idx)?)?
517+
} else {
518+
span_bug!(
519+
this.cur_span(),
520+
"simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
521+
);
522+
};
523+
this.write_immediate(*val, &dest)?;
524+
}
525+
}
493526
"shuffle" => {
494527
let [left, right, index] = check_arg_count(args)?;
495528
let (left, left_len) = this.operand_to_simd(left)?;

0 commit comments

Comments
 (0)