@@ -739,14 +739,20 @@ fn int_abs<'tcx>(
739
739
740
740
assert_eq ! ( op_len, dest_len) ;
741
741
742
+ let zero = ImmTy :: from_int ( 0 , op. layout . field ( this, 0 ) ) ;
743
+
742
744
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) ?) ?;
744
746
let dest = this. project_index ( & dest, i) ?;
745
747
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
+ } ;
748
754
749
- this. write_scalar ( Scalar :: from_uint ( res, dest . layout . size ) , & dest) ?;
755
+ this. write_immediate ( * res, & dest) ?;
750
756
}
751
757
752
758
Ok ( ( ) )
@@ -1127,6 +1133,13 @@ fn pmulhrsw<'tcx>(
1127
1133
Ok ( ( ) )
1128
1134
}
1129
1135
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`).
1130
1143
fn pack_generic < ' tcx > (
1131
1144
this : & mut crate :: MiriInterpCx < ' _ , ' tcx > ,
1132
1145
left : & OpTy < ' tcx , Provenance > ,
0 commit comments