Skip to content

Compiler Intrinsics #658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
philberty opened this issue Sep 8, 2021 · 1 comment
Open

Compiler Intrinsics #658

philberty opened this issue Sep 8, 2021 · 1 comment

Comments

@philberty
Copy link
Member

philberty commented Sep 8, 2021

We need to support the extern "rust-intrinsics" GCC seems to have something at least pretty similar to a lot of these not 100% about all of them, things like transmute look more custom to rust.

https://github.com/rust-lang/rust/blob/master/library/core/src/intrinsics.rs
https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs

  • atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
  • atomic_load_seqcst<T: Copy>(src: *const T) -> T;
  • atomic_load_acquire<T: Copy>(src: *const T) -> T;
  • atomic_load_relaxed<T: Copy>(src: *const T) -> T;
  • atomic_load_unordered<T: Copy>(src: *const T) -> T;
  • atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
  • atomic_store_release<T: Copy>(dst: *mut T, val: T);
  • atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
  • atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
  • atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
  • atomic_fence_seqcst();
  • atomic_fence_acquire();
  • atomic_fence_release();
  • atomic_fence_acqrel();
  • atomic_singlethreadfence_seqcst();
  • atomic_singlethreadfence_acquire();
  • atomic_singlethreadfence_release();
  • atomic_singlethreadfence_acqrel();
  • prefetch_read_data<T>(data: *const T, locality: i32);
  • prefetch_write_data<T>(data: *const T, locality: i32);
  • prefetch_read_instruction<T>(data: *const T, locality: i32);
  • prefetch_write_instruction<T>(data: *const T, locality: i32);
  • rustc_peek<T>(_: T) -> T;
  • abort() -> !;
  • unreachable() -> !;
  • assume(b: bool); Implement assume(b: bool); intrinsic #1561
  • likely(b: bool) -> bool;
  • unlikely(b: bool) -> bool;
  • breakpoint();
  • size_of<T>() -> usize;
  • min_align_of<T>() -> usize;
  • pref_align_of<T>() -> usize;
  • size_of_val<T: ?Sized>(_: *const T) -> usize;
  • min_align_of_val<T: ?Sized>(_: *const T) -> usize;
  • type_name<T: ?Sized>() -> &'static str;
  • type_id<T: ?Sized + 'static>() -> u64;
  • assert_inhabited<T>();
  • assert_zero_valid<T>();
  • assert_uninit_valid<T>();
  • caller_location() -> &'static crate::panic::Location<'static>;
  • forget<T: ?Sized>(_: T);
  • transmute<T, U>(e: T) -> U;
  • needs_drop<T: ?Sized>() -> bool;
  • offset<T>(dst: *const T, offset: isize) -> *const T;
  • arith_offset<T>(dst: *const T, offset: isize) -> *const T;
  • volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
  • volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
  • volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
  • volatile_load<T>(src: *const T) -> T;
  • volatile_store<T>(dst: *mut T, val: T);
  • unaligned_volatile_load<T>(src: *const T) -> T;
  • unaligned_volatile_store<T>(dst: *mut T, val: T);
  • sqrtf32(x: f32) -> f32;
  • sqrtf64(x: f64) -> f64;
  • powif32(a: f32, x: i32) -> f32;
  • powif64(a: f64, x: i32) -> f64;
  • sinf32(x: f32) -> f32;
  • sinf64(x: f64) -> f64;
  • cosf32(x: f32) -> f32;
  • cosf64(x: f64) -> f64;
  • powf32(a: f32, x: f32) -> f32;
  • powf64(a: f64, x: f64) -> f64;
  • expf32(x: f32) -> f32;
  • expf64(x: f64) -> f64;
  • exp2f32(x: f32) -> f32;
  • exp2f64(x: f64) -> f64;
  • logf32(x: f32) -> f32;
  • logf64(x: f64) -> f64;
  • log10f32(x: f32) -> f32;
  • log10f64(x: f64) -> f64;
  • log2f32(x: f32) -> f32;
  • log2f64(x: f64) -> f64;
  • fmaf32(a: f32, b: f32, c: f32) -> f32;
  • fmaf64(a: f64, b: f64, c: f64) -> f64;
  • fabsf32(x: f32) -> f32;
  • fabsf64(x: f64) -> f64;
  • minnumf32(x: f32, y: f32) -> f32;
  • minnumf64(x: f64, y: f64) -> f64;
  • maxnumf32(x: f32, y: f32) -> f32;
  • maxnumf64(x: f64, y: f64) -> f64;
  • copysignf32(x: f32, y: f32) -> f32;
  • copysignf64(x: f64, y: f64) -> f64;
  • floorf32(x: f32) -> f32;
  • floorf64(x: f64) -> f64;
  • ceilf32(x: f32) -> f32;
  • ceilf64(x: f64) -> f64;
  • truncf32(x: f32) -> f32;
  • truncf64(x: f64) -> f64;
  • rintf32(x: f32) -> f32;
  • rintf64(x: f64) -> f64;
  • nearbyintf32(x: f32) -> f32;
  • nearbyintf64(x: f64) -> f64;
  • roundf32(x: f32) -> f32;
  • roundf64(x: f64) -> f64;
  • fadd_fast<T: Copy>(a: T, b: T) -> T;
  • fsub_fast<T: Copy>(a: T, b: T) -> T;
  • fmul_fast<T: Copy>(a: T, b: T) -> T;
  • fdiv_fast<T: Copy>(a: T, b: T) -> T;
  • frem_fast<T: Copy>(a: T, b: T) -> T;
  • float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
  • ctpop<T: Copy>(x: T) -> T;
  • ctlz<T: Copy>(x: T) -> T;
  • ctlz_nonzero<T: Copy>(x: T) -> T;
  • cttz<T: Copy>(x: T) -> T;
  • cttz_nonzero<T: Copy>(x: T) -> T;
  • bswap<T: Copy>(x: T) -> T;
  • bitreverse<T: Copy>(x: T) -> T;
  • add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
  • sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
  • mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
  • exact_div<T: Copy>(x: T, y: T) -> T;
  • unchecked_div<T: Copy>(x: T, y: T) -> T;
  • unchecked_rem<T: Copy>(x: T, y: T) -> T;
  • unchecked_shl<T: Copy>(x: T, y: T) -> T;
  • unchecked_shr<T: Copy>(x: T, y: T) -> T;
  • unchecked_add<T: Copy>(x: T, y: T) -> T;
  • unchecked_sub<T: Copy>(x: T, y: T) -> T;
  • unchecked_mul<T: Copy>(x: T, y: T) -> T;
  • rotate_left<T: Copy>(x: T, y: T) -> T;
  • rotate_right<T: Copy>(x: T, y: T) -> T;
  • wrapping_add<T: Copy>(a: T, b: T) -> T;
  • wrapping_sub<T: Copy>(a: T, b: T) -> T;
  • wrapping_mul<T: Copy>(a: T, b: T) -> T;
  • saturating_add<T: Copy>(a: T, b: T) -> T;
  • saturating_sub<T: Copy>(a: T, b: T) -> T;
  • discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
  • variant_count<T>() -> usize;
  • r#try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
  • nontemporal_store<T>(ptr: *mut T, val: T);
  • ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
  • ptr_offset_from_unsigned<T>(ptr: *const T, base: *const T) -> usize;
  • ptr_guaranteed_eq<T>(ptr: *const T, other: *const T) -> bool;
  • ptr_guaranteed_ne<T>(ptr: *const T, other: *const T) -> bool;
  • const_allocate(size: usize, align: usize) -> *mut u8;
  • const_deallocate(ptr: *mut u8, size: usize, align: usize);
  • raw_eq<T>(a: &T, b: &T) -> bool;
  • black_box<T>(dummy: T) -> T; Add black_box intrinsic #3372
  • vtable_size(ptr: *const ()) -> usize;
  • vtable_align(ptr: *const ()) -> usize;
  • copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
@bjorn3
Copy link

bjorn3 commented Sep 8, 2021

rustc_peek is only used to test a part of rustc. I believe it always results in an error, but with the error message depending on the result of a certain analysis.

bors bot added a commit that referenced this issue Sep 9, 2021
659: Initial intrinsics builtin block r=philberty a=philberty

This is the initial piece to get the simple intrinsic's mapped over to GCC ones. The
GCC wrapper contains a mapping system of rust names over to the builtin gcc names
as far as I can tell gcc will allow for fallback onto linking against -lm.

I think this will be a nice piece of work for new contributors, given the number of intrinsics

Addresses #658 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Co-authored-by: Thomas Schwinge <thomas@codesourcery.com>
philberty added a commit that referenced this issue Mar 9, 2022
This patch adds the initial support for generic intrinsics these are do not
map directly to GCC builtins and need to be substited with their specificed
types. This patch allows for custom implementation body for these functions
by specifying handler functions which will generate the applicable
intrinsic when asked for.

Addresses #658
philberty added a commit that referenced this issue Mar 9, 2022
This demonstrates how we can add in the simple intrinsics in a single
patch.

Addresses #658
philberty added a commit that referenced this issue Mar 9, 2022
philberty added a commit that referenced this issue Mar 9, 2022
This is another type of intrisic since the function contains no parameters
but the argument for the size_of is the generic parameter T. Which uses
TYPE_SIZE_UNIT to get the type size in bytes. GCC will optimize the
function call away when you turn optimizations on.

Addresses #658
philberty added a commit that referenced this issue Mar 10, 2022
This demonstrates how we can add in the simple intrinsics in a single
patch.

Addresses #658
philberty added a commit that referenced this issue Mar 10, 2022
philberty added a commit that referenced this issue Mar 10, 2022
This is another type of intrisic since the function contains no parameters
but the argument for the size_of is the generic parameter T. Which uses
TYPE_SIZE_UNIT to get the type size in bytes. GCC will optimize the
function call away when you turn optimizations on.

Addresses #658
philberty added a commit that referenced this issue Mar 10, 2022
This patch adds the initial support for generic intrinsics these are do not
map directly to GCC builtins and need to be substited with their specificed
types. This patch allows for custom implementation body for these functions
by specifying handler functions which will generate the applicable
intrinsic when asked for.

Addresses #658
philberty added a commit that referenced this issue Mar 10, 2022
This demonstrates how we can add in the simple intrinsics in a single
patch.

Addresses #658
philberty added a commit that referenced this issue Mar 10, 2022
philberty added a commit that referenced this issue Mar 10, 2022
This is another type of intrisic since the function contains no parameters
but the argument for the size_of is the generic parameter T. Which uses
TYPE_SIZE_UNIT to get the type size in bytes. GCC will optimize the
function call away when you turn optimizations on.

Addresses #658
bors bot added a commit that referenced this issue Mar 11, 2022
1003: Add more intrinsics and refactor how we implement them r=philberty a=philberty

This patch series implements:

1. offset
2. size_of
3. unreachable
4. abort

It removes the GCC wrapper mappings to make them much easier to implement. It also demonstrates in single commits
the implementation of each of these intrinsic to make it easy to follow in how we implement them.

Addresses #658 #849 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
philberty added a commit that referenced this issue Apr 28, 2022
This adds in the transmute intrisic by utilizing the convert_expression
framework we have in the backend class.

Fixes #1130
Addresses #658
bors bot added a commit that referenced this issue Apr 29, 2022
1194: Add support for transmute r=philberty a=philberty

This PR adds support for the transmute intrinsic by utilizing the convert
expression code. It also fixes a bug with our coercion rules which miss
two chances for inference variables to resolve slices and arrays.

Fixes #1130
Addresses #658

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
bors bot added a commit that referenced this issue May 4, 2022
1206: Use correct format specifiers for unisnged HOST_WIDE_INT r=philberty a=philberty

The code here was wrongly assuming the unsigned long interface which is not
correctly for all targets.


1209: Allow match on boolean expressions r=philberty a=dafaust

Enables compiling `match` expressions where the scrutinee is a boolean expression. Also enable compiling match arms with Literal patterns, since `true` and `false` literals are commonly used with matches on boolean expressions.

Fixes: #1207 

1211: Preserve inside_loop context when type checking match r=philberty a=dafaust

Previously, we would lose the context of being inside a loop when compiling a `match`.
This would lead to incorrect error messages like "cannot 'break' outside of a loop" when
trying to break out of a loop from within a `match` expression.

Fixes: #1196 


1212: intrinsic: add breakpoint intrinsic r=philberty a=liushuyu

- intrinsic: add breakpoint intrinsic

Addresses #658 

1213: intrinsic: add rotate_left and rotate_right intrinsic r=philberty a=liushuyu

- intrinsic: add rotate_left and rotate_right intrinsic

Address #658

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Co-authored-by: David Faust <david.faust@oracle.com>
Co-authored-by: liushuyu <liushuyu011@gmail.com>
bors bot added a commit that referenced this issue Oct 7, 2022
1565: Implement data prefetch intrinsics r=CohenArthur a=CohenArthur

Addresses #658 
Needs #1564 so only review the last commit

This PR implements the two intrinsics related to data prefetching. I have to say, since these are hints for the backend, I am unsure if the current implementation is right. I believe it should be.

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
bors bot added a commit that referenced this issue Oct 27, 2022
1620: Intrinsics unchecked ops r=CohenArthur a=CohenArthur

Addresses #658 


Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
bors bot added a commit that referenced this issue Dec 16, 2022
1706: Add math intrinsics r=CohenArthur a=tamaroning

Addresses #658
Added math intrinsic functions.

Co-authored-by: Raiki Tamura <tamaron1203@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants