Re: [PATCH v7 16/31] rust: ptr: add const_align_up()
From: David Rheinsberg
Date: Fri Mar 20 2026 - 06:32:38 EST
Hi Alice!
On Fri, Mar 20, 2026, at 10:47 AM, Alice Ryhl wrote:
> On Fri, Mar 20, 2026 at 10:27 AM David Rheinsberg <david@xxxxxxxxxxxx> wrote:
>> Kinda off-topic: why doesn't `Alignment` store a u8 that represents the exponent, rather than the power? The left-shift when needing the power should be effectively free, shouldn't it? It would avoid all the unsafety in the impl.
>
> For one, it mirrors the design of the unstable stdlib Alignment type.
> For another, it'd make Alignment::of and similar a pain to implement.
Fair enough!
>> Do you need this helper then at all? I assume it is added because `Alignable` cannot be used in const. But it hard-codes `usize` as type, yet does not reflect that in the name. It comes down to which one is more readable, I guess:
>>
>> const_align_up(value, align)
>> vs
>> value.checked_next_multiple_of(align.as_usize())
>>
>> Meh, I don't mind too much. Just wanted to point out that the standard library provides this exactly.
>
> The stdlib implementation probably invokes an expensive division
> operation in place of our bitwise-and operation when the argument is
> not a compile-time constant value.
Fortunately, it does not! Yay! `Alignment::as_nonzero()` has enough annotations to produce competitive assembly. If you care, see my example on x86_64 below, which uses:
align_up1: v.checked_next_multiple_of(align.as_nonzero())
align_up2: const_align_up(v, align)
Thanks
David
align_up1:
lea rax, [rsi - 1]
and rax, rdi
sub rsi, rax
lea rdx, [rsi + rdi]
cmp rdx, rdi
setae cl
test rax, rax
sete al
cmove rdx, rdi
or al, cl
movzx eax, al
ret
align_up2:
lea rdx, [rdi + rsi]
dec rdx
xor eax, eax
cmp rdx, rdi
setae al
neg rsi
and rdx, rsi
ret