Skip to content

Commit 465ffc9

Browse files
okanecoGKFXscottmcm
committed
Refactor some char, u8 ascii functions to be branchless
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 <[email protected]> Co-authored-by: scottmcm <[email protected]>
1 parent 8396efe commit 465ffc9

File tree

3 files changed

+59
-6
lines changed

3 files changed

+59
-6
lines changed

library/core/src/char/methods.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ impl char {
14501450
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
14511451
#[inline]
14521452
pub const fn is_ascii_alphanumeric(&self) -> bool {
1453-
matches!(*self, '0'..='9' | 'A'..='Z' | 'a'..='z')
1453+
matches!(*self, '0'..='9') | matches!(*self, 'A'..='Z') | matches!(*self, 'a'..='z')
14541454
}
14551455

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

15591559
/// Checks if the value is an ASCII punctuation character:
@@ -1591,7 +1591,10 @@ impl char {
15911591
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
15921592
#[inline]
15931593
pub const fn is_ascii_punctuation(&self) -> bool {
1594-
matches!(*self, '!'..='/' | ':'..='@' | '['..='`' | '{'..='~')
1594+
matches!(*self, '!'..='/')
1595+
| matches!(*self, ':'..='@')
1596+
| matches!(*self, '['..='`')
1597+
| matches!(*self, '{'..='~')
15951598
}
15961599

15971600
/// Checks if the value is an ASCII graphic character:

library/core/src/num/mod.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ impl u8 {
791791
#[rustc_const_stable(feature = "const_ascii_ctype_on_intrinsics", since = "1.47.0")]
792792
#[inline]
793793
pub const fn is_ascii_alphanumeric(&self) -> bool {
794-
matches!(*self, b'0'..=b'9' | b'A'..=b'Z' | b'a'..=b'z')
794+
matches!(*self, b'0'..=b'9') | matches!(*self, b'A'..=b'Z') | matches!(*self, b'a'..=b'z')
795795
}
796796

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

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

938941
/// Checks if the value is an ASCII graphic character:
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Checks that these functions are branchless.
2+
//
3+
// compile-flags: -O
4+
5+
#![crate_type = "lib"]
6+
7+
// CHECK-LABEL: @is_ascii_alphanumeric_char
8+
#[no_mangle]
9+
pub fn is_ascii_alphanumeric_char(x: char) -> bool {
10+
// CHECK-NOT: br
11+
x.is_ascii_alphanumeric()
12+
}
13+
14+
// CHECK-LABEL: @is_ascii_alphanumeric_u8
15+
#[no_mangle]
16+
pub fn is_ascii_alphanumeric_u8(x: u8) -> bool {
17+
// CHECK-NOT: br
18+
x.is_ascii_alphanumeric()
19+
}
20+
21+
// CHECK-LABEL: @is_ascii_hexdigit_char
22+
#[no_mangle]
23+
pub fn is_ascii_hexdigit_char(x: char) -> bool {
24+
// CHECK-NOT: br
25+
x.is_ascii_hexdigit()
26+
}
27+
28+
// CHECK-LABEL: @is_ascii_hexdigit_u8
29+
#[no_mangle]
30+
pub fn is_ascii_hexdigit_u8(x: u8) -> bool {
31+
// CHECK-NOT: br
32+
x.is_ascii_hexdigit()
33+
}
34+
35+
// CHECK-LABEL: @is_ascii_punctuation_char
36+
#[no_mangle]
37+
pub fn is_ascii_punctuation_char(x: char) -> bool {
38+
// CHECK-NOT: br
39+
x.is_ascii_punctuation()
40+
}
41+
42+
// CHECK-LABEL: @is_ascii_punctuation_u8
43+
#[no_mangle]
44+
pub fn is_ascii_punctuation_u8(x: u8) -> bool {
45+
// CHECK-NOT: br
46+
x.is_ascii_punctuation()
47+
}

0 commit comments

Comments
 (0)