@@ -382,7 +382,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
382
382
assert_eq ! ( dest_len, left_len) ;
383
383
assert_eq ! ( dest_len, right_len) ;
384
384
385
- let op = match intrinsic_name {
385
+ let mir_op = match intrinsic_name {
386
386
"simd_add" => BinOp :: Add ,
387
387
"simd_sub" => BinOp :: Sub ,
388
388
"simd_mul" => BinOp :: Mul ,
@@ -406,16 +406,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
406
406
let left = this. read_immediate ( & this. mplace_index ( & left, i) ?. into ( ) ) ?;
407
407
let right = this. read_immediate ( & this. mplace_index ( & right, i) ?. into ( ) ) ?;
408
408
let dest = this. mplace_index ( & dest, i) ?;
409
- let ( val, overflowed, ty) = this. overflowing_binary_op ( op , & left, & right) ?;
410
- if matches ! ( op , BinOp :: Shl | BinOp :: Shr ) {
409
+ let ( val, overflowed, ty) = this. overflowing_binary_op ( mir_op , & left, & right) ?;
410
+ if matches ! ( mir_op , BinOp :: Shl | BinOp :: Shr ) {
411
411
// Shifts have extra UB as SIMD operations that the MIR binop does not have.
412
412
// See <https://github.com/rust-lang/rust/issues/91237>.
413
413
if overflowed {
414
414
let r_val = right. to_scalar ( ) ?. to_bits ( right. layout . size ) ?;
415
415
throw_ub_format ! ( "overflowing shift by {} in `{}` in SIMD lane {}" , r_val, intrinsic_name, i) ;
416
416
}
417
417
}
418
- if matches ! ( op , BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ) {
418
+ if matches ! ( mir_op , BinOp :: Eq | BinOp :: Ne | BinOp :: Lt | BinOp :: Le | BinOp :: Gt | BinOp :: Ge ) {
419
419
// Special handling for boolean-returning operations
420
420
assert_eq ! ( ty, this. tcx. types. bool ) ;
421
421
let val = val. to_bool ( ) . unwrap ( ) ;
@@ -469,7 +469,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
469
469
}
470
470
} ;
471
471
}
472
+ this. write_immediate ( * res, dest) ?;
473
+ }
474
+ #[ rustfmt:: skip]
475
+ | "simd_reduce_add_ordered"
476
+ | "simd_reduce_mul_ordered" => {
477
+ use mir:: BinOp ;
478
+
479
+ let & [ ref op, ref init] = check_arg_count ( args) ?;
480
+ let ( op, op_len) = this. operand_to_simd ( op) ?;
481
+ let init = this. read_immediate ( init) ?;
472
482
483
+ let mir_op = match intrinsic_name {
484
+ "simd_reduce_add_ordered" => BinOp :: Add ,
485
+ "simd_reduce_mul_ordered" => BinOp :: Mul ,
486
+ _ => unreachable ! ( ) ,
487
+ } ;
488
+
489
+ let mut res = init;
490
+ for i in 0 ..op_len {
491
+ let op = this. read_immediate ( & this. mplace_index ( & op, i) ?. into ( ) ) ?;
492
+ res = this. binary_op ( mir_op, & res, & op) ?;
493
+ }
473
494
this. write_immediate ( * res, dest) ?;
474
495
}
475
496
"simd_select" => {
0 commit comments