diff --git a/src/compile_test.rs b/src/compile_test.rs index 0d9b3a25..9b9d277f 100644 --- a/src/compile_test.rs +++ b/src/compile_test.rs @@ -694,6 +694,7 @@ run_test! {fuzz,test1,stable} run_test! {intrinsics,addr_of,stable} run_test! {intrinsics,alloc,stable} run_test! {intrinsics,arith_offset,stable} +run_test! {intrinsics,arithmetic_misc,stable} run_test! {intrinsics,assert,stable} run_test! {intrinsics,atomics,stable} run_test! {intrinsics,bswap,stable} @@ -704,11 +705,16 @@ run_test! {intrinsics,copy_nonoverlaping,stable} run_test! {intrinsics,ctpop,stable} run_test! {intrinsics,malloc,stable} run_test! {intrinsics,offset_of,unstable} +run_test! {intrinsics,overflow_ops,stable} +run_test! {intrinsics,pow_sqrt,stable} run_test! {intrinsics,printf,stable} run_test! {intrinsics,ptr_offset_from_unsigned,stable} +run_test! {intrinsics,round,stable} run_test! {intrinsics,size_of_val,stable} run_test! {intrinsics,transmute,stable} +run_test! {intrinsics,trigonometry,stable} run_test! {intrinsics,type_id,stable} +run_test! {intrinsics,wrapping_ops,stable} run_test! {iter,fold,stable} run_test! {statics,thread_local,stable} run_test! {std,arg_test,stable} diff --git a/test/intrinsics/arithmetic_misc.rs b/test/intrinsics/arithmetic_misc.rs new file mode 100644 index 00000000..141bbb73 --- /dev/null +++ b/test/intrinsics/arithmetic_misc.rs @@ -0,0 +1,78 @@ +#![feature( + lang_items, + adt_const_params, + associated_type_defaults, + core_intrinsics, + start, + unsized_const_params +)] +#![allow(internal_features, incomplete_features, unused_variables, dead_code)] +#![no_std] +include!("../common.rs"); +extern crate core; + +use core::intrinsics::copysignf32; +use core::intrinsics::copysignf64; +use core::intrinsics::fmaf32; +use core::intrinsics::fmaf64; +use core::intrinsics::maxnumf32; +use core::intrinsics::maxnumf64; +use core::intrinsics::minnumf32; +use core::intrinsics::minnumf64; + +fn main() { + let x = 1.0_f32; + let y = 2.0_f32; + test_eq!(maxnumf32(x, y), black_box(y)); + let x = 1.0_f64; + let y = 2.0_f64; + test_eq!(maxnumf64(x, y), black_box(y)); + let x = 1.0_f32; + let y = 2.0_f32; + test_eq!(minnumf32(x, y), black_box(x)); + let x = 1.0_f64; + let y = 2.0_f64; + test_eq!(minnumf64(x, y), black_box(x)); + + let m = 10.0_f32; + let x = 4.0_f32; + let b = 60.0_f32; + let result = unsafe { fmaf32(m, x, b) }; + test_eq!(result, black_box(100.0)); + test_eq!(m * x + b, black_box(100.0)); + let one_plus_eps = 1.0_f32 + f32::EPSILON; + let one_minus_eps = 1.0_f32 - f32::EPSILON; + let minus_one = -1.0_f32; + let result = unsafe { fmaf32(one_plus_eps, one_minus_eps, minus_one) }; + // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps. + test_eq!(result, black_box(-f32::EPSILON * f32::EPSILON)); + // Different rounding with the non-fused multiply and add. + test_eq!(one_plus_eps * one_minus_eps + minus_one, black_box(0.0)); + let m = 10.0_f64; + let x = 4.0_f64; + let b = 60.0_f64; + let result = unsafe { fmaf64(m, x, b) }; + test_eq!(result, black_box(100.0)); + test_eq!(m * x + b, black_box(100.0)); + let one_plus_eps = 1.0_f64 + f64::EPSILON; + let one_minus_eps = 1.0_f64 - f64::EPSILON; + let minus_one = -1.0_f64; + let result = unsafe { fmaf64(one_plus_eps, one_minus_eps, minus_one) }; + // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps. + test_eq!(result, black_box(-f64::EPSILON * f64::EPSILON)); + // Different rounding with the non-fused multiply and add. + test_eq!(one_plus_eps * one_minus_eps + minus_one, black_box(0.0)); + + let f = 3.5_f32; + test_eq!(unsafe { copysignf32(f, 0.42) }, black_box(3.5_f32)); + test_eq!(unsafe { copysignf32(f, -0.42) }, black_box(-3.5_f32)); + test_eq!(unsafe { copysignf32(-f, 0.42) }, black_box(3.5_f32)); + test_eq!(unsafe { copysignf32(-f, -0.42) }, black_box(-3.5_f32)); + test!(unsafe { copysignf32(f32::NAN, 1.0) }.is_nan()); + let f = 3.5_f64; + test_eq!(unsafe { copysignf64(f, 0.42) }, black_box(3.5_f64)); + test_eq!(unsafe { copysignf64(f, -0.42) }, black_box(-3.5_f64)); + test_eq!(unsafe { copysignf64(-f, 0.42) }, black_box(3.5_f64)); + test_eq!(unsafe { copysignf64(-f, -0.42) }, black_box(-3.5_f64)); + test!(unsafe { copysignf64(f64::NAN, 1.0) }.is_nan()); +} diff --git a/test/intrinsics/overflow_ops.rs b/test/intrinsics/overflow_ops.rs new file mode 100644 index 00000000..e4d72da9 --- /dev/null +++ b/test/intrinsics/overflow_ops.rs @@ -0,0 +1,28 @@ +#![feature( + lang_items, + adt_const_params, + associated_type_defaults, + core_intrinsics, + start, + unsized_const_params +)] +#![allow(internal_features, incomplete_features, unused_variables, dead_code)] +#![no_std] +include!("../common.rs"); +extern crate core; + +use core::intrinsics::add_with_overflow; +use core::intrinsics::mul_with_overflow; +use core::intrinsics::sub_with_overflow; + +fn main() { + test_eq!(add_with_overflow(5u32, 2), black_box((7, false))); + test_eq!(add_with_overflow(u32::MAX, 1), black_box((0, true))); + test_eq!(sub_with_overflow(5u32, 2), black_box((3, false))); + test_eq!(sub_with_overflow(0u32, 1), black_box((u32::MAX, true))); + test_eq!(mul_with_overflow(5u32, 2), black_box((10, false))); + test_eq!( + mul_with_overflow(1_000_000_000u32, 10), + black_box((1410065408, true)) + ); +} diff --git a/test/intrinsics/pow_sqrt.rs b/test/intrinsics/pow_sqrt.rs new file mode 100644 index 00000000..e730996b --- /dev/null +++ b/test/intrinsics/pow_sqrt.rs @@ -0,0 +1,65 @@ +#![feature( + lang_items, + adt_const_params, + associated_type_defaults, + core_intrinsics, + start, + unsized_const_params +)] +#![allow(internal_features, incomplete_features, unused_variables, dead_code)] +#![no_std] +include!("../common.rs"); +extern crate core; + +// use core::intrinsics::sqrtf32; +// This intrinsic is already imported in common.rs. +use core::intrinsics::exp2f32; +use core::intrinsics::exp2f64; +use core::intrinsics::powf32; +use core::intrinsics::powf64; +use core::intrinsics::powif32; +use core::intrinsics::powif64; +use core::intrinsics::sqrtf64; + +use core::intrinsics::fabsf32; +use core::intrinsics::fabsf64; + +fn main() { + let positive = 4.0_f32; + let negative = -4.0_f32; + let negative_zero = -0.0_f32; + + test_eq!(unsafe { sqrtf32(positive) }, black_box(2.0)); + test!(unsafe { sqrtf32(negative) }.is_nan()); + test_eq!(unsafe { sqrtf32(negative_zero) }, black_box(negative_zero)); + + let positive = 4.0_f64; + let negative = -4.0_f64; + let negative_zero = -0.0_f64; + + test_eq!(unsafe { sqrtf64(positive) }, black_box(2.0)); + test!(unsafe { sqrtf64(negative) }.is_nan()); + test_eq!(unsafe { sqrtf64(negative_zero) }, black_box(negative_zero)); + + let x = 2.0_f32; + let abs_difference = unsafe { fabsf32(powf32(x, 2.0) - (x * x)) }; + test!(abs_difference <= black_box(f32::EPSILON)); + let x = 2.0_f64; + let abs_difference = unsafe { fabsf64(powf64(x, 2.0) - (x * x)) }; + test!(abs_difference <= black_box(f64::EPSILON)); + let x = 2.0_f32; + let abs_difference = unsafe { fabsf32(powif32(x, 2) - (x * x)) }; + test!(abs_difference <= black_box(f32::EPSILON)); + let x = 2.0_f64; + let abs_difference = unsafe { fabsf64(powif64(x, 2) - (x * x)) }; + test!(abs_difference <= black_box(f64::EPSILON)); + + let f = 2.0f32; + // 2^2 - 4 == 0 + let abs_difference = unsafe { fabsf32(exp2f32(f) - 4.0) }; + test!(abs_difference <= black_box(f32::EPSILON)); + let f = 2.0f64; + // 2^2 - 4 == 0 + let abs_difference = unsafe { fabsf64(exp2f64(f) - 4.0) }; + test!(abs_difference <= black_box(f64::EPSILON)); +} diff --git a/test/intrinsics/round.rs b/test/intrinsics/round.rs new file mode 100644 index 00000000..e5a030d9 --- /dev/null +++ b/test/intrinsics/round.rs @@ -0,0 +1,130 @@ +#![feature( + lang_items, + adt_const_params, + associated_type_defaults, + core_intrinsics, + start, + unsized_const_params +)] +#![allow(internal_features, incomplete_features, unused_variables, dead_code)] +#![no_std] +include!("../common.rs"); +extern crate core; + +use core::intrinsics::ceilf32; +use core::intrinsics::ceilf64; +use core::intrinsics::fabsf32; +use core::intrinsics::fabsf64; +use core::intrinsics::floorf32; +use core::intrinsics::floorf64; +use core::intrinsics::nearbyintf32; +use core::intrinsics::nearbyintf64; +use core::intrinsics::rintf32; +use core::intrinsics::rintf64; +use core::intrinsics::roundevenf32; +use core::intrinsics::roundevenf64; +use core::intrinsics::roundf32; +use core::intrinsics::roundf64; +use core::intrinsics::truncf32; +use core::intrinsics::truncf64; + +fn main() { + let x = 3.5_f32; + let y = -3.5_f32; + test_eq!(unsafe { fabsf32(x) }, black_box(x)); + test_eq!(unsafe { fabsf32(y) }, black_box(-y)); + test!(unsafe { fabsf32(f32::NAN) }.is_nan()); + let x = 3.5_f64; + let y = -3.5_f64; + test_eq!(unsafe { fabsf64(x) }, black_box(x)); + test_eq!(unsafe { fabsf64(y) }, black_box(-y)); + test!(unsafe { fabsf64(f64::NAN) }.is_nan()); + test_eq!(unsafe { nearbyintf32(2.5f32) }, black_box(2.0)); + test_eq!(unsafe { nearbyintf32(3.5f32) }, black_box(4.0)); + test_eq!(unsafe { nearbyintf64(2.5f64) }, black_box(2.0)); + test_eq!(unsafe { nearbyintf64(3.5f64) }, black_box(4.0)); + let f = 3.3_f32; + let g = -3.3_f32; + let h = 3.5_f32; + let i = 4.5_f32; + test_eq!(unsafe { rintf32(f) }, black_box(3.0)); + test_eq!(unsafe { rintf32(g) }, black_box(-3.0)); + test_eq!(unsafe { rintf32(h) }, black_box(4.0)); + test_eq!(unsafe { rintf32(i) }, black_box(4.0)); + let f = 3.3_f64; + let g = -3.3_f64; + let h = 3.5_f64; + let i = 4.5_f64; + test_eq!(unsafe { rintf64(f) }, black_box(3.0)); + test_eq!(unsafe { rintf64(g) }, black_box(-3.0)); + test_eq!(unsafe { rintf64(h) }, black_box(4.0)); + test_eq!(unsafe { rintf64(i) }, black_box(4.0)); + let f = 3.3_f32; + let g = -3.3_f32; + let h = 3.5_f32; + let i = 4.5_f32; + test_eq!(unsafe { roundevenf32(f) }, black_box(3.0)); + test_eq!(unsafe { roundevenf32(g) }, black_box(-3.0)); + test_eq!(unsafe { roundevenf32(h) }, black_box(4.0)); + test_eq!(unsafe { roundevenf32(i) }, black_box(4.0)); + let f = 3.3_f64; + let g = -3.3_f64; + let h = 3.5_f64; + let i = 4.5_f64; + test_eq!(unsafe { roundevenf64(f) }, black_box(3.0)); + test_eq!(unsafe { roundevenf64(g) }, black_box(-3.0)); + test_eq!(unsafe { roundevenf64(h) }, black_box(4.0)); + test_eq!(unsafe { roundevenf64(i) }, black_box(4.0)); + let f = 3.3_f32; + let g = -3.3_f32; + let h = -3.7_f32; + let i = 3.5_f32; + let j = 4.5_f32; + test_eq!(unsafe { roundf32(f) }, black_box(3.0)); + test_eq!(unsafe { roundf32(g) }, black_box(-3.0)); + test_eq!(unsafe { roundf32(h) }, black_box(-4.0)); + test_eq!(unsafe { roundf32(i) }, black_box(4.0)); + test_eq!(unsafe { roundf32(j) }, black_box(5.0)); + let f = 3.3_f64; + let g = -3.3_f64; + let h = -3.7_f64; + let i = 3.5_f64; + let j = 4.5_f64; + test_eq!(unsafe { roundf64(f) }, black_box(3.0)); + test_eq!(unsafe { roundf64(g) }, black_box(-3.0)); + test_eq!(unsafe { roundf64(h) }, black_box(-4.0)); + test_eq!(unsafe { roundf64(i) }, black_box(4.0)); + test_eq!(unsafe { roundf64(j) }, black_box(5.0)); + let f = 3.01_f32; + let g = 4.0_f32; + test_eq!(unsafe { ceilf32(f) }, black_box(4.0)); + test_eq!(unsafe { ceilf32(g) }, black_box(4.0)); + let f = 3.01_f64; + let g = 4.0_f64; + test_eq!(unsafe { ceilf64(f) }, black_box(4.0)); + test_eq!(unsafe { ceilf64(g) }, black_box(4.0)); + let f = 3.7_f32; + let g = 3.0_f32; + let h = -3.7_f32; + test_eq!(unsafe { floorf32(f) }, black_box(3.0)); + test_eq!(unsafe { floorf32(g) }, black_box(3.0)); + test_eq!(unsafe { floorf32(h) }, black_box(-4.0)); + let f = 3.7_f64; + let g = 3.0_f64; + let h = -3.7_f64; + test_eq!(unsafe { floorf64(f) }, black_box(3.0)); + test_eq!(unsafe { floorf64(g) }, black_box(3.0)); + test_eq!(unsafe { floorf64(h) }, black_box(-4.0)); + let f = 3.7_f32; + let g = 3.0_f32; + let h = -3.7_f32; + assert_eq!(unsafe { truncf32(f) }, black_box(3.0)); + assert_eq!(unsafe { truncf32(g) }, black_box(3.0)); + assert_eq!(unsafe { truncf32(h) }, black_box(-3.0)); + let f = 3.7_f64; + let g = 3.0_f64; + let h = -3.7_f64; + assert_eq!(unsafe { truncf64(f) }, black_box(3.0)); + assert_eq!(unsafe { truncf64(g) }, black_box(3.0)); + assert_eq!(unsafe { truncf64(h) }, black_box(-3.0)); +} diff --git a/test/intrinsics/trigonometry.rs b/test/intrinsics/trigonometry.rs new file mode 100644 index 00000000..6aa912cf --- /dev/null +++ b/test/intrinsics/trigonometry.rs @@ -0,0 +1,35 @@ +#![feature( + lang_items, + adt_const_params, + associated_type_defaults, + core_intrinsics, + start, + unsized_const_params +)] +#![allow(internal_features, incomplete_features, unused_variables, dead_code)] +#![no_std] +include!("../common.rs"); +extern crate core; + +use core::intrinsics::cosf32; +use core::intrinsics::cosf64; +use core::intrinsics::sinf32; +use core::intrinsics::sinf64; + +use core::intrinsics::fabsf32; +use core::intrinsics::fabsf64; + +fn main() { + let x = 2.0 * core::f32::consts::PI; + let abs_difference = unsafe { fabsf32(cosf32(x) - 1.0) }; + test!(abs_difference <= black_box(f32::EPSILON)); + let x = 2.0 * core::f64::consts::PI; + let abs_difference = unsafe { fabsf64(cosf64(x) - 1.0) }; + test!(abs_difference <= black_box(f64::EPSILON)); + let x = 2.0 * core::f32::consts::FRAC_PI_2; + let abs_difference = unsafe { fabsf32(sinf32(x) - 1.0) }; + test!(abs_difference <= black_box(f32::EPSILON)); + let x = 2.0 * core::f64::consts::FRAC_PI_2; + let abs_difference = unsafe { fabsf64(sinf64(x) - 1.0) }; + test!(abs_difference <= black_box(f64::EPSILON)); +} diff --git a/test/intrinsics/wrapping_ops.rs b/test/intrinsics/wrapping_ops.rs new file mode 100644 index 00000000..d4a840e8 --- /dev/null +++ b/test/intrinsics/wrapping_ops.rs @@ -0,0 +1,25 @@ +#![feature( + lang_items, + adt_const_params, + associated_type_defaults, + core_intrinsics, + start, + unsized_const_params +)] +#![allow(internal_features, incomplete_features, unused_variables, dead_code)] +#![no_std] +include!("../common.rs"); +extern crate core; + +use core::intrinsics::wrapping_add; +use core::intrinsics::wrapping_sub; +use core::intrinsics::wrapping_mul; + +fn main() { + test_eq!(wrapping_add(200u32, 55), black_box(255)); + test_eq!(wrapping_add(200u32, u32::MAX), black_box(199)); + test_eq!(wrapping_sub(100u32, 100), black_box(0)); + test_eq!(wrapping_sub(100u32, u32::MAX), black_box(101)); + test_eq!(wrapping_mul(10u8, 12), black_box(120)); + test_eq!(wrapping_mul(25u8, 12), black_box(44)); +}