summaryrefslogtreecommitdiffstats
path: root/src/test/ui/simd/target-feature-mixup.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/simd/target-feature-mixup.rs')
-rw-r--r--src/test/ui/simd/target-feature-mixup.rs185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/test/ui/simd/target-feature-mixup.rs b/src/test/ui/simd/target-feature-mixup.rs
new file mode 100644
index 000000000..6d7688191
--- /dev/null
+++ b/src/test/ui/simd/target-feature-mixup.rs
@@ -0,0 +1,185 @@
+// run-pass
+#![allow(unused_variables)]
+#![allow(stable_features)]
+#![allow(overflowing_literals)]
+
+// ignore-emscripten
+// ignore-sgx no processes
+
+#![feature(repr_simd, target_feature, cfg_target_feature)]
+#![feature(avx512_target_feature)]
+
+use std::process::{Command, ExitStatus};
+use std::env;
+
+fn main() {
+ if let Some(level) = env::args().nth(1) {
+ return test::main(&level)
+ }
+
+ let me = env::current_exe().unwrap();
+ for level in ["sse", "avx", "avx512"].iter() {
+ let status = Command::new(&me).arg(level).status().unwrap();
+ if status.success() {
+ println!("success with {}", level);
+ continue
+ }
+
+ // We don't actually know if our computer has the requisite target features
+ // for the test below. Testing for that will get added to libstd later so
+ // for now just assume sigill means this is a machine that can't run this test.
+ if is_sigill(status) {
+ println!("sigill with {}, assuming spurious", level);
+ continue
+ }
+ panic!("invalid status at {}: {}", level, status);
+ }
+}
+
+#[cfg(unix)]
+fn is_sigill(status: ExitStatus) -> bool {
+ use std::os::unix::prelude::*;
+ status.signal() == Some(4)
+}
+
+#[cfg(windows)]
+fn is_sigill(status: ExitStatus) -> bool {
+ status.code() == Some(0xc000001d)
+}
+
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+#[allow(nonstandard_style)]
+mod test {
+ // An SSE type
+ #[repr(simd)]
+ #[derive(PartialEq, Debug, Clone, Copy)]
+ struct __m128i(u64, u64);
+
+ // An AVX type
+ #[repr(simd)]
+ #[derive(PartialEq, Debug, Clone, Copy)]
+ struct __m256i(u64, u64, u64, u64);
+
+ // An AVX-512 type
+ #[repr(simd)]
+ #[derive(PartialEq, Debug, Clone, Copy)]
+ struct __m512i(u64, u64, u64, u64, u64, u64, u64, u64);
+
+ pub fn main(level: &str) {
+ unsafe {
+ main_normal(level);
+ main_sse(level);
+ if level == "sse" {
+ return
+ }
+ main_avx(level);
+ if level == "avx" {
+ return
+ }
+ main_avx512(level);
+ }
+ }
+
+ macro_rules! mains {
+ ($(
+ $(#[$attr:meta])*
+ unsafe fn $main:ident(level: &str) {
+ ...
+ }
+ )*) => ($(
+ $(#[$attr])*
+ unsafe fn $main(level: &str) {
+ let m128 = __m128i(1, 2);
+ let m256 = __m256i(3, 4, 5, 6);
+ let m512 = __m512i(7, 8, 9, 10, 11, 12, 13, 14);
+ assert_eq!(id_sse_128(m128), m128);
+ assert_eq!(id_sse_256(m256), m256);
+ assert_eq!(id_sse_512(m512), m512);
+
+ if level == "sse" {
+ return
+ }
+ assert_eq!(id_avx_128(m128), m128);
+ assert_eq!(id_avx_256(m256), m256);
+ assert_eq!(id_avx_512(m512), m512);
+
+ if level == "avx" {
+ return
+ }
+ assert_eq!(id_avx512_128(m128), m128);
+ assert_eq!(id_avx512_256(m256), m256);
+ assert_eq!(id_avx512_512(m512), m512);
+ }
+ )*)
+ }
+
+ mains! {
+ unsafe fn main_normal(level: &str) { ... }
+ #[target_feature(enable = "sse2")]
+ unsafe fn main_sse(level: &str) { ... }
+ #[target_feature(enable = "avx")]
+ unsafe fn main_avx(level: &str) { ... }
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn main_avx512(level: &str) { ... }
+ }
+
+
+ #[target_feature(enable = "sse2")]
+ unsafe fn id_sse_128(a: __m128i) -> __m128i {
+ assert_eq!(a, __m128i(1, 2));
+ a.clone()
+ }
+
+ #[target_feature(enable = "sse2")]
+ unsafe fn id_sse_256(a: __m256i) -> __m256i {
+ assert_eq!(a, __m256i(3, 4, 5, 6));
+ a.clone()
+ }
+
+ #[target_feature(enable = "sse2")]
+ unsafe fn id_sse_512(a: __m512i) -> __m512i {
+ assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx")]
+ unsafe fn id_avx_128(a: __m128i) -> __m128i {
+ assert_eq!(a, __m128i(1, 2));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx")]
+ unsafe fn id_avx_256(a: __m256i) -> __m256i {
+ assert_eq!(a, __m256i(3, 4, 5, 6));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx")]
+ unsafe fn id_avx_512(a: __m512i) -> __m512i {
+ assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn id_avx512_128(a: __m128i) -> __m128i {
+ assert_eq!(a, __m128i(1, 2));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn id_avx512_256(a: __m256i) -> __m256i {
+ assert_eq!(a, __m256i(3, 4, 5, 6));
+ a.clone()
+ }
+
+ #[target_feature(enable = "avx512bw")]
+ unsafe fn id_avx512_512(a: __m512i) -> __m512i {
+ assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+ a.clone()
+ }
+}
+
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+mod test {
+ pub fn main(level: &str) {}
+}