Skip to content

Commit

Permalink
Rollup merge of rust-lang#101381 - Urgau:target-mixup-homogenous-floa…
Browse files Browse the repository at this point in the history
…ts, r=Amanieu

Test that target feature mix up with homogeneous floats is sound

This pull-request adds a test in `src/test/abi/` that 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](https://github.com/rust-lang/rust/blob/47d1cdb0bcac8e417071ce1929d261efe2399ae2/src/test/ui/simd/target-feature-mixup.rs) but for floats and without `#[repr(simd)]`.

*Extracted from rust-lang#97559 since I don't yet know what to do with that PR.*
  • Loading branch information
Manishearth committed Nov 9, 2022
2 parents f162e3a + 66847ff commit bd4e608
Showing 1 changed file with 192 additions and 0 deletions.
192 changes: 192 additions & 0 deletions src/test/ui/abi/homogenous-floats-target-feature-mixup.rs
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) {}
}

0 comments on commit bd4e608

Please sign in to comment.