Skip to content

Commit bd4e608

Browse files
authored
Rollup merge of rust-lang#101381 - Urgau:target-mixup-homogenous-floats, 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.*
2 parents f162e3a + 66847ff commit bd4e608

File tree

1 file changed

+192
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)