about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tests/ui/simd/intrinsic/generic-cast-pass.rs146
-rw-r--r--tests/ui/simd/intrinsic/generic-gather-pass.rs24
-rw-r--r--tests/ui/simd/issue-89193.rs11
3 files changed, 60 insertions, 121 deletions
diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs
index 15f232e2c0f..89436c83e25 100644
--- a/tests/ui/simd/intrinsic/generic-cast-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs
@@ -1,121 +1,59 @@
 // run-pass
-#![allow(unused_must_use)]
 // ignore-emscripten FIXME(#45351) hits an LLVM assert
 
-#![feature(repr_simd, platform_intrinsics, concat_idents, test)]
-#![allow(non_camel_case_types)]
-
-extern crate test;
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct i32x4(i32, i32, i32, i32);
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct i8x4(i8, i8, i8, i8);
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct u32x4(u32, u32, u32, u32);
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct u8x4(u8, u8, u8, u8);
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct f32x4(f32, f32, f32, f32);
-
-#[repr(simd)]
-#[derive(PartialEq, Debug)]
-struct f64x4(f64, f64, f64, f64);
-
+#![feature(repr_simd, platform_intrinsics)]
 
 extern "platform-intrinsic" {
     fn simd_cast<T, U>(x: T) -> U;
 }
 
-const A: i32 = -1234567;
-const B: i32 = 12345678;
-const C: i32 = -123456789;
-const D: i32 = 1234567890;
+use std::cmp::{max, min};
 
-trait Foo {
-    fn is_float() -> bool { false }
-    fn in_range(x: i32) -> bool;
-}
-impl Foo for i32 {
-    fn in_range(_: i32) -> bool { true }
-}
-impl Foo for i8 {
-    fn in_range(x: i32) -> bool { -128 <= x && x < 128 }
-}
-impl Foo for u32 {
-    fn in_range(x: i32) -> bool { 0 <= x }
-}
-impl Foo for u8 {
-    fn in_range(x: i32) -> bool { 0 <= x && x < 128 }
-}
-impl Foo for f32 {
-    fn is_float() -> bool { true }
-    fn in_range(_: i32) -> bool { true }
-}
-impl Foo for f64 {
-    fn is_float() -> bool { true }
-    fn in_range(_: i32) -> bool { true }
-}
+#[derive(Copy, Clone)]
+#[repr(simd)]
+struct V<T>([T; 2]);
 
 fn main() {
-    macro_rules! test {
-        ($from: ident, $to: ident) => {{
-            // force the casts to actually happen, or else LLVM/rustc
-            // may fold them and get slightly different results.
-            let (a, b, c, d) = test::black_box((A as $from, B as $from, C as $from, D as $from));
-            // the SIMD vectors are all FOOx4, so we can concat_idents
-            // so we don't have to pass in the extra args to the macro
-            let mut from = simd_cast(concat_idents!($from, x4)(a, b, c, d));
-            let mut to = concat_idents!($to, x4)(a as $to,
-                                                 b as $to,
-                                                 c as $to,
-                                                 d as $to);
-            // assist type inference, it needs to know what `from` is
-            // for the `if` statements.
-            to == from;
+    unsafe {
+        let u = V::<u32>([i16::MIN as u32, i16::MAX as u32]);
+        let i: V<i16> = simd_cast(u);
+        assert_eq!(i.0[0], u.0[0] as i16);
+        assert_eq!(i.0[1], u.0[1] as i16);
+    }
 
-            // there are platform differences for some out of range
-            // casts, so we just normalize such things: it's OK for
-            // "invalid" calculations to result in nonsense answers.
-            // (e.g., negative float to unsigned integer goes through a
-            // library routine on the default i686 platforms, and the
-            // implementation of that routine differs on e.g., Linux
-            // vs. macOS, resulting in different answers.)
-            if $from::is_float() {
-                if !$to::in_range(A) { from.0 = 0 as $to; to.0 = 0 as $to; }
-                if !$to::in_range(B) { from.1 = 0 as $to; to.1 = 0 as $to; }
-                if !$to::in_range(C) { from.2 = 0 as $to; to.2 = 0 as $to; }
-                if !$to::in_range(D) { from.3 = 0 as $to; to.3 = 0 as $to; }
-            }
+    unsafe {
+        let f = V::<f32>([i16::MIN as f32, i16::MAX as f32]);
+        let i: V<i16> = simd_cast(f);
+        assert_eq!(i.0[0], f.0[0] as i16);
+        assert_eq!(i.0[1], f.0[1] as i16);
+    }
 
-            assert!(to == from,
-                    "{} -> {} ({:?} != {:?})", stringify!($from), stringify!($to),
-                    from, to);
-        }}
+    unsafe {
+        let f = V::<f32>([u8::MIN as f32, u8::MAX as f32]);
+        let u: V<u8> = simd_cast(f);
+        assert_eq!(u.0[0], f.0[0] as u8);
+        assert_eq!(u.0[1], f.0[1] as u8);
     }
-    macro_rules! tests {
-        (: $($to: ident),*) => { () };
-        // repeating the list twice is easier than writing a cartesian
-        // product macro
-        ($from: ident $(, $from_: ident)*: $($to: ident),*) => {
-            fn $from() { unsafe { $( test!($from, $to); )* } }
-            tests!($($from_),*: $($to),*)
-        };
-        ($($types: ident),*) => {{
-            tests!($($types),* : $($types),*);
-            $($types();)*
-        }}
+
+    unsafe {
+        // We would like to do isize::MIN..=isize::MAX, but those values are not representable in
+        // an f64, so we clamp to the range of an i32 to prevent running into UB.
+        let f = V::<f64>([
+            max(isize::MIN, i32::MIN as isize) as f64,
+            min(isize::MAX, i32::MAX as isize) as f64,
+        ]);
+        let i: V<isize> = simd_cast(f);
+        assert_eq!(i.0[0], f.0[0] as isize);
+        assert_eq!(i.0[1], f.0[1] as isize);
     }
 
-    // test various combinations, including truncation,
-    // signed/unsigned extension, and floating point casts.
-    tests!(i32, i8, u32, u8, f32);
-    tests!(i32, u32, f32, f64)
+    unsafe {
+        let f = V::<f64>([
+            max(usize::MIN, u32::MIN as usize) as f64,
+            min(usize::MAX, u32::MAX as usize) as f64,
+        ]);
+        let u: V<usize> = simd_cast(f);
+        assert_eq!(u.0[0], f.0[0] as usize);
+        assert_eq!(u.0[1], f.0[1] as usize);
+    }
 }
diff --git a/tests/ui/simd/intrinsic/generic-gather-pass.rs b/tests/ui/simd/intrinsic/generic-gather-pass.rs
index 805caebe5b1..7d4b3dbd7b4 100644
--- a/tests/ui/simd/intrinsic/generic-gather-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-gather-pass.rs
@@ -24,9 +24,9 @@ fn main() {
 
     // reading from *const
     unsafe {
-        let pointer = &x[0] as *const f32;
+        let pointer = x.as_ptr();
         let pointers =  x4(
-            pointer.offset(0) as *const f32,
+            pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
@@ -39,9 +39,9 @@ fn main() {
 
     // reading from *mut
     unsafe {
-        let pointer = &mut x[0] as *mut f32;
+        let pointer = x.as_mut_ptr();
         let pointers = x4(
-            pointer.offset(0) as *mut f32,
+            pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
@@ -54,9 +54,9 @@ fn main() {
 
     // writing to *mut
     unsafe {
-        let pointer = &mut x[0] as *mut f32;
+        let pointer = x.as_mut_ptr();
         let pointers = x4(
-            pointer.offset(0) as *mut f32,
+            pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
@@ -85,9 +85,9 @@ fn main() {
 
     // reading from *const
     unsafe {
-        let pointer = &y[0] as *const *const f32;
+        let pointer = y.as_ptr();
         let pointers = x4(
-            pointer.offset(0) as *const *const f32,
+            pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
@@ -100,9 +100,9 @@ fn main() {
 
     // reading from *mut
     unsafe {
-        let pointer = &mut y[0] as *mut *const f32;
+        let pointer = y.as_mut_ptr();
         let pointers = x4(
-            pointer.offset(0) as *mut *const f32,
+            pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
@@ -115,9 +115,9 @@ fn main() {
 
     // writing to *mut
     unsafe {
-        let pointer = &mut y[0] as *mut *const f32;
+        let pointer = y.as_mut_ptr();
         let pointers = x4(
-            pointer.offset(0) as *mut *const f32,
+            pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs
index 79c4e6a312c..cd24d6675b2 100644
--- a/tests/ui/simd/issue-89193.rs
+++ b/tests/ui/simd/issue-89193.rs
@@ -17,13 +17,14 @@ extern "platform-intrinsic" {
 fn main() {
     let x: [usize; 4] = [10, 11, 12, 13];
     let default = x4(0_usize, 1, 2, 3);
-    let mask = x4(1_i32, 1, 1, 1);
+    let all_set = u8::MAX as i8; // aka -1
+    let mask = x4(all_set, all_set, all_set, all_set);
     let expected = x4(10_usize, 11, 12, 13);
 
     unsafe {
-        let pointer = &x[0] as *const usize;
+        let pointer = x.as_ptr();
         let pointers =  x4(
-            pointer.offset(0) as *const usize,
+            pointer.offset(0),
             pointer.offset(1),
             pointer.offset(2),
             pointer.offset(3)
@@ -38,9 +39,9 @@ fn main() {
     let expected = x4(10_isize, 11, 12, 13);
 
     unsafe {
-        let pointer = &x[0] as *const isize;
+        let pointer = x.as_ptr();
         let pointers =  x4(
-            pointer.offset(0) as *const isize,
+            pointer.offset(0),
             pointer.offset(1),
             pointer.offset(2),
             pointer.offset(3)