rustc_codegen_clr
rustc_codegen_clr copied to clipboard
Add tests for more intrinsics
This is an issue tracking the progress of adding tests for each intrinsic.
The Rust language has many intrinsic functions . In order for the codegen to function propely, it has to support all of them. While many of them are already implemented, they lack tests.
How to add tests?
To add a new test to the harness, simply create a new file, named after your intrinsic, in the test/intrinsics
directory(eg. test/intrinsics/addr_of.rs
). Then, add a like this:
run_test! {intrinsics,addr_of,stable}
to src/compile_tests.rs
.
All tests run in a special, #[no_std]
enviroment, where even certain core functions are not avalible. So, each test should look like this:
#![feature(lang_items,adt_const_params,associated_type_defaults,core_intrinsics,start)]
#![allow(internal_features,incomplete_features,unused_variables,dead_code)]
#![no_std]
// Starts the test, includes some debug/test code
include!("../common.rs");
fn main(){
// test code here
}
Tests can't use assert!
, assert_eq!
or assert_ne!
. Instead, they should use test!
, test_eq!
, and test_ne!
macros. Those macros behave exactly like assert
, but they can work in the stripped-down test env. They also aid debugging, by seting .NET breakpoints, printing values using .NET builitns, etc.
In order to test an intrinisc, learn what it does from its documntation, and/or check its results in the Rust playground.
Then, use the test!
macro to check if the intrisnic gets compiled propely.
REMEMBER TO USE core::hint::black_box
TO PREVENT THE COMPILER FORM OPTIMIZING OUT THE INTRINSIC CALL!
// bad!
test_eq!(4,core::intrinsics::wrapping_add(2,2));
// ok!
test_eq!(4,core::intrinsics::wrapping_add(2,core::hint::black_box(2)));
List of intrinsics
- [x] copy_nonoverlapping Copies count * size_of::<T>() bytes from src to dst. The source and destination may overlap.
- [ ] drop_in_place Copies count * size_of::<T>() bytes from src to dst. The source and destination must not overlap.
- [x] transmute Reinterprets the bits of a value of one type as another type.
- [x] write_bytes Sets count * size_of::<T>() bytes of memory starting at dst to val.
- [x] abort Aborts the execution of the process.
- [ ] add_with_overflow Performs checked integer addition.
- [x] arith_offset Calculates the offset from a pointer, potentially wrapping.
- [ ] assert_inhabited A guard for unsafe functions that cannot ever be executed if T is uninhabited: This will statically either panic, or do nothing.
- [ ] assert_mem_uninitialized_valid A guard for std::mem::uninitialized. This will statically either panic, or do nothing.
- [ ] assert_zero_valid A guard for unsafe functions that cannot ever be executed if T does not permit zero-initialization: This will statically either panic, or do nothing.
- [ ] assume Informs the optimizer that a condition is always true. If the condition is false, the behavior is undefined.
- [ ] atomic_and_acqrel Bitwise and with the current value, returning the previous value.
- [ ] atomic_and_acquire Bitwise and with the current value, returning the previous value.
- [ ] atomic_and_relaxed Bitwise and with the current value, returning the previous value.
- [ ] atomic_and_release Bitwise and with the current value, returning the previous value.
- [ ] atomic_and_seqcst Bitwise and with the current value, returning the previous value.
- [ ] atomic_cxchg_acqrel_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_acqrel_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_acqrel_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_acquire_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_acquire_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_acquire_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_relaxed_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_relaxed_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_relaxed_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_release_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_release_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_release_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_seqcst_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_seqcst_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchg_seqcst_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_acqrel_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_acqrel_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_acqrel_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_acquire_acquire Stores a value if the current value is the same as the old value.
- [x] atomic_cxchgweak_acquire_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_acquire_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_relaxed_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_relaxed_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_relaxed_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_release_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_release_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_release_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_seqcst_acquire Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_seqcst_relaxed Stores a value if the current value is the same as the old value.
- [ ] atomic_cxchgweak_seqcst_seqcst Stores a value if the current value is the same as the old value.
- [ ] atomic_fence_acqrel An atomic fence.
- [ ] atomic_fence_acquire An atomic fence.
- [ ] atomic_fence_release An atomic fence.
- [ ] atomic_fence_seqcst An atomic fence.
- [ ] atomic_load_acquire Loads the current value of the pointer.
- [ ] atomic_load_relaxed Loads the current value of the pointer.
- [ ] atomic_load_seqcst Loads the current value of the pointer.
- [ ] atomic_load_unordered Do NOT use this intrinsic; “unordered” operations do not exist in our memory model! In terms of the Rust Abstract Machine, this operation is equivalent to src.read(), i.e., it performs a non-atomic read.
- [ ] atomic_max_acqrel Maximum with the current value using a signed comparison.
- [ ] atomic_max_acquire Maximum with the current value using a signed comparison.
- [ ] atomic_max_relaxed Maximum with the current value.
- [ ] atomic_max_release Maximum with the current value using a signed comparison.
- [ ] atomic_max_seqcst Maximum with the current value using a signed comparison.
- [ ] atomic_min_acqrel Minimum with the current value using a signed comparison.
- [ ] atomic_min_acquire Minimum with the current value using a signed comparison.
- [ ] atomic_min_relaxed Minimum with the current value using a signed comparison.
- [ ] atomic_min_release Minimum with the current value using a signed comparison.
- [ ] atomic_min_seqcst Minimum with the current value using a signed comparison.
- [ ] atomic_nand_acqrel Bitwise nand with the current value, returning the previous value.
- [ ] atomic_nand_acquire Bitwise nand with the current value, returning the previous value.
- [ ] atomic_nand_relaxed Bitwise nand with the current value, returning the previous value.
- [ ] atomic_nand_release Bitwise nand with the current value, returning the previous value.
- [ ] atomic_nand_seqcst Bitwise nand with the current value, returning the previous value.
- [ ] atomic_or_acqrel Bitwise or with the current value, returning the previous value.
- [ ] atomic_or_acquire Bitwise or with the current value, returning the previous value.
- [ ] atomic_or_relaxed Bitwise or with the current value, returning the previous value.
- [ ] atomic_or_release Bitwise or with the current value, returning the previous value.
- [ ] atomic_or_seqcst Bitwise or with the current value, returning the previous value.
- [ ] atomic_singlethreadfence_acqrel A compiler-only memory barrier.
- [ ] atomic_singlethreadfence_acquire A compiler-only memory barrier.
- [ ] atomic_singlethreadfence_release A compiler-only memory barrier.
- [ ] atomic_singlethreadfence_seqcst A compiler-only memory barrier.
- [ ] atomic_store_relaxed Stores the value at the specified memory location.
- [ ] atomic_store_release Stores the value at the specified memory location.
- [ ] atomic_store_seqcst Stores the value at the specified memory location.
- [ ] atomic_store_unordered Do NOT use this intrinsic; “unordered” operations do not exist in our memory model! In terms of the Rust Abstract Machine, this operation is equivalent to dst.write(val), i.e., it performs a non-atomic write.
- [ ] atomic_umax_acqrel Maximum with the current value using an unsigned comparison.
- [ ] atomic_umax_acquire Maximum with the current value using an unsigned comparison.
- [ ] atomic_umax_relaxed Maximum with the current value using an unsigned comparison.
- [ ] atomic_umax_release Maximum with the current value using an unsigned comparison.
- [ ] atomic_umax_seqcst Maximum with the current value using an unsigned comparison.
- [ ] atomic_umin_acqrel Minimum with the current value using an unsigned comparison.
- [ ] atomic_umin_acquire Minimum with the current value using an unsigned comparison.
- [ ] atomic_umin_relaxed Minimum with the current value using an unsigned comparison.
- [ ] atomic_umin_release Minimum with the current value using an unsigned comparison.
- [ ] atomic_umin_seqcst Minimum with the current value using an unsigned comparison.
- [ ] atomic_xadd_acqrel Adds to the current value, returning the previous value.
- [ ] atomic_xadd_acquire Adds to the current value, returning the previous value.
- [ ] atomic_xadd_relaxed Adds to the current value, returning the previous value.
- [ ] atomic_xadd_release Adds to the current value, returning the previous value.
- [ ] atomic_xadd_seqcst Adds to the current value, returning the previous value.
- [ ] atomic_xchg_acqrel Stores the value at the specified memory location, returning the old value.
- [ ] atomic_xchg_acquire Stores the value at the specified memory location, returning the old value.
- [ ] atomic_xchg_relaxed Stores the value at the specified memory location, returning the old value.
- [ ] atomic_xchg_release Stores the value at the specified memory location, returning the old value.
- [ ] atomic_xchg_seqcst Stores the value at the specified memory location, returning the old value.
- [ ] atomic_xor_acqrel Bitwise xor with the current value, returning the previous value.
- [ ] atomic_xor_acquire Bitwise xor with the current value, returning the previous value.
- [ ] atomic_xor_relaxed Bitwise xor with the current value, returning the previous value.
- [ ] atomic_xor_release Bitwise xor with the current value, returning the previous value.
- [ ] atomic_xor_seqcst Bitwise xor with the current value, returning the previous value.
- [ ] atomic_xsub_acqrel Subtract from the current value, returning the previous value.
- [ ] atomic_xsub_acquire Subtract from the current value, returning the previous value.
- [ ] atomic_xsub_relaxed Subtract from the current value, returning the previous value.
- [x] atomic_xsub_release Subtract from the current value, returning the previous value.
- [ ] atomic_xsub_seqcst Subtract from the current value, returning the previous value.
- [ ] bitreverse Reverses the bits in an integer type T.
- [x] black_box See documentation of std::hint::black_box for details.
- [x] breakpoint Executes a breakpoint trap, for inspection by a debugger.
- [x] bswap Reverses the bytes in an integer type T.
- [ ] caller_location Gets a reference to a static Location indicating where it was called.
- [ ] catch_unwind Rust’s “try catch” construct for unwinding. Invokes the function pointer try_fn with the data pointer data, and calls catch_fn if unwinding occurs while try_fn runs.
- [x] ceilf32 Returns the smallest integer greater than or equal to an f32.
- [x] ceilf64 Returns the smallest integer greater than or equal to an f64.
- [ ] compare_bytes Lexicographically compare [left, left + bytes) and [right, right + bytes) as unsigned bytes, returning negative if left is less, zero if all the bytes match, or positive if right is greater.
- [ ] const_allocate Allocates a block of memory at compile time. At runtime, just returns a null pointer.
- [ ] const_deallocate Deallocates a memory which allocated by intrinsics::const_allocate at compile time. At runtime, does nothing.
- [ ] const_eval_select Selects which function to call depending on the context.
- [x] copysignf32 Copies the sign from y to x for f32 values.
- [x] copysignf64 Copies the sign from y to x for f64 values.
- [x] cosf32 Returns the cosine of an f32.
- [x] cosf64 Returns the cosine of an f64.
- [ ] ctlz Returns the number of leading unset bits (zeroes) in an integer type T.
- [ ] ctlz_nonzero Like ctlz, but extra-unsafe as it returns undef when given an x with value 0.
- [ ] ctpop Returns the number of bits set in an integer type T
- [ ] cttz Returns the number of trailing unset bits (zeroes) in an integer type T.
- [ ] cttz_nonzero Like cttz, but extra-unsafe as it returns undef when given an x with value 0.
- [ ] discriminant_value Returns the value of the discriminant for the variant in ‘v’; if T has no discriminant, returns 0.
- [ ] exact_div Performs an exact division, resulting in undefined behavior where x % y != 0 or y == 0 or x == T::MIN && y == -1
- [ ] exp2f32 Returns 2 raised to the power of an f32.
- [ ] exp2f64 Returns 2 raised to the power of an f64.
- [ ] expf32 Returns the exponential of an f32.
- [ ] expf64 Returns the exponential of an f64.
- [ ] fabsf32 Returns the absolute value of an f32.
- [ ] fabsf64 Returns the absolute value of an f64.
- [ ] fadd_algebraic Float addition that allows optimizations based on algebraic rules.
- [ ] fadd_fast Float addition that allows optimizations based on algebraic rules. May assume inputs are finite.
- [ ] fdiv_algebraic Float division that allows optimizations based on algebraic rules.
- [ ] fdiv_fast Float division that allows optimizations based on algebraic rules. May assume inputs are finite.
- [ ] float_to_int_unchecked Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range (https://github.com/rust-lang/rust/issues/10184)
- [ ] floorf32 Returns the largest integer less than or equal to an f32.
- [ ] floorf64 Returns the largest integer less than or equal to an f64.
- [ ] fmaf32 Returns a * b + c for f32 values.
- [ ] fmaf64 Returns a * b + c for f64 values.
- [ ] fmul_algebraic Float multiplication that allows optimizations based on algebraic rules.
- [ ] fmul_fast Float multiplication that allows optimizations based on algebraic rules. May assume inputs are finite.
- [ ] forget Moves a value out of scope without running drop glue.
- [ ] frem_algebraic Float remainder that allows optimizations based on algebraic rules.
- [ ] frem_fast Float remainder that allows optimizations based on algebraic rules. May assume inputs are finite.
- [ ] fsub_algebraic Float subtraction that allows optimizations based on algebraic rules.
- [ ] fsub_fast Float subtraction that allows optimizations based on algebraic rules. May assume inputs are finite.
- [ ] is_val_statically_known Returns whether the argument’s value is statically known at compile-time.
- [ ] likely Hints to the compiler that branch condition is likely to be true. Returns the value passed to it.
- [ ] log2f32 Returns the base 2 logarithm of an f32.
- [ ] log2f64 Returns the base 2 logarithm of an f64.
- [ ] log10f32 Returns the base 10 logarithm of an f32.
- [ ] log10f64 Returns the base 10 logarithm of an f64.
- [ ] logf32 Returns the natural logarithm of an f32.
- [ ] logf64 Returns the natural logarithm of an f64.
- [x] maxnumf32 Returns the maximum of two f32 values.
- [x] maxnumf64 Returns the maximum of two f64 values.
- [ ] min_align_of The minimum alignment of a type.
- [ ] min_align_of_val The required alignment of the referenced value.
- [x] minnumf32 Returns the minimum of two f32 values.
- [x] minnumf64 Returns the minimum of two f64 values.
- [ ] mul_with_overflow Performs checked integer multiplication
- [x] nearbyintf32 Returns the nearest integer to an f32. Changing the rounding mode is not possible in Rust, so this rounds half-way cases to the number with an even least significant digit.
- [x] nearbyintf64 Returns the nearest integer to an f64. Changing the rounding mode is not possible in Rust, so this rounds half-way cases to the number with an even least significant digit.
- [ ] needs_drop Returns true if the actual type given as T requires drop glue; returns false if the actual type provided for T implements Copy.
- [ ] nontemporal_store Emits a !nontemporal store according to LLVM (see their docs). Probably will never become stable.
- [ ] offset Calculates the offset from a pointer.
- [x] powf32 Raises an f32 to an f32 power.
- [x] powf64 Raises an f64 to an f64 power.
- [x] powif32 Raises an f32 to an integer power.
- [x] powif64 Raises an f64 to an integer power.
- [ ] pref_align_of The preferred alignment of a type.
- [ ] prefetch_read_data The prefetch intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a no-op. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
- [ ] prefetch_read_instruction The prefetch intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a no-op. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
- [ ] prefetch_write_data The prefetch intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a no-op. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
- [ ] prefetch_write_instruction The prefetch intrinsic is a hint to the code generator to insert a prefetch instruction if supported; otherwise, it is a no-op. Prefetches have no effect on the behavior of the program but can change its performance characteristics.
- [ ] ptr_guaranteed_cmp See documentation of <*const T>::guaranteed_eq for details. Returns 2 if the result is unknown. Returns 1 if the pointers are guaranteed equal Returns 0 if the pointers are guaranteed inequal
- [ ] ptr_mask Masks out bits of the pointer according to a mask.
- [ ] ptr_offset_from See documentation of <*const T>::offset_from for details.
- [x] ptr_offset_from_unsigned See documentation of <*const T>::sub_ptr for details.
- [ ] raw_eq Determines whether the raw bytes of the two values are equal.
- [ ] read_via_copy This is an implementation detail of crate::ptr::read and should not be used anywhere else. See its comments for why this exists.
- [ ] retag_box_to_raw Retag a box pointer as part of casting it to a raw pointer. This is the Box equivalent of (x: &mut T) as *mut T. The input pointer must be the pointer of a Box (passed as raw pointer to avoid all questions around move semantics and custom allocators), and A must be the Box’s allocator.
- [x] rintf32 Returns the nearest integer to an f32. Changing the rounding mode is not possible in Rust, so this rounds half-way cases to the number with an even least significant digit.
- [x] rintf64 Returns the nearest integer to an f64. Changing the rounding mode is not possible in Rust, so this rounds half-way cases to the number with an even least significant digit.
- [ ] rotate_left Performs rotate left.
- [ ] rotate_right Performs rotate right.
- [x] roundevenf32 Returns the nearest integer to an f32. Rounds half-way cases to the number with an even least significant digit.
- [x] roundevenf64 Returns the nearest integer to an f64. Rounds half-way cases to the number with an even least significant digit.
- [x] roundf32 Returns the nearest integer to an f32. Rounds half-way cases away from zero.
- [x] roundf64 Returns the nearest integer to an f64. Rounds half-way cases away from zero.
- [ ] rustc_peek Magic intrinsic that derives its meaning from attributes attached to the function.
- [ ] saturating_add Computes a + b, saturating at numeric bounds.
- [ ] saturating_sub Computes a - b, saturating at numeric bounds.
- [ ] sinf32 Returns the sine of an f32.
- [ ] sinf64 Returns the sine of an f64.
- [ ] size_of The size of a type in bytes.
- [ ] size_of_val The size of the referenced value in bytes.
- [ ] sqrtf32 Returns the square root of an f32
- [ ] sqrtf64 Returns the square root of an f64
- [ ] sub_with_overflow Performs checked integer subtraction
- [ ] transmute_unchecked Like transmute, but even less checked at compile-time: rather than giving an error for size_of::<Src>() != size_of::<Dst>(), it’s Undefined Behaviour at runtime.
- [ ] truncf32 Returns the integer part of an f32.
- [ ] truncf64 Returns the integer part of an f64.
- [x] type_id Gets an identifier which is globally unique to the specified type. This function will return the same value for a type regardless of whichever crate it is invoked in.
- [ ] type_name Gets a static string slice containing the name of a type.
- [ ] unaligned_volatile_load Performs a volatile load from the src pointer The pointer is not required to be aligned.
- [ ] unaligned_volatile_store Performs a volatile store to the dst pointer. The pointer is not required to be aligned.
- [ ] unchecked_add Returns the result of an unchecked addition, resulting in undefined behavior when x + y > T::MAX or x + y < T::MIN.
- [ ] unchecked_div Performs an unchecked division, resulting in undefined behavior where y == 0 or x == T::MIN && y == -1
- [ ] unchecked_mul Returns the result of an unchecked multiplication, resulting in undefined behavior when x * y > T::MAX or x * y < T::MIN.
- [ ] unchecked_rem Returns the remainder of an unchecked division, resulting in undefined behavior when y == 0 or x == T::MIN && y == -1
- [ ] unchecked_shl Performs an unchecked left shift, resulting in undefined behavior when y < 0 or y >= N, where N is the width of T in bits.
- [ ] unchecked_shr Performs an unchecked right shift, resulting in undefined behavior when y < 0 or y >= N, where N is the width of T in bits.
- [ ] unchecked_sub Returns the result of an unchecked subtraction, resulting in undefined behavior when x - y > T::MAX or x - y < T::MIN.
- [ ] unlikely Hints to the compiler that branch condition is likely to be false. Returns the value passed to it.
- [ ] unreachable Informs the optimizer that this point in the code is not reachable, enabling further optimizations.
- [ ] variant_count Returns the number of variants of the type T cast to a usize; if T has no variants, returns 0. Uninhabited variants will be counted.
- [ ] volatile_copy_memory Equivalent to the appropriate llvm.memmove.p0i8.0i8.* intrinsic, with a size of count * size_of::<T>() and an alignment of min_align_of::<T>()
- [ ] volatile_copy_nonoverlapping_memory Equivalent to the appropriate llvm.memcpy.p0i8.0i8.* intrinsic, with a size of count * size_of::<T>() and an alignment of min_align_of::<T>()
- [ ] volatile_load Performs a volatile load from the src pointer.
- [ ] volatile_set_memory Equivalent to the appropriate llvm.memset.p0i8.* intrinsic, with a size of count * size_of::<T>() and an alignment of min_align_of::<T>().
- [ ] volatile_store Performs a volatile store to the dst pointer.
- [ ] vtable_align ptr must point to a vtable. The intrinsic will return the alignment stored in that vtable.
- [ ] vtable_size ptr must point to a vtable. The intrinsic will return the size stored in that vtable.
- [ ] wrapping_add Returns (a + b) mod 2N, where N is the width of T in bits.
- [ ] wrapping_mul Returns (a * b) mod 2N, where N is the width of T in bits.
- [ ] wrapping_sub Returns (a - b) mod 2N, where N is the width of T in bits.
- [ ] write_via_move This is an implementation detail of crate::ptr::write and should not be used anywhere else. See its comments for why this exists.