]>
Commit | Line | Data |
---|---|---|
b7449926 | 1 | // run-pass |
0531ce1d | 2 | // ignore-emscripten FIXME(#45351) hits an LLVM assert |
17df50a5 XL |
3 | // revisions: mir thir |
4 | // [thir]compile-flags: -Zthir-unsafeck | |
0531ce1d | 5 | |
e9174d1e SL |
6 | #![feature(repr_simd, platform_intrinsics, concat_idents)] |
7 | #![allow(non_camel_case_types)] | |
8 | ||
e9174d1e SL |
9 | #[repr(simd)] |
10 | #[derive(Copy, Clone)] | |
11 | struct i32x4(i32, i32, i32, i32); | |
12 | #[repr(simd)] | |
13 | #[derive(Copy, Clone)] | |
14 | struct u32x4(pub u32, pub u32, pub u32, pub u32); | |
15 | #[repr(simd)] | |
16 | #[derive(Copy, Clone)] | |
17 | struct f32x4(pub f32, pub f32, pub f32, pub f32); | |
18 | ||
19 | extern "platform-intrinsic" { | |
20 | fn simd_eq<T, U>(x: T, y: T) -> U; | |
21 | fn simd_ne<T, U>(x: T, y: T) -> U; | |
22 | fn simd_lt<T, U>(x: T, y: T) -> U; | |
23 | fn simd_le<T, U>(x: T, y: T) -> U; | |
24 | fn simd_gt<T, U>(x: T, y: T) -> U; | |
25 | fn simd_ge<T, U>(x: T, y: T) -> U; | |
26 | } | |
27 | ||
28 | macro_rules! cmp { | |
29 | ($method: ident($lhs: expr, $rhs: expr)) => {{ | |
30 | let lhs = $lhs; | |
31 | let rhs = $rhs; | |
32 | let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs); | |
33 | // assume the scalar version is correct/the behaviour we want. | |
34 | assert!((e.0 != 0) == lhs.0 .$method(&rhs.0)); | |
35 | assert!((e.1 != 0) == lhs.1 .$method(&rhs.1)); | |
36 | assert!((e.2 != 0) == lhs.2 .$method(&rhs.2)); | |
37 | assert!((e.3 != 0) == lhs.3 .$method(&rhs.3)); | |
38 | }} | |
39 | } | |
40 | macro_rules! tests { | |
41 | ($($lhs: ident, $rhs: ident;)*) => {{ | |
42 | $( | |
43 | (|| { | |
44 | cmp!(eq($lhs, $rhs)); | |
45 | cmp!(ne($lhs, $rhs)); | |
46 | ||
47 | // test both directions | |
48 | cmp!(lt($lhs, $rhs)); | |
49 | cmp!(lt($rhs, $lhs)); | |
50 | ||
51 | cmp!(le($lhs, $rhs)); | |
52 | cmp!(le($rhs, $lhs)); | |
53 | ||
54 | cmp!(gt($lhs, $rhs)); | |
55 | cmp!(gt($rhs, $lhs)); | |
56 | ||
57 | cmp!(ge($lhs, $rhs)); | |
58 | cmp!(ge($rhs, $lhs)); | |
59 | })(); | |
60 | )* | |
61 | }} | |
62 | } | |
63 | fn main() { | |
64 | // 13 vs. -100 tests that we get signed vs. unsigned comparisons | |
65 | // correct (i32: 13 > -100, u32: 13 < -100). let i1 = i32x4(10, -11, 12, 13); | |
66 | let i1 = i32x4(10, -11, 12, 13); | |
67 | let i2 = i32x4(5, -5, 20, -100); | |
68 | let i3 = i32x4(10, -11, 20, -100); | |
69 | ||
70 | let u1 = u32x4(10, !11+1, 12, 13); | |
71 | let u2 = u32x4(5, !5+1, 20, !100+1); | |
72 | let u3 = u32x4(10, !11+1, 20, !100+1); | |
73 | ||
74 | let f1 = f32x4(10.0, -11.0, 12.0, 13.0); | |
75 | let f2 = f32x4(5.0, -5.0, 20.0, -100.0); | |
76 | let f3 = f32x4(10.0, -11.0, 20.0, -100.0); | |
77 | ||
78 | unsafe { | |
79 | tests! { | |
80 | i1, i1; | |
81 | u1, u1; | |
82 | f1, f1; | |
83 | ||
84 | i1, i2; | |
85 | u1, u2; | |
86 | f1, f2; | |
87 | ||
88 | i1, i3; | |
89 | u1, u3; | |
90 | f1, f3; | |
91 | } | |
92 | } | |
93 | ||
94 | // NAN comparisons are special: | |
95 | // -11 (*) 13 | |
96 | // -5 -100 (*) | |
fc512014 | 97 | let f4 = f32x4(f32::NAN, f1.1, f32::NAN, f2.3); |
e9174d1e SL |
98 | |
99 | unsafe { | |
100 | tests! { | |
101 | f1, f4; | |
102 | f2, f4; | |
103 | f4, f4; | |
104 | } | |
105 | } | |
106 | } |