rust/src/test/run-pass/simd-target-feature-mixup.rs
2018-02-17 17:38:49 +01:00

189 lines
5.3 KiB
Rust

// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-emscripten
#![feature(repr_simd, target_feature, cfg_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(bad_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) {}
}