Skip to content

Commit 8b64140

Browse files
authored
Merge pull request #50 from Oneirical/main
Assorted arithmetic intrinsics tests
2 parents 44028c1 + 593e57c commit 8b64140

File tree

7 files changed

+367
-0
lines changed

7 files changed

+367
-0
lines changed

src/compile_test.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ run_test! {fuzz,test1,stable}
694694
run_test! {intrinsics,addr_of,stable}
695695
run_test! {intrinsics,alloc,stable}
696696
run_test! {intrinsics,arith_offset,stable}
697+
run_test! {intrinsics,arithmetic_misc,stable}
697698
run_test! {intrinsics,assert,stable}
698699
run_test! {intrinsics,atomics,stable}
699700
run_test! {intrinsics,bswap,stable}
@@ -704,11 +705,16 @@ run_test! {intrinsics,copy_nonoverlaping,stable}
704705
run_test! {intrinsics,ctpop,stable}
705706
run_test! {intrinsics,malloc,stable}
706707
run_test! {intrinsics,offset_of,unstable}
708+
run_test! {intrinsics,overflow_ops,stable}
709+
run_test! {intrinsics,pow_sqrt,stable}
707710
run_test! {intrinsics,printf,stable}
708711
run_test! {intrinsics,ptr_offset_from_unsigned,stable}
712+
run_test! {intrinsics,round,stable}
709713
run_test! {intrinsics,size_of_val,stable}
710714
run_test! {intrinsics,transmute,stable}
715+
run_test! {intrinsics,trigonometry,stable}
711716
run_test! {intrinsics,type_id,stable}
717+
run_test! {intrinsics,wrapping_ops,stable}
712718
run_test! {iter,fold,stable}
713719
run_test! {statics,thread_local,stable}
714720
run_test! {std,arg_test,stable}

test/intrinsics/arithmetic_misc.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#![feature(
2+
lang_items,
3+
adt_const_params,
4+
associated_type_defaults,
5+
core_intrinsics,
6+
start,
7+
unsized_const_params
8+
)]
9+
#![allow(internal_features, incomplete_features, unused_variables, dead_code)]
10+
#![no_std]
11+
include!("../common.rs");
12+
extern crate core;
13+
14+
use core::intrinsics::copysignf32;
15+
use core::intrinsics::copysignf64;
16+
use core::intrinsics::fmaf32;
17+
use core::intrinsics::fmaf64;
18+
use core::intrinsics::maxnumf32;
19+
use core::intrinsics::maxnumf64;
20+
use core::intrinsics::minnumf32;
21+
use core::intrinsics::minnumf64;
22+
23+
fn main() {
24+
let x = 1.0_f32;
25+
let y = 2.0_f32;
26+
test_eq!(maxnumf32(x, y), black_box(y));
27+
let x = 1.0_f64;
28+
let y = 2.0_f64;
29+
test_eq!(maxnumf64(x, y), black_box(y));
30+
let x = 1.0_f32;
31+
let y = 2.0_f32;
32+
test_eq!(minnumf32(x, y), black_box(x));
33+
let x = 1.0_f64;
34+
let y = 2.0_f64;
35+
test_eq!(minnumf64(x, y), black_box(x));
36+
37+
let m = 10.0_f32;
38+
let x = 4.0_f32;
39+
let b = 60.0_f32;
40+
let result = unsafe { fmaf32(m, x, b) };
41+
test_eq!(result, black_box(100.0));
42+
test_eq!(m * x + b, black_box(100.0));
43+
let one_plus_eps = 1.0_f32 + f32::EPSILON;
44+
let one_minus_eps = 1.0_f32 - f32::EPSILON;
45+
let minus_one = -1.0_f32;
46+
let result = unsafe { fmaf32(one_plus_eps, one_minus_eps, minus_one) };
47+
// The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
48+
test_eq!(result, black_box(-f32::EPSILON * f32::EPSILON));
49+
// Different rounding with the non-fused multiply and add.
50+
test_eq!(one_plus_eps * one_minus_eps + minus_one, black_box(0.0));
51+
let m = 10.0_f64;
52+
let x = 4.0_f64;
53+
let b = 60.0_f64;
54+
let result = unsafe { fmaf64(m, x, b) };
55+
test_eq!(result, black_box(100.0));
56+
test_eq!(m * x + b, black_box(100.0));
57+
let one_plus_eps = 1.0_f64 + f64::EPSILON;
58+
let one_minus_eps = 1.0_f64 - f64::EPSILON;
59+
let minus_one = -1.0_f64;
60+
let result = unsafe { fmaf64(one_plus_eps, one_minus_eps, minus_one) };
61+
// The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
62+
test_eq!(result, black_box(-f64::EPSILON * f64::EPSILON));
63+
// Different rounding with the non-fused multiply and add.
64+
test_eq!(one_plus_eps * one_minus_eps + minus_one, black_box(0.0));
65+
66+
let f = 3.5_f32;
67+
test_eq!(unsafe { copysignf32(f, 0.42) }, black_box(3.5_f32));
68+
test_eq!(unsafe { copysignf32(f, -0.42) }, black_box(-3.5_f32));
69+
test_eq!(unsafe { copysignf32(-f, 0.42) }, black_box(3.5_f32));
70+
test_eq!(unsafe { copysignf32(-f, -0.42) }, black_box(-3.5_f32));
71+
test!(unsafe { copysignf32(f32::NAN, 1.0) }.is_nan());
72+
let f = 3.5_f64;
73+
test_eq!(unsafe { copysignf64(f, 0.42) }, black_box(3.5_f64));
74+
test_eq!(unsafe { copysignf64(f, -0.42) }, black_box(-3.5_f64));
75+
test_eq!(unsafe { copysignf64(-f, 0.42) }, black_box(3.5_f64));
76+
test_eq!(unsafe { copysignf64(-f, -0.42) }, black_box(-3.5_f64));
77+
test!(unsafe { copysignf64(f64::NAN, 1.0) }.is_nan());
78+
}

test/intrinsics/overflow_ops.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![feature(
2+
lang_items,
3+
adt_const_params,
4+
associated_type_defaults,
5+
core_intrinsics,
6+
start,
7+
unsized_const_params
8+
)]
9+
#![allow(internal_features, incomplete_features, unused_variables, dead_code)]
10+
#![no_std]
11+
include!("../common.rs");
12+
extern crate core;
13+
14+
use core::intrinsics::add_with_overflow;
15+
use core::intrinsics::mul_with_overflow;
16+
use core::intrinsics::sub_with_overflow;
17+
18+
fn main() {
19+
test_eq!(add_with_overflow(5u32, 2), black_box((7, false)));
20+
test_eq!(add_with_overflow(u32::MAX, 1), black_box((0, true)));
21+
test_eq!(sub_with_overflow(5u32, 2), black_box((3, false)));
22+
test_eq!(sub_with_overflow(0u32, 1), black_box((u32::MAX, true)));
23+
test_eq!(mul_with_overflow(5u32, 2), black_box((10, false)));
24+
test_eq!(
25+
mul_with_overflow(1_000_000_000u32, 10),
26+
black_box((1410065408, true))
27+
);
28+
}

test/intrinsics/pow_sqrt.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#![feature(
2+
lang_items,
3+
adt_const_params,
4+
associated_type_defaults,
5+
core_intrinsics,
6+
start,
7+
unsized_const_params
8+
)]
9+
#![allow(internal_features, incomplete_features, unused_variables, dead_code)]
10+
#![no_std]
11+
include!("../common.rs");
12+
extern crate core;
13+
14+
// use core::intrinsics::sqrtf32;
15+
// This intrinsic is already imported in common.rs.
16+
use core::intrinsics::exp2f32;
17+
use core::intrinsics::exp2f64;
18+
use core::intrinsics::powf32;
19+
use core::intrinsics::powf64;
20+
use core::intrinsics::powif32;
21+
use core::intrinsics::powif64;
22+
use core::intrinsics::sqrtf64;
23+
24+
use core::intrinsics::fabsf32;
25+
use core::intrinsics::fabsf64;
26+
27+
fn main() {
28+
let positive = 4.0_f32;
29+
let negative = -4.0_f32;
30+
let negative_zero = -0.0_f32;
31+
32+
test_eq!(unsafe { sqrtf32(positive) }, black_box(2.0));
33+
test!(unsafe { sqrtf32(negative) }.is_nan());
34+
test_eq!(unsafe { sqrtf32(negative_zero) }, black_box(negative_zero));
35+
36+
let positive = 4.0_f64;
37+
let negative = -4.0_f64;
38+
let negative_zero = -0.0_f64;
39+
40+
test_eq!(unsafe { sqrtf64(positive) }, black_box(2.0));
41+
test!(unsafe { sqrtf64(negative) }.is_nan());
42+
test_eq!(unsafe { sqrtf64(negative_zero) }, black_box(negative_zero));
43+
44+
let x = 2.0_f32;
45+
let abs_difference = unsafe { fabsf32(powf32(x, 2.0) - (x * x)) };
46+
test!(abs_difference <= black_box(f32::EPSILON));
47+
let x = 2.0_f64;
48+
let abs_difference = unsafe { fabsf64(powf64(x, 2.0) - (x * x)) };
49+
test!(abs_difference <= black_box(f64::EPSILON));
50+
let x = 2.0_f32;
51+
let abs_difference = unsafe { fabsf32(powif32(x, 2) - (x * x)) };
52+
test!(abs_difference <= black_box(f32::EPSILON));
53+
let x = 2.0_f64;
54+
let abs_difference = unsafe { fabsf64(powif64(x, 2) - (x * x)) };
55+
test!(abs_difference <= black_box(f64::EPSILON));
56+
57+
let f = 2.0f32;
58+
// 2^2 - 4 == 0
59+
let abs_difference = unsafe { fabsf32(exp2f32(f) - 4.0) };
60+
test!(abs_difference <= black_box(f32::EPSILON));
61+
let f = 2.0f64;
62+
// 2^2 - 4 == 0
63+
let abs_difference = unsafe { fabsf64(exp2f64(f) - 4.0) };
64+
test!(abs_difference <= black_box(f64::EPSILON));
65+
}

test/intrinsics/round.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#![feature(
2+
lang_items,
3+
adt_const_params,
4+
associated_type_defaults,
5+
core_intrinsics,
6+
start,
7+
unsized_const_params
8+
)]
9+
#![allow(internal_features, incomplete_features, unused_variables, dead_code)]
10+
#![no_std]
11+
include!("../common.rs");
12+
extern crate core;
13+
14+
use core::intrinsics::ceilf32;
15+
use core::intrinsics::ceilf64;
16+
use core::intrinsics::fabsf32;
17+
use core::intrinsics::fabsf64;
18+
use core::intrinsics::floorf32;
19+
use core::intrinsics::floorf64;
20+
use core::intrinsics::nearbyintf32;
21+
use core::intrinsics::nearbyintf64;
22+
use core::intrinsics::rintf32;
23+
use core::intrinsics::rintf64;
24+
use core::intrinsics::roundevenf32;
25+
use core::intrinsics::roundevenf64;
26+
use core::intrinsics::roundf32;
27+
use core::intrinsics::roundf64;
28+
use core::intrinsics::truncf32;
29+
use core::intrinsics::truncf64;
30+
31+
fn main() {
32+
let x = 3.5_f32;
33+
let y = -3.5_f32;
34+
test_eq!(unsafe { fabsf32(x) }, black_box(x));
35+
test_eq!(unsafe { fabsf32(y) }, black_box(-y));
36+
test!(unsafe { fabsf32(f32::NAN) }.is_nan());
37+
let x = 3.5_f64;
38+
let y = -3.5_f64;
39+
test_eq!(unsafe { fabsf64(x) }, black_box(x));
40+
test_eq!(unsafe { fabsf64(y) }, black_box(-y));
41+
test!(unsafe { fabsf64(f64::NAN) }.is_nan());
42+
test_eq!(unsafe { nearbyintf32(2.5f32) }, black_box(2.0));
43+
test_eq!(unsafe { nearbyintf32(3.5f32) }, black_box(4.0));
44+
test_eq!(unsafe { nearbyintf64(2.5f64) }, black_box(2.0));
45+
test_eq!(unsafe { nearbyintf64(3.5f64) }, black_box(4.0));
46+
let f = 3.3_f32;
47+
let g = -3.3_f32;
48+
let h = 3.5_f32;
49+
let i = 4.5_f32;
50+
test_eq!(unsafe { rintf32(f) }, black_box(3.0));
51+
test_eq!(unsafe { rintf32(g) }, black_box(-3.0));
52+
test_eq!(unsafe { rintf32(h) }, black_box(4.0));
53+
test_eq!(unsafe { rintf32(i) }, black_box(4.0));
54+
let f = 3.3_f64;
55+
let g = -3.3_f64;
56+
let h = 3.5_f64;
57+
let i = 4.5_f64;
58+
test_eq!(unsafe { rintf64(f) }, black_box(3.0));
59+
test_eq!(unsafe { rintf64(g) }, black_box(-3.0));
60+
test_eq!(unsafe { rintf64(h) }, black_box(4.0));
61+
test_eq!(unsafe { rintf64(i) }, black_box(4.0));
62+
let f = 3.3_f32;
63+
let g = -3.3_f32;
64+
let h = 3.5_f32;
65+
let i = 4.5_f32;
66+
test_eq!(unsafe { roundevenf32(f) }, black_box(3.0));
67+
test_eq!(unsafe { roundevenf32(g) }, black_box(-3.0));
68+
test_eq!(unsafe { roundevenf32(h) }, black_box(4.0));
69+
test_eq!(unsafe { roundevenf32(i) }, black_box(4.0));
70+
let f = 3.3_f64;
71+
let g = -3.3_f64;
72+
let h = 3.5_f64;
73+
let i = 4.5_f64;
74+
test_eq!(unsafe { roundevenf64(f) }, black_box(3.0));
75+
test_eq!(unsafe { roundevenf64(g) }, black_box(-3.0));
76+
test_eq!(unsafe { roundevenf64(h) }, black_box(4.0));
77+
test_eq!(unsafe { roundevenf64(i) }, black_box(4.0));
78+
let f = 3.3_f32;
79+
let g = -3.3_f32;
80+
let h = -3.7_f32;
81+
let i = 3.5_f32;
82+
let j = 4.5_f32;
83+
test_eq!(unsafe { roundf32(f) }, black_box(3.0));
84+
test_eq!(unsafe { roundf32(g) }, black_box(-3.0));
85+
test_eq!(unsafe { roundf32(h) }, black_box(-4.0));
86+
test_eq!(unsafe { roundf32(i) }, black_box(4.0));
87+
test_eq!(unsafe { roundf32(j) }, black_box(5.0));
88+
let f = 3.3_f64;
89+
let g = -3.3_f64;
90+
let h = -3.7_f64;
91+
let i = 3.5_f64;
92+
let j = 4.5_f64;
93+
test_eq!(unsafe { roundf64(f) }, black_box(3.0));
94+
test_eq!(unsafe { roundf64(g) }, black_box(-3.0));
95+
test_eq!(unsafe { roundf64(h) }, black_box(-4.0));
96+
test_eq!(unsafe { roundf64(i) }, black_box(4.0));
97+
test_eq!(unsafe { roundf64(j) }, black_box(5.0));
98+
let f = 3.01_f32;
99+
let g = 4.0_f32;
100+
test_eq!(unsafe { ceilf32(f) }, black_box(4.0));
101+
test_eq!(unsafe { ceilf32(g) }, black_box(4.0));
102+
let f = 3.01_f64;
103+
let g = 4.0_f64;
104+
test_eq!(unsafe { ceilf64(f) }, black_box(4.0));
105+
test_eq!(unsafe { ceilf64(g) }, black_box(4.0));
106+
let f = 3.7_f32;
107+
let g = 3.0_f32;
108+
let h = -3.7_f32;
109+
test_eq!(unsafe { floorf32(f) }, black_box(3.0));
110+
test_eq!(unsafe { floorf32(g) }, black_box(3.0));
111+
test_eq!(unsafe { floorf32(h) }, black_box(-4.0));
112+
let f = 3.7_f64;
113+
let g = 3.0_f64;
114+
let h = -3.7_f64;
115+
test_eq!(unsafe { floorf64(f) }, black_box(3.0));
116+
test_eq!(unsafe { floorf64(g) }, black_box(3.0));
117+
test_eq!(unsafe { floorf64(h) }, black_box(-4.0));
118+
let f = 3.7_f32;
119+
let g = 3.0_f32;
120+
let h = -3.7_f32;
121+
assert_eq!(unsafe { truncf32(f) }, black_box(3.0));
122+
assert_eq!(unsafe { truncf32(g) }, black_box(3.0));
123+
assert_eq!(unsafe { truncf32(h) }, black_box(-3.0));
124+
let f = 3.7_f64;
125+
let g = 3.0_f64;
126+
let h = -3.7_f64;
127+
assert_eq!(unsafe { truncf64(f) }, black_box(3.0));
128+
assert_eq!(unsafe { truncf64(g) }, black_box(3.0));
129+
assert_eq!(unsafe { truncf64(h) }, black_box(-3.0));
130+
}

test/intrinsics/trigonometry.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#![feature(
2+
lang_items,
3+
adt_const_params,
4+
associated_type_defaults,
5+
core_intrinsics,
6+
start,
7+
unsized_const_params
8+
)]
9+
#![allow(internal_features, incomplete_features, unused_variables, dead_code)]
10+
#![no_std]
11+
include!("../common.rs");
12+
extern crate core;
13+
14+
use core::intrinsics::cosf32;
15+
use core::intrinsics::cosf64;
16+
use core::intrinsics::sinf32;
17+
use core::intrinsics::sinf64;
18+
19+
use core::intrinsics::fabsf32;
20+
use core::intrinsics::fabsf64;
21+
22+
fn main() {
23+
let x = 2.0 * core::f32::consts::PI;
24+
let abs_difference = unsafe { fabsf32(cosf32(x) - 1.0) };
25+
test!(abs_difference <= black_box(f32::EPSILON));
26+
let x = 2.0 * core::f64::consts::PI;
27+
let abs_difference = unsafe { fabsf64(cosf64(x) - 1.0) };
28+
test!(abs_difference <= black_box(f64::EPSILON));
29+
let x = 2.0 * core::f32::consts::FRAC_PI_2;
30+
let abs_difference = unsafe { fabsf32(sinf32(x) - 1.0) };
31+
test!(abs_difference <= black_box(f32::EPSILON));
32+
let x = 2.0 * core::f64::consts::FRAC_PI_2;
33+
let abs_difference = unsafe { fabsf64(sinf64(x) - 1.0) };
34+
test!(abs_difference <= black_box(f64::EPSILON));
35+
}

test/intrinsics/wrapping_ops.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(
2+
lang_items,
3+
adt_const_params,
4+
associated_type_defaults,
5+
core_intrinsics,
6+
start,
7+
unsized_const_params
8+
)]
9+
#![allow(internal_features, incomplete_features, unused_variables, dead_code)]
10+
#![no_std]
11+
include!("../common.rs");
12+
extern crate core;
13+
14+
use core::intrinsics::wrapping_add;
15+
use core::intrinsics::wrapping_sub;
16+
use core::intrinsics::wrapping_mul;
17+
18+
fn main() {
19+
test_eq!(wrapping_add(200u32, 55), black_box(255));
20+
test_eq!(wrapping_add(200u32, u32::MAX), black_box(199));
21+
test_eq!(wrapping_sub(100u32, 100), black_box(0));
22+
test_eq!(wrapping_sub(100u32, u32::MAX), black_box(101));
23+
test_eq!(wrapping_mul(10u8, 12), black_box(120));
24+
test_eq!(wrapping_mul(25u8, 12), black_box(44));
25+
}

0 commit comments

Comments
 (0)