Skip to content

Commit 2beae13

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 c1bffa5 + 5c6caf3 commit 2beae13

File tree

1 file changed

+182
-0
lines changed

1 file changed

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

0 commit comments

Comments
 (0)