Open
Description
If you round up a pointer and calculate how far it moved from the original pointer (((p + (a-1)) & -a) - p
), that distance is always less than the alignment: https://alive2.llvm.org/ce/z/fL_uXq
define i1 @src(i64 noundef %p, i64 noundef %a) noundef zeroext {
%start:
%0 = ctpop i64 noundef %a
%_3 = icmp eq i64 %0, 1
assume i1 %_3
%_8 = add i64 noundef %p, -1
%_7 = add i64 %_8, noundef %a
%_9 = sub i64 0, noundef %a
%_6 = and i64 %_7, %_9
%offset = sub i64 %_6, noundef %p
%1 = icmp ult i64 %offset, noundef %a
ret i1 %1
}
=>
define i1 @tgt(i64 noundef %p, i64 noundef %a) noundef zeroext {
%start:
%0 = ctpop i64 noundef %a
%_3 = icmp eq i64 %0, 1
assume i1 %_3
ret i1 1
}
Transformation seems to be correct!
But it appears that optimizations can't take advantage of that today https://llvm.godbolt.org/z/Mcc7ads1j, not even for constant alignment.
(Found trying to use https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.align_offset in Rust, when I noticed unnecessary checks.)