Skip to content

Commit

Permalink
Refactor some char, u8 ascii functions to be branchless
Browse files Browse the repository at this point in the history
Decompose singular `matches!` with or-patterns to individual `matches!`
statements to enable branchless code output. The following functions
were changed:
- `is_ascii_alphanumeric`
- `is_ascii_hexdigit`
- `is_ascii_punctuation`

Add codegen tests

Co-authored-by: George Bateman <george.bateman16@gmail.com>
Co-authored-by: scottmcm <scottmcm@users.noreply.github.com>
  • Loading branch information
3 people committed Oct 27, 2023
1 parent 8396efe commit 465ffc9
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
9 changes: 6 additions & 3 deletions library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1450,7 +1450,7 @@ impl char {
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
#[inline]
pub const fn is_ascii_alphanumeric(&self) -> bool {
matches!(*self, '0'..='9' | 'A'..='Z' | 'a'..='z')
matches!(*self, '0'..='9') | matches!(*self, 'A'..='Z') | matches!(*self, 'a'..='z')
}

/// Checks if the value is an ASCII decimal digit:
Expand Down Expand Up @@ -1553,7 +1553,7 @@ impl char {
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
#[inline]
pub const fn is_ascii_hexdigit(&self) -> bool {
matches!(*self, '0'..='9' | 'A'..='F' | 'a'..='f')
matches!(*self, '0'..='9') | matches!(*self, 'A'..='F') | matches!(*self, 'a'..='f')
}

/// Checks if the value is an ASCII punctuation character:
Expand Down Expand Up @@ -1591,7 +1591,10 @@ impl char {
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
#[inline]
pub const fn is_ascii_punctuation(&self) -> bool {
matches!(*self, '!'..='/' | ':'..='@' | '['..='`' | '{'..='~')
matches!(*self, '!'..='/')
| matches!(*self, ':'..='@')
| matches!(*self, '['..='`')
| matches!(*self, '{'..='~')
}

/// Checks if the value is an ASCII graphic character:
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ impl u8 {
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
#[inline]
pub const fn is_ascii_alphanumeric(&self) -> bool {
matches!(*self, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
matches!(*self, b'0'..=b'9') | matches!(*self, b'A'..=b'Z') | matches!(*self, b'a'..=b'z')
}

/// Checks if the value is an ASCII decimal digit:
Expand Down Expand Up @@ -894,7 +894,7 @@ impl u8 {
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
#[inline]
pub const fn is_ascii_hexdigit(&self) -> bool {
matches!(*self, b'0'..=b'9' | b'A'..=b'F' | b'a'..=b'f')
matches!(*self, b'0'..=b'9') | matches!(*self, b'A'..=b'F') | matches!(*self, b'a'..=b'f')
}

/// Checks if the value is an ASCII punctuation character:
Expand Down Expand Up @@ -932,7 +932,10 @@ impl u8 {
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
#[inline]
pub const fn is_ascii_punctuation(&self) -> bool {
matches!(*self, b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~')
matches!(*self, b'!'..=b'/')
| matches!(*self, b':'..=b'@')
| matches!(*self, b'['..=b'`')
| matches!(*self, b'{'..=b'~')
}

/// Checks if the value is an ASCII graphic character:
Expand Down
47 changes: 47 additions & 0 deletions tests/codegen/char-ascii-branchless.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Checks that these functions are branchless.
//
// compile-flags: -O

#![crate_type = "lib"]

// CHECK-LABEL: @is_ascii_alphanumeric_char
#[no_mangle]
pub fn is_ascii_alphanumeric_char(x: char) -> bool {
// CHECK-NOT: br
x.is_ascii_alphanumeric()
}

// CHECK-LABEL: @is_ascii_alphanumeric_u8
#[no_mangle]
pub fn is_ascii_alphanumeric_u8(x: u8) -> bool {
// CHECK-NOT: br
x.is_ascii_alphanumeric()
}

// CHECK-LABEL: @is_ascii_hexdigit_char
#[no_mangle]
pub fn is_ascii_hexdigit_char(x: char) -> bool {
// CHECK-NOT: br
x.is_ascii_hexdigit()
}

// CHECK-LABEL: @is_ascii_hexdigit_u8
#[no_mangle]
pub fn is_ascii_hexdigit_u8(x: u8) -> bool {
// CHECK-NOT: br
x.is_ascii_hexdigit()
}

// CHECK-LABEL: @is_ascii_punctuation_char
#[no_mangle]
pub fn is_ascii_punctuation_char(x: char) -> bool {
// CHECK-NOT: br
x.is_ascii_punctuation()
}

// CHECK-LABEL: @is_ascii_punctuation_u8
#[no_mangle]
pub fn is_ascii_punctuation_u8(x: u8) -> bool {
// CHECK-NOT: br
x.is_ascii_punctuation()
}

0 comments on commit 465ffc9

Please sign in to comment.