about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-28 06:42:56 +0000
committerbors <bors@rust-lang.org>2024-04-28 06:42:56 +0000
commit5c6f95ca30d62cac626f3a1ea2674a425e8bf293 (patch)
treed0ec6ddc4a1ae6b9d7d44912d1e3b1aacd3ac9d2
parent45d93945ad031b18cb723e8d4c65aa717366dd57 (diff)
parentb26153555f623b5c436695b76fa536f449fd3424 (diff)
downloadrust-5c6f95ca30d62cac626f3a1ea2674a425e8bf293.tar.gz
rust-5c6f95ca30d62cac626f3a1ea2674a425e8bf293.zip
Auto merge of #3521 - eduardosm:avx2-2, r=RalfJung
Handle post-merge comments of AVX2 PR
-rw-r--r--src/tools/miri/src/shims/x86/avx2.rs2
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs21
2 files changed, 19 insertions, 4 deletions
diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs
index bbf53f9f1e5..ba361ec6558 100644
--- a/src/tools/miri/src/shims/x86/avx2.rs
+++ b/src/tools/miri/src/shims/x86/avx2.rs
@@ -71,6 +71,8 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // There are cases like dest: i32x4, offsets: i64x2
+                // If dest has more elements than offset, extra dest elements are filled with zero.
+                // If offsets has more elements than dest, extra offsets are ignored.
                 let actual_len = dest_len.min(offsets_len);
 
                 assert_eq!(dest_len, mask_len);
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index cf4d6a04bec..9a36286a755 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -739,14 +739,20 @@ fn int_abs<'tcx>(
 
     assert_eq!(op_len, dest_len);
 
+    let zero = ImmTy::from_int(0, op.layout.field(this, 0));
+
     for i in 0..dest_len {
-        let op = this.read_scalar(&this.project_index(&op, i)?)?;
+        let op = this.read_immediate(&this.project_index(&op, i)?)?;
         let dest = this.project_index(&dest, i)?;
 
-        // Converting to a host "i128" works since the input is always signed.
-        let res = op.to_int(dest.layout.size)?.unsigned_abs();
+        let lt_zero = this.wrapping_binary_op(mir::BinOp::Lt, &op, &zero)?;
+        let res = if lt_zero.to_scalar().to_bool()? {
+            this.wrapping_unary_op(mir::UnOp::Neg, &op)?
+        } else {
+            op
+        };
 
-        this.write_scalar(Scalar::from_uint(res, dest.layout.size), &dest)?;
+        this.write_immediate(*res, &dest)?;
     }
 
     Ok(())
@@ -1127,6 +1133,13 @@ fn pmulhrsw<'tcx>(
     Ok(())
 }
 
+/// Packs two N-bit integer vectors to a single N/2-bit integers.
+///
+/// The conversion from N-bit to N/2-bit should be provided by `f`.
+///
+/// Each 128-bit chunk is treated independently (i.e., the value for
+/// the is i-th 128-bit chunk of `dest` is calculated with the i-th
+/// 128-bit chunks of `left` and `right`).
 fn pack_generic<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     left: &OpTy<'tcx, Provenance>,