]> git.lizzy.rs Git - rust.git/commitdiff
Refactor
authorgnzlbg <gonzalobg88@gmail.com>
Wed, 25 Sep 2019 10:54:23 +0000 (12:54 +0200)
committergnzlbg <gonzalobg88@gmail.com>
Wed, 25 Sep 2019 10:54:23 +0000 (12:54 +0200)
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/interpret/operand.rs
src/librustc_mir/interpret/place.rs
src/test/ui/consts/const-eval/simd/insert_extract-fail.rs
src/test/ui/consts/const-eval/simd/read_fail.rs [new file with mode: 0644]

index fc1ec61c9629ef84cc128bd044dc6255189e3436..586611397e34432200e940cdd255ae6043980124 100644 (file)
@@ -240,24 +240,55 @@ pub fn emulate_intrinsic(
                 self.copy_op_transmute(args[0], dest)?;
             }
             "simd_insert" => {
-                let mut vector = self.read_vector(args[0])?;
-                let index = self.read_scalar(args[1])?.to_u32()? as usize;
+                let index = self.read_scalar(args[1])?.to_u32()? as u64;
                 let scalar = self.read_immediate(args[2])?;
-                if vector[index].layout.size == scalar.layout.size {
-                    vector[index] = scalar;
-                } else {
-                    throw_ub_format!(
-                        "Inserting `{}` with size `{}` to a vector element place of size `{}`",
-                        scalar.layout.ty,
-                        scalar.layout.size.bytes(), vector[index].layout.size.bytes()
-                    );
+                let input = args[0];
+                let (len, e_ty) = self.read_vector_ty(input);
+                assert!(
+                    index < len,
+                    "index `{}` must be in bounds of vector type `{}`: `[0, {})`",
+                    index, e_ty, len
+                );
+                assert_eq!(
+                    args[0].layout, dest.layout,
+                    "Return type `{}` must match vector type `{}`",
+                    dest.layout.ty, input.layout.ty
+                );
+                assert_eq!(
+                    scalar.layout.ty, e_ty,
+                    "Scalar type `{}` must match vector element type `{}`",
+                    scalar.layout.ty, e_ty
+                );
+
+                for i in 0..len {
+                    let place = self.place_field(dest, index)?;
+                    if i == index {
+                        self.write_immediate(*scalar, place)?;
+                    } else {
+                        self.write_immediate(
+                            *self.read_immediate(self.operand_field(input, index)?)?,
+                            place
+                        )?;
+                    };
                 }
-                self.write_vector(vector, dest)?;
             }
             "simd_extract" => {
                 let index = self.read_scalar(args[1])?.to_u32()? as _;
-                let scalar = self.read_immediate(self.operand_field(args[0], index)?)?;
-                self.write_immediate(*scalar, dest)?;
+                let (len, e_ty) = self.read_vector_ty(args[0]);
+                assert!(
+                    index < len,
+                    "index `{}` must be in bounds of vector type `{}`: `[0, {})`",
+                    index, e_ty, len
+                );
+                assert_eq!(
+                    e_ty, dest.layout.ty,
+                    "Return type `{}` must match vector element type `{}`",
+                    dest.layout.ty, e_ty
+                );
+                self.write_immediate(
+                    *self.read_immediate(self.operand_field(args[0], index)?)?,
+                    dest
+                )?;
             }
             _ => return Ok(false),
         }
index 184e2ee9516fcb08c9900c081afa10a2966b53ad..c5771e4f34378125768fa932525f704ceb8336c3 100644 (file)
@@ -335,18 +335,15 @@ pub fn read_immediate(
         }
     }
 
-    /// Read vector from operand `op`
-    pub fn read_vector(&self, op: OpTy<'tcx, M::PointerTag>)
-                       -> InterpResult<'tcx, Vec<ImmTy<'tcx, M::PointerTag>>> {
-        if let layout::Abi::Vector { count, .. } = op.layout.abi {
-            assert_ne!(count, 0);
-            let mut scalars = Vec::new();
-            for index in 0..count {
-                scalars.push(self.read_immediate(self.operand_field(op, index as _)?)?);
-            }
-            Ok(scalars)
+    /// Read vector length and element type
+    pub fn read_vector_ty(
+        &self, op: OpTy<'tcx, M::PointerTag>
+    )
+        -> (u64, &rustc::ty::TyS<'tcx>) {
+        if let layout::Abi::Vector { .. } = op.layout.abi {
+            (op.layout.ty.simd_size(*self.tcx) as _, op.layout.ty.simd_type(*self.tcx))
         } else {
-            bug!("type is not a vector: {:?}, abi: {:?}", op.layout.ty, op.layout.abi);
+            bug!("Type `{}` is not a SIMD vector type", op.layout.ty)
         }
     }
 
index 9154e2666c598a53e89e286c8ee7597ab58a537c..c3660fb7a2e28ffe07758838cbd994fb904ece10 100644 (file)
@@ -696,40 +696,6 @@ pub fn write_immediate(
         Ok(())
     }
 
-    /// Writes the `scalar` to the `index`-th element of the `vector`.
-    pub fn write_scalar_to_vector(
-        &mut self,
-        scalar: ImmTy<'tcx, M::PointerTag>,
-        vector: PlaceTy<'tcx, M::PointerTag>,
-        index: usize,
-    ) -> InterpResult<'tcx> {
-        let index = index as u64;
-        let place = self.place_field(vector, index)?;
-        self.write_immediate(*scalar, place)?;
-        Ok(())
-    }
-
-    /// Writes the `scalars` to the `vector`.
-    pub fn write_vector(
-        &mut self,
-        scalars: Vec<ImmTy<'tcx, M::PointerTag>>,
-        vector: PlaceTy<'tcx, M::PointerTag>,
-    ) -> InterpResult<'tcx> {
-        assert_ne!(scalars.len(), 0);
-        match vector.layout.ty.sty {
-            ty::Adt(def, ..) if def.repr.simd() => {
-                let tcx = &*self.tcx;
-                let count = vector.layout.ty.simd_size(*tcx);
-                assert_eq!(count, scalars.len());
-                for index in 0..scalars.len() {
-                    self.write_scalar_to_vector(scalars[index], vector, index)?;
-                }
-            }
-            _ => bug!("not a vector"),
-        }
-        Ok(())
-    }
-
     /// Write an `Immediate` to memory.
     #[inline(always)]
     pub fn write_immediate_to_mplace(
index bbfae997e724196bc0bb5ae5a6137219a895d3b9..1d1df8d25a406e285f355bdfa6447e3e7a6338fa 100644 (file)
@@ -7,6 +7,7 @@
 
 extern "platform-intrinsic" {
     fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
+    fn simd_extract<T, U>(x: T, idx: u32) -> U;
 }
 
 const fn foo(x: i8x1) -> i8 {
@@ -14,7 +15,13 @@ const fn foo(x: i8x1) -> i8 {
     unsafe { simd_insert(x, 0_u32, 42_i16) }.0  //~ ERROR
 }
 
+const fn bar(x: i8x1) -> i16 {
+    // the i8 is not a i16:
+    unsafe { simd_extract(x, 0_u32) }  //~ ERROR
+}
+
 fn main() {
     const V: i8x1 = i8x1(13);
     const X: i8 = foo(V);
+    const Y: i16 = bar(V);
 }
diff --git a/src/test/ui/consts/const-eval/simd/read_fail.rs b/src/test/ui/consts/const-eval/simd/read_fail.rs
new file mode 100644 (file)
index 0000000..c5109c1
--- /dev/null
@@ -0,0 +1,17 @@
+#![feature(const_fn)]
+#![feature(platform_intrinsics)]
+#![allow(non_camel_case_types)]
+
+extern "platform-intrinsic" {
+    fn simd_extract<T, U>(x: T, idx: u32) -> U;
+}
+
+const fn foo(x: i8) -> i8 {
+    // i8 is not a vector type:
+    unsafe { simd_extract(x, 0_u32) }  //~ ERROR
+}
+
+fn main() {
+    const V: i8 = 13;
+    const X: i8 = foo(V);
+}