-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Add unchecked_disjoint_bitor
per ACP373
#135760
Open
scottmcm
wants to merge
2
commits into
rust-lang:master
Choose a base branch
from
scottmcm:disjoint-bitor
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+172
−4
Open
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
Add
unchecked_disjoint_bitor
with fallback intrinsic implementation
- Loading branch information
commit 23329986cc8165309a7df23b867aa50778da135d
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -3244,6 +3244,25 @@ pub const fn three_way_compare<T: Copy>(_lhs: T, _rhss: T) -> crate::cmp::Orderi | |||||
unimplemented!() | ||||||
} | ||||||
|
||||||
/// Combine two values which have no bits in common. | ||||||
/// | ||||||
/// This allows the backend to implement it as `a + b` *or* `a | b`, | ||||||
/// depending which us easier to implement on a specific target. | ||||||
/// | ||||||
/// # Safety | ||||||
/// | ||||||
/// Requires that `(a & b) == 0`, or equivalently that `(a | b) == (a + b)`. | ||||||
/// | ||||||
/// Otherwise it's immediate UB. | ||||||
#[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] | ||||||
#[rustc_nounwind] | ||||||
#[cfg_attr(not(bootstrap), rustc_intrinsic)] | ||||||
#[miri::intrinsic_fallback_is_spec] // the fallbacks all `assume` to tell MIRI | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Just for consistency :) |
||||||
pub const unsafe fn disjoint_bitor<T: ~const fallback::DisjointBitOr>(a: T, b: T) -> T { | ||||||
// SAFETY: same preconditions as this function. | ||||||
unsafe { fallback::DisjointBitOr::disjoint_bitor(a, b) } | ||||||
} | ||||||
|
||||||
/// Performs checked integer addition. | ||||||
/// | ||||||
/// Note that, unlike most intrinsics, this is safe to call; | ||||||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1187,6 +1187,52 @@ macro_rules! uint_impl { | |
self % rhs | ||
} | ||
|
||
/// Same value as | ||
#[doc = concat!("`<", stringify!($SelfT), " as BitOr>::bitor(self, other)`")] | ||
/// but UB if any bit position is set in both inputs. | ||
/// | ||
/// This is a situational μoptimization for places where you'd rather use | ||
/// addition on some platforms and bitwise or on other platforms, based on | ||
/// exactly which instructions combine better with whatever else you're | ||
/// doing. Note that there's no reason to bother using this for places | ||
/// where it's clear from the operations involved that they can't overlap. | ||
/// For example, if you're combining `u16`s into a `u32` with | ||
/// `((a as u32) << 16) | (b as u32)`, that's fine, as the backend will | ||
/// know those sides of the `|` are disjoint without needing help. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ``` | ||
/// #![feature(disjoint_bitor)] | ||
/// | ||
/// // SAFETY: `1` and `4` have no bits in common. | ||
/// unsafe { | ||
#[doc = concat!(" assert_eq!(1_", stringify!($SelfT), ".unchecked_disjoint_bitor(4), 5);")] | ||
/// } | ||
/// ``` | ||
/// | ||
/// # Safety | ||
/// | ||
/// Requires that `(self | other) == 0`, otherwise it's immediate UB. | ||
/// | ||
/// Equivalently, requires that `(self | other) == (self + other)`. | ||
#[unstable(feature = "disjoint_bitor", issue = "135758")] | ||
#[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] | ||
#[inline] | ||
pub const unsafe fn unchecked_disjoint_bitor(self, other: Self) -> Self { | ||
assert_unsafe_precondition!( | ||
check_language_ub, | ||
concat!(stringify!($SelfT), "::unchecked_disjoint_bitor cannot have overlapping bits"), | ||
( | ||
lhs: $SelfT = self, | ||
rhs: $SelfT = other, | ||
) => (lhs & rhs) == 0, | ||
); | ||
|
||
// SAFETY: Same precondition | ||
unsafe { intrinsics::disjoint_bitor(self, other) } | ||
} | ||
|
||
/// Returns the logarithm of the number with respect to an arbitrary base, | ||
/// rounded down. | ||
/// | ||
|
@@ -2346,15 +2392,22 @@ macro_rules! uint_impl { | |
/// assert_eq!((sum1, sum0), (9, 6)); | ||
/// ``` | ||
#[unstable(feature = "bigint_helper_methods", issue = "85532")] | ||
#[rustc_const_unstable(feature = "bigint_helper_methods", issue = "85532")] | ||
#[must_use = "this returns the result of the operation, \ | ||
without modifying the original"] | ||
#[inline] | ||
pub const fn carrying_add(self, rhs: Self, carry: bool) -> (Self, bool) { | ||
// note: longer-term this should be done via an intrinsic, but this has been shown | ||
// to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic | ||
let (a, b) = self.overflowing_add(rhs); | ||
let (c, d) = a.overflowing_add(carry as $SelfT); | ||
(c, b | d) | ||
let (a, c1) = self.overflowing_add(rhs); | ||
let (b, c2) = a.overflowing_add(carry as $SelfT); | ||
// Ideally LLVM would know this is disjoint without us telling them, | ||
// but it doesn't <https://github.com/llvm/llvm-project/issues/118162> | ||
// SAFETY: Only one of `c1` and `c2` can be set. | ||
// For c1 to be set we need to have overflowed, but if we did then | ||
// `a` is at most `MAX-1`, which means that `c2` cannot possibly | ||
// overflow because it's adding at most `1` (since it came from `bool`) | ||
(b, unsafe { intrinsics::disjoint_bitor(c1, c2) }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use of this intrinsic inside |
||
} | ||
|
||
/// Calculates `self` + `rhs` with a signed `rhs`. | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.