forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test that target feature mix up with homogeneous floats is sound
This is basically is ripoff of src/test/ui/simd/target-feature-mixup.rs but for floats and without #[repr(simd)]
- Loading branch information
Showing
1 changed file
with
192 additions
and
0 deletions.
There are no files selected for viewing
192 changes: 192 additions & 0 deletions
192
src/test/ui/abi/homogenous-floats-target-feature-mixup.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
// This test check that even if we mixup target feature of function with homogenous floats, | ||
// the abi is sound and still produce the right answer. | ||
// | ||
// This is basically the same test as src/test/ui/simd/target-feature-mixup.rs but for floats and | ||
// without #[repr(simd)] | ||
|
||
// run-pass | ||
// ignore-emscripten | ||
// ignore-sgx no processes | ||
|
||
#![feature(avx512_target_feature)] | ||
|
||
#![allow(overflowing_literals)] | ||
#![allow(unused_variables)] | ||
|
||
use std::process::{Command, ExitStatus}; | ||
use std::env; | ||
|
||
fn main() { | ||
if let Some(level) = env::args().nth(1) { | ||
return test::main(&level) | ||
} | ||
|
||
match std::env::var("TARGET") { | ||
Ok(s) => { | ||
// Skip this tests on i586-unknown-linux-gnu where sse2 is disabled | ||
if s.contains("i586") { | ||
return | ||
} | ||
} | ||
Err(_) => return, | ||
} | ||
|
||
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 { | ||
#[derive(PartialEq, Debug, Clone, Copy)] | ||
struct f32x2(f32, f32); | ||
|
||
#[derive(PartialEq, Debug, Clone, Copy)] | ||
struct f32x4(f32, f32, f32, f32); | ||
|
||
#[derive(PartialEq, Debug, Clone, Copy)] | ||
struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); | ||
|
||
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 = f32x2(1., 2.); | ||
let m256 = f32x4(3., 4., 5., 6.); | ||
let m512 = f32x8(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: f32x2) -> f32x2 { | ||
assert_eq!(a, f32x2(1., 2.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "sse2")] | ||
unsafe fn id_sse_256(a: f32x4) -> f32x4 { | ||
assert_eq!(a, f32x4(3., 4., 5., 6.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "sse2")] | ||
unsafe fn id_sse_512(a: f32x8) -> f32x8 { | ||
assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "avx")] | ||
unsafe fn id_avx_128(a: f32x2) -> f32x2 { | ||
assert_eq!(a, f32x2(1., 2.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "avx")] | ||
unsafe fn id_avx_256(a: f32x4) -> f32x4 { | ||
assert_eq!(a, f32x4(3., 4., 5., 6.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "avx")] | ||
unsafe fn id_avx_512(a: f32x8) -> f32x8 { | ||
assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "avx512bw")] | ||
unsafe fn id_avx512_128(a: f32x2) -> f32x2 { | ||
assert_eq!(a, f32x2(1., 2.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "avx512bw")] | ||
unsafe fn id_avx512_256(a: f32x4) -> f32x4 { | ||
assert_eq!(a, f32x4(3., 4., 5., 6.)); | ||
a.clone() | ||
} | ||
|
||
#[target_feature(enable = "avx512bw")] | ||
unsafe fn id_avx512_512(a: f32x8) -> f32x8 { | ||
assert_eq!(a, f32x8(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) {} | ||
} |