Skip to content

Commit fdc672a

Browse files
committed
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)]
1 parent 7b69d21 commit fdc672a

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
// This test check that even if we mixup target feature of function with homogenous floats,
2+
// the abi is sound and still produce the right answer.
3+
//
4+
// This is basically the same test as src/test/ui/simd/target-feature-mixup.rs but for floats and
5+
// without #[repr(simd)]
6+
7+
// run-pass
8+
// ignore-emscripten
9+
// ignore-sgx no processes
10+
11+
#![feature(target_feature, cfg_target_feature)]
12+
#![feature(avx512_target_feature)]
13+
14+
#![allow(overflowing_literals)]
15+
#![allow(unused_variables)]
16+
#![allow(stable_features)]
17+
18+
use std::process::{Command, ExitStatus};
19+
use std::env;
20+
21+
fn main() {
22+
if let Some(level) = env::args().nth(1) {
23+
return test::main(&level)
24+
}
25+
26+
let me = env::current_exe().unwrap();
27+
for level in ["sse", "avx", "avx512"].iter() {
28+
let status = Command::new(&me).arg(level).status().unwrap();
29+
if status.success() {
30+
println!("success with {}", level);
31+
continue
32+
}
33+
34+
// We don't actually know if our computer has the requisite target features
35+
// for the test below. Testing for that will get added to libstd later so
36+
// for now just assume sigill means this is a machine that can't run this test.
37+
if is_sigill(status) {
38+
println!("sigill with {}, assuming spurious", level);
39+
continue
40+
}
41+
panic!("invalid status at {}: {}", level, status);
42+
}
43+
}
44+
45+
#[cfg(unix)]
46+
fn is_sigill(status: ExitStatus) -> bool {
47+
use std::os::unix::prelude::*;
48+
status.signal() == Some(4)
49+
}
50+
51+
#[cfg(windows)]
52+
fn is_sigill(status: ExitStatus) -> bool {
53+
status.code() == Some(0xc000001d)
54+
}
55+
56+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
57+
#[allow(nonstandard_style)]
58+
mod test {
59+
#[derive(PartialEq, Debug, Clone, Copy)]
60+
struct f32x2(f32, f32);
61+
62+
#[derive(PartialEq, Debug, Clone, Copy)]
63+
struct f32x4(f32, f32, f32, f32);
64+
65+
#[derive(PartialEq, Debug, Clone, Copy)]
66+
struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
67+
68+
pub fn main(level: &str) {
69+
unsafe {
70+
main_normal(level);
71+
main_sse(level);
72+
if level == "sse" {
73+
return
74+
}
75+
main_avx(level);
76+
if level == "avx" {
77+
return
78+
}
79+
main_avx512(level);
80+
}
81+
}
82+
83+
macro_rules! mains {
84+
($(
85+
$(#[$attr:meta])*
86+
unsafe fn $main:ident(level: &str) {
87+
...
88+
}
89+
)*) => ($(
90+
$(#[$attr])*
91+
unsafe fn $main(level: &str) {
92+
let m128 = f32x2(1., 2.);
93+
let m256 = f32x4(3., 4., 5., 6.);
94+
let m512 = f32x8(7., 8., 9., 10., 11., 12., 13., 14.);
95+
assert_eq!(id_sse_128(m128), m128);
96+
assert_eq!(id_sse_256(m256), m256);
97+
assert_eq!(id_sse_512(m512), m512);
98+
99+
if level == "sse" {
100+
return
101+
}
102+
assert_eq!(id_avx_128(m128), m128);
103+
assert_eq!(id_avx_256(m256), m256);
104+
assert_eq!(id_avx_512(m512), m512);
105+
106+
if level == "avx" {
107+
return
108+
}
109+
assert_eq!(id_avx512_128(m128), m128);
110+
assert_eq!(id_avx512_256(m256), m256);
111+
assert_eq!(id_avx512_512(m512), m512);
112+
}
113+
)*)
114+
}
115+
116+
mains! {
117+
unsafe fn main_normal(level: &str) { ... }
118+
#[target_feature(enable = "sse2")]
119+
unsafe fn main_sse(level: &str) { ... }
120+
#[target_feature(enable = "avx")]
121+
unsafe fn main_avx(level: &str) { ... }
122+
#[target_feature(enable = "avx512bw")]
123+
unsafe fn main_avx512(level: &str) { ... }
124+
}
125+
126+
#[target_feature(enable = "sse2")]
127+
unsafe fn id_sse_128(a: f32x2) -> f32x2 {
128+
assert_eq!(a, f32x2(1., 2.));
129+
a.clone()
130+
}
131+
132+
#[target_feature(enable = "sse2")]
133+
unsafe fn id_sse_256(a: f32x4) -> f32x4 {
134+
assert_eq!(a, f32x4(3., 4., 5., 6.));
135+
a.clone()
136+
}
137+
138+
#[target_feature(enable = "sse2")]
139+
unsafe fn id_sse_512(a: f32x8) -> f32x8 {
140+
assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
141+
a.clone()
142+
}
143+
144+
#[target_feature(enable = "avx")]
145+
unsafe fn id_avx_128(a: f32x2) -> f32x2 {
146+
assert_eq!(a, f32x2(1., 2.));
147+
a.clone()
148+
}
149+
150+
#[target_feature(enable = "avx")]
151+
unsafe fn id_avx_256(a: f32x4) -> f32x4 {
152+
assert_eq!(a, f32x4(3., 4., 5., 6.));
153+
a.clone()
154+
}
155+
156+
#[target_feature(enable = "avx")]
157+
unsafe fn id_avx_512(a: f32x8) -> f32x8 {
158+
assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
159+
a.clone()
160+
}
161+
162+
#[target_feature(enable = "avx512bw")]
163+
unsafe fn id_avx512_128(a: f32x2) -> f32x2 {
164+
assert_eq!(a, f32x2(1., 2.));
165+
a.clone()
166+
}
167+
168+
#[target_feature(enable = "avx512bw")]
169+
unsafe fn id_avx512_256(a: f32x4) -> f32x4 {
170+
assert_eq!(a, f32x4(3., 4., 5., 6.));
171+
a.clone()
172+
}
173+
174+
#[target_feature(enable = "avx512bw")]
175+
unsafe fn id_avx512_512(a: f32x8) -> f32x8 {
176+
assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
177+
a.clone()
178+
}
179+
}
180+
181+
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
182+
mod test {
183+
pub fn main(level: &str) {}
184+
}

0 commit comments

Comments
 (0)