about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaybe Waffle <waffle.lapkin@gmail.com>2022-04-15 02:00:45 +0400
committerMaybe Waffle <waffle.lapkin@gmail.com>2022-05-12 12:54:21 +0400
commit5a5d62aeb2a7be83bff34d6f4db4e1bbe7bd5a93 (patch)
treeb59627aaa1411b832ecce6a4082af097adf3efc5
parent6c1ebff59e5c92eadd1ed5d986c36e34791d6ed3 (diff)
downloadrust-5a5d62aeb2a7be83bff34d6f4db4e1bbe7bd5a93.tar.gz
rust-5a5d62aeb2a7be83bff34d6f4db4e1bbe7bd5a93.zip
Optimize `ptr.is_aligned_to()`
Apparently LLVM is unable to understand that if count_ones() == 1 then self != 0.
Adding `assume(align != 0)` helps generating better asm:
https://rust.godbolt.org/z/ja18YKq91
-rw-r--r--library/core/src/ptr/const_ptr.rs3
-rw-r--r--library/core/src/ptr/mut_ptr.rs3
2 files changed, 6 insertions, 0 deletions
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 9bbdfd1cbb5..824b3fad6c3 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1320,6 +1320,9 @@ impl<T: ?Sized> *const T {
             panic!("is_aligned_to: align is not a power-of-two");
         }
 
+        // SAFETY: `is_power_of_two()` will return `false` for zero.
+        unsafe { core::intrinsics::assume(align != 0) };
+
         // Cast is needed for `T: !Sized`
         self.cast::<u8>().addr() % align == 0
     }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 21220e2a486..4613262dad9 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1589,6 +1589,9 @@ impl<T: ?Sized> *mut T {
             panic!("is_aligned_to: align is not a power-of-two");
         }
 
+        // SAFETY: `is_power_of_two()` will return `false` for zero.
+        unsafe { core::intrinsics::assume(align != 0) };
+
         // Cast is needed for `T: !Sized`
         self.cast::<u8>().addr() % align == 0
     }