File: generic-arithmetic-saturating-pass.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg3-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, sid, trixie
  • size: 893,396 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (91 lines) | stat: -rw-r--r-- 3,252 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//@ run-pass
//@ ignore-emscripten

#![allow(non_camel_case_types)]
#![feature(repr_simd, intrinsics)]

#[repr(simd)]
#[derive(Copy, Clone, PartialEq, Debug)]
struct u32x4(pub [u32; 4]);

#[repr(simd)]
#[derive(Copy, Clone)]
struct I32<const N: usize>([i32; N]);

extern "rust-intrinsic" {
    fn simd_saturating_add<T>(x: T, y: T) -> T;
    fn simd_saturating_sub<T>(x: T, y: T) -> T;
}

fn main() {
    // unsigned
    {
        const M: u32 = u32::MAX;

        let a = u32x4([1, 2, 3, 4]);
        let b = u32x4([2, 4, 6, 8]);
        let m = u32x4([M, M, M, M]);
        let m1 = u32x4([M - 1, M - 1, M - 1, M - 1]);
        let z = u32x4([0, 0, 0, 0]);

        unsafe {
            assert_eq!(simd_saturating_add(z, z), z);
            assert_eq!(simd_saturating_add(z, a), a);
            assert_eq!(simd_saturating_add(b, z), b);
            assert_eq!(simd_saturating_add(a, a), b);
            assert_eq!(simd_saturating_add(a, m), m);
            assert_eq!(simd_saturating_add(m, b), m);
            assert_eq!(simd_saturating_add(m1, a), m);

            assert_eq!(simd_saturating_sub(b, z), b);
            assert_eq!(simd_saturating_sub(b, a), a);
            assert_eq!(simd_saturating_sub(a, a), z);
            assert_eq!(simd_saturating_sub(a, b), z);
            assert_eq!(simd_saturating_sub(a, m1), z);
            assert_eq!(simd_saturating_sub(b, m1), z);
        }
    }

    // signed
    {
        const MIN: i32 = i32::MIN;
        const MAX: i32 = i32::MAX;

        let a = I32::<4>([1, 2, 3, 4]);
        let b = I32::<4>([2, 4, 6, 8]);
        let c = I32::<4>([-1, -2, -3, -4]);
        let d = I32::<4>([-2, -4, -6, -8]);

        let max = I32::<4>([MAX, MAX, MAX, MAX]);
        let max1 = I32::<4>([MAX - 1, MAX - 1, MAX - 1, MAX - 1]);
        let min = I32::<4>([MIN, MIN, MIN, MIN]);
        let min1 = I32::<4>([MIN + 1, MIN + 1, MIN + 1, MIN + 1]);

        let z = I32::<4>([0, 0, 0, 0]);

        unsafe {
            assert_eq!(simd_saturating_add(z, z).0, z.0);
            assert_eq!(simd_saturating_add(z, a).0, a.0);
            assert_eq!(simd_saturating_add(b, z).0, b.0);
            assert_eq!(simd_saturating_add(a, a).0, b.0);
            assert_eq!(simd_saturating_add(a, max).0, max.0);
            assert_eq!(simd_saturating_add(max, b).0, max.0);
            assert_eq!(simd_saturating_add(max1, a).0, max.0);
            assert_eq!(simd_saturating_add(min1, z).0, min1.0);
            assert_eq!(simd_saturating_add(min, z).0, min.0);
            assert_eq!(simd_saturating_add(min1, c).0, min.0);
            assert_eq!(simd_saturating_add(min, c).0, min.0);
            assert_eq!(simd_saturating_add(min1, d).0, min.0);
            assert_eq!(simd_saturating_add(min, d).0, min.0);

            assert_eq!(simd_saturating_sub(b, z).0, b.0);
            assert_eq!(simd_saturating_sub(b, a).0, a.0);
            assert_eq!(simd_saturating_sub(a, a).0, z.0);
            assert_eq!(simd_saturating_sub(a, b).0, c.0);
            assert_eq!(simd_saturating_sub(z, max).0, min1.0);
            assert_eq!(simd_saturating_sub(min1, z).0, min1.0);
            assert_eq!(simd_saturating_sub(min1, a).0, min.0);
            assert_eq!(simd_saturating_sub(min1, b).0, min.0);
        }
    }
}