@@ -739,14 +739,20 @@ fn int_abs<'tcx>(
739739
740740 assert_eq ! ( op_len, dest_len) ;
741741
742+ let zero = ImmTy :: from_int ( 0 , op. layout . field ( this, 0 ) ) ;
743+
742744 for i in 0 ..dest_len {
743- let op = this. read_scalar ( & this. project_index ( & op, i) ?) ?;
745+ let op = this. read_immediate ( & this. project_index ( & op, i) ?) ?;
744746 let dest = this. project_index ( & dest, i) ?;
745747
746- // Converting to a host "i128" works since the input is always signed.
747- let res = op. to_int ( dest. layout . size ) ?. unsigned_abs ( ) ;
748+ let lt_zero = this. wrapping_binary_op ( mir:: BinOp :: Lt , & op, & zero) ?;
749+ let res = if lt_zero. to_scalar ( ) . to_bool ( ) ? {
750+ this. wrapping_unary_op ( mir:: UnOp :: Neg , & op) ?
751+ } else {
752+ op
753+ } ;
748754
749- this. write_scalar ( Scalar :: from_uint ( res, dest . layout . size ) , & dest) ?;
755+ this. write_immediate ( * res, & dest) ?;
750756 }
751757
752758 Ok ( ( ) )
@@ -1127,6 +1133,13 @@ fn pmulhrsw<'tcx>(
11271133 Ok ( ( ) )
11281134}
11291135
1136+ /// Packs two N-bit integer vectors to a single N/2-bit integers.
1137+ ///
1138+ /// The conversion from N-bit to N/2-bit should be provided by `f`.
1139+ ///
1140+ /// Each 128-bit chunk is treated independently (i.e., the value for
1141+ /// the is i-th 128-bit chunk of `dest` is calculated with the i-th
1142+ /// 128-bit chunks of `left` and `right`).
11301143fn pack_generic < ' tcx > (
11311144 this : & mut crate :: MiriInterpCx < ' _ , ' tcx > ,
11321145 left : & OpTy < ' tcx , Provenance > ,
0 commit comments