From 5913ef6660aa7977d7cbee01b115d8a5e926b893 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 27 Oct 2021 13:00:42 +0200 Subject: [PATCH 1/5] replace `|` with `||` in {unsigned_int}::carrying_add Using short-circuiting operators makes it easier to perform some kinds of source code analysis, like MC/DC code coverage (a requirement in safety-critical environments). The optimized x86_64 assembly is the same between the old and new versions: ``` mov eax, edi add dl, -1 adc eax, esi setb dl ret ``` --- library/core/src/num/uint_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 507ff516a8f28..18c1353e7c62d 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1525,7 +1525,7 @@ macro_rules! uint_impl { // 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) + (c, b || d) } /// Calculates `self` + `rhs` with a signed `rhs` From 9fb66969e38f1ce4b269f9506faf7ebc161ececa Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 27 Oct 2021 16:56:57 +0200 Subject: [PATCH 2/5] replace `|` with `||` in {unsigned_int}::borrowing_sub Using short-circuiting operators makes it easier to perform some kinds of source code analysis, like MC/DC code coverage (a requirement in safety-critical environments). The optimized x86_64 assembly is the same between the old and new versions: ``` mov eax, edi add dl, -1 sbb eax, esi setb dl ret ``` --- library/core/src/num/uint_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 18c1353e7c62d..691d0891b1448 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1606,7 +1606,7 @@ macro_rules! uint_impl { // to generate optimal code for now, and LLVM doesn't have an equivalent intrinsic let (a, b) = self.overflowing_sub(rhs); let (c, d) = a.overflowing_sub(borrow as $SelfT); - (c, b | d) + (c, b || d) } /// Computes the absolute difference between `self` and `other`. From a5a8bb012540c23a9b4ab5a38bc7f75d5ebaba60 Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 27 Oct 2021 13:03:55 +0200 Subject: [PATCH 3/5] replace `|` with `||` in string validation Using short-circuiting operators makes it easier to perform some kinds of source code analysis, like MC/DC code coverage (a requirement in safety-critical environments). The optimized x86_64 assembly is equivalent between the old and new versions. Old assembly of that condition: ``` mov rax, qword ptr [rdi + rdx + 8] or rax, qword ptr [rdi + rdx] test rax, r9 je .LBB0_7 ``` New assembly of that condition: ``` mov rax, qword ptr [rdi + rdx] or rax, qword ptr [rdi + rdx + 8] test rax, r8 je .LBB0_7 ``` --- library/core/src/str/validations.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs index 093c9c37b60b4..f2d1c73780880 100644 --- a/library/core/src/str/validations.rs +++ b/library/core/src/str/validations.rs @@ -210,7 +210,7 @@ pub(super) fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { // break if there is a nonascii byte let zu = contains_nonascii(*block); let zv = contains_nonascii(*block.offset(1)); - if zu | zv { + if zu || zv { break; } } From 81130fe188ff37f2deacdf53d7afe823ceaba7ec Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 27 Oct 2021 15:25:00 +0200 Subject: [PATCH 4/5] replace `&` with `&&` in {integer}::checked_div Using short-circuit operators makes it easier to perform some kinds of source code analysis, like MC/DC code coverage (a requirement in safety-critical environments). The optimized x86 assembly is the same between the old and new versions: ``` xor eax, eax test esi, esi je .LBB0_1 cmp edi, -2147483648 jne .LBB0_4 cmp esi, -1 jne .LBB0_4 ret .LBB0_1: ret .LBB0_4: mov eax, edi cdq idiv esi mov edx, eax mov eax, 1 ret ``` --- library/core/src/num/int_macros.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 5ef2558a5fe4b..22d36d4eba3ff 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -608,8 +608,7 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_div(self, rhs: Self) -> Option { - // Using `&` helps LLVM see that it is the same check made in division. - if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) { + if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) { None } else { // SAFETY: div by zero and by INT_MIN have been checked above From 68a4460b614bc925a12231d5bba04dd66cb78c6e Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Wed, 27 Oct 2021 15:45:31 +0200 Subject: [PATCH 5/5] replace `&` with `&&` in {integer}::checked_rem Using short-circuit operators makes it easier to perform some kinds of source code analysis, like MC/DC code coverage (a requirement in safety-critical environments). The optimized x86 assembly is the same between the old and new versions: ``` xor eax, eax test esi, esi je .LBB0_1 cmp edi, -2147483648 jne .LBB0_4 cmp esi, -1 jne .LBB0_4 ret .LBB0_1: ret .LBB0_4: mov eax, edi cdq idiv esi mov eax, 1 ret ``` --- library/core/src/num/int_macros.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 22d36d4eba3ff..052e1a21b32cb 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -661,8 +661,7 @@ macro_rules! int_impl { without modifying the original"] #[inline] pub const fn checked_rem(self, rhs: Self) -> Option { - // Using `&` helps LLVM see that it is the same check made in division. - if unlikely!(rhs == 0 || ((self == Self::MIN) & (rhs == -1))) { + if unlikely!(rhs == 0 || ((self == Self::MIN) && (rhs == -1))) { None } else { // SAFETY: div by zero and by INT_MIN have been checked above