[llvm-bugs] [Bug 44448] New: __builtin_align_down() - some opts missing
via llvm-bugs
llvm-bugs at lists.llvm.org
Thu Jan 2 15:27:16 PST 2020
https://bugs.llvm.org/show_bug.cgi?id=44448
Bug ID: 44448
Summary: __builtin_align_down() - some opts missing
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: Backend: X86
Assignee: unassignedbugs at nondot.org
Reporter: lebedev.ri at gmail.com
CC: craig.topper at gmail.com, llvm-bugs at lists.llvm.org,
llvm-dev at redking.me.uk, spatel+llvm at rotateright.com
The `__builtin_align_down()` is naive, sane version, it results in suboptimal
assembly.
The `__builtin_align_down_GOOD()` results in optimal assembly,
identical to `__builtin_align_down_UNFRIENDLY()`.
I'm not really sure what folds are missing.
I would say that `@_Z20__builtin_align_downPcm()` is IR-canonical,
while `@_Z25__builtin_align_down_GOODPcm()` isn't,
even though the final assembly is optimal for the 'non-canonical' one.
(1) Their difference is this IR-level fold: https://rise4fun.com/Alive/sltV
^ should we be hoisting that IR `neg`, or sinking it?
Name: __builtin_align_down
%neg = sub i64 0, %alignment
%and = and i64 %0, %neg
%r = sub i64 %and, %0
=>
%neg.not = add i64 %alignment, -1
%sub1 = and i64 %neg.not, %0
%r = sub i64 0, %sub1
(2) In backend, we are clearly missing the following fold:
https://rise4fun.com/Alive/ZVdp
Name: ptr - (ptr & (alignment-1)) -> ptr & (0 - alignment)
%mask = add i64 %alignment, -1
%bias = and i64 %ptr, %mask
%r = sub i64 %ptr, %bias
=>
%highbitmask = sub i64 0, %alignment
%r = and i64 %ptr, %highbitmask
Not sure if there is more general fold than that missing?
https://godbolt.org/z/GBAsiB
#include <cstdint>
#include <cstddef>
char* __attribute__((alloc_align(2)))
__builtin_align_down(char* maybe_overbiased_ptr, size_t alignment) {
size_t mask = alignment - 1;
uintptr_t maybe_overbiased_intptr = (uintptr_t)maybe_overbiased_ptr;
uintptr_t aligned_intptr = maybe_overbiased_intptr & (~mask);
uintptr_t bias = maybe_overbiased_intptr - aligned_intptr;
return maybe_overbiased_ptr - bias;
}
char* __attribute__((alloc_align(2)))
__builtin_align_down_GOOD(char* maybe_overbiased_ptr, size_t alignment) {
size_t mask = alignment - 1;
uintptr_t maybe_overbiased_intptr = (uintptr_t)maybe_overbiased_ptr;
uintptr_t aligned_intptr = maybe_overbiased_intptr & (~mask);
uintptr_t bias = aligned_intptr - maybe_overbiased_intptr;
return maybe_overbiased_ptr + bias;
}
char* __attribute__((alloc_align(2)))
__builtin_align_up(char* maybe_underbiased_ptr, size_t alignment) {
size_t mask = alignment - 1;
uintptr_t maybe_underbiased_intptr = (uintptr_t)maybe_underbiased_ptr;
uintptr_t aligned_biased_intptr = maybe_underbiased_intptr + mask;
uintptr_t aligned_intptr = aligned_biased_intptr & (~mask);
uintptr_t bias = aligned_intptr - maybe_underbiased_intptr;
return maybe_underbiased_ptr + bias;
}
char* __attribute__((alloc_align(2)))
__builtin_align_down_UNFRIENDLY(char* maybe_overbiased_ptr, size_t alignment) {
size_t mask = alignment - 1;
uintptr_t maybe_overbiased_intptr = (uintptr_t)maybe_overbiased_ptr;
uintptr_t aligned_intptr = maybe_overbiased_intptr & (~mask);
return (char*)aligned_intptr;
}
char* __attribute__((alloc_align(2)))
__builtin_align_up_UNFRIENDLY(char* maybe_underbiased_ptr, size_t alignment) {
size_t mask = alignment - 1;
uintptr_t maybe_underbiased_intptr = (uintptr_t)maybe_underbiased_ptr;
uintptr_t aligned_biased_intptr = maybe_underbiased_intptr + mask;
uintptr_t aligned_intptr = aligned_biased_intptr & (~mask);
return (char*)aligned_intptr;
}
define dso_local i8* @_Z20__builtin_align_downPcm(i8* %maybe_overbiased_ptr,
i64 %alignment) local_unnamed_addr #0 {
%0 = ptrtoint i8* %maybe_overbiased_ptr to i64
%neg.not = add i64 %alignment, -1
%sub1 = and i64 %neg.not, %0
%idx.neg = sub i64 0, %sub1
%add.ptr = getelementptr inbounds i8, i8* %maybe_overbiased_ptr, i64 %idx.neg
ret i8* %add.ptr
}
define dso_local i8* @_Z25__builtin_align_down_GOODPcm(i8*
%maybe_overbiased_ptr, i64 %alignment) local_unnamed_addr #0 {
%0 = ptrtoint i8* %maybe_overbiased_ptr to i64
%neg = sub i64 0, %alignment
%and = and i64 %0, %neg
%sub1 = sub i64 %and, %0
%add.ptr = getelementptr inbounds i8, i8* %maybe_overbiased_ptr, i64 %sub1
ret i8* %add.ptr
}
__builtin_align_down(char*, unsigned long): #
@__builtin_align_down(char*, unsigned long)
dec rsi
mov rax, rdi
and rsi, rdi
sub rax, rsi
ret
__builtin_align_down_GOOD(char*, unsigned long): #
@__builtin_align_down_GOOD(char*, unsigned long)
mov rax, rsi
neg rax
and rax, rdi
ret
__builtin_align_up(char*, unsigned long): #
@__builtin_align_up(char*, unsigned long)
lea rax, [rsi + rdi - 1]
neg rsi
and rax, rsi
ret
__builtin_align_down_UNFRIENDLY(char*, unsigned long): #
@__builtin_align_down_UNFRIENDLY(char*, unsigned long)
mov rax, rsi
neg rax
and rax, rdi
ret
__builtin_align_up_UNFRIENDLY(char*, unsigned long): #
@__builtin_align_up_UNFRIENDLY(char*, unsigned long)
lea rax, [rsi + rdi - 1]
neg rsi
and rax, rsi
ret
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200102/db094172/attachment.html>
More information about the llvm-bugs
mailing list