Skip to content

Conversation

@hulxv
Copy link
Member

@hulxv hulxv commented Mar 21, 2025

This patch adds the memalignment function to LLVM-libc, following its description in WG14 N3220, §7.24.2.1.

Closes #132300

@llvmbot llvmbot added the libc label Mar 21, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 21, 2025

@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-libc

Author: Mohamed Emad (hulxv)

Changes

This patch adds the memalignment function to LLVM-libc, following its description in WG14 N3220, §7.24.2.1.

Closes #132300


Full diff: https://github.com/llvm/llvm-project/pull/132493.diff

2 Files Affected:

  • (added) libc/src/stdlib/memalignment.c (+19)
  • (added) libc/src/stdlib/memalignment.h (+22)
diff --git a/libc/src/stdlib/memalignment.c b/libc/src/stdlib/memalignment.c
new file mode 100644
index 0000000000000..bf182f16ea138
--- /dev/null
+++ b/libc/src/stdlib/memalignment.c
@@ -0,0 +1,19 @@
+#include "src/stdlib/memalignment.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(size_t, memalignment, (const void *p)) {
+  if (p == NULL) {
+    return 0;
+  }
+
+  uintptr_t addr = (uintptr_t)p;
+
+  // Find the rightmost set bit, which represents the maximum alignment
+  // The alignment is a power of two, so we need to find the largest
+  // power of two that divides the address
+  return addr & (~addr + 1);
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/stdlib/memalignment.h b/libc/src/stdlib/memalignment.h
new file mode 100644
index 0000000000000..8ed900122a153
--- /dev/null
+++ b/libc/src/stdlib/memalignment.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for memalignment --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDLIB_MEM_ALIGNMENT_H
+#define LLVM_LIBC_SRC_STDLIB_MEM_ALIGNMENT_H
+
+#include "src/__support/macros/config.h"
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+size_t memalignment(const void* p);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_STDLIB_LDIV_H
+

@github-actions
Copy link

github-actions bot commented Mar 21, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@hulxv
Copy link
Member Author

hulxv commented Mar 22, 2025

@michaelrj-google Should I add it to stdlib.yaml or stdlib-malloc.yaml ?

Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this patch: I think this is also one of the freestanding functions, I wonder what the plan is to provide that? Normally those go in the clang resource directory headers but we don't have a freestanding stdlib.h there yet.

// Find the rightmost set bit, which represents the maximum alignment
// The alignment is a power of two, so we need to find the largest
// power of two that divides the address
return addr & (~addr + 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return addr & (~addr + 1);
return addr & (~addr + 1);

I can't decide if it would be better to just use ctz. They reduce to the same ASM https://godbolt.org/z/qTjxc6dPn.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made up my mind, the bit twiddling is good here, while 1ull << cpp::count_trailing_zeroes(addr) is probably easier to read, I think it performs worse for 64-bit values.

Copy link
Member Author

@hulxv hulxv Mar 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then going with __builtin_ctzg is better?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the opposite.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does 1ull << cpp::count_trailing_zeroes(addr) exist? I don't find it anywhere. what about using countr_zeros?

Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead and add this to all the entrypoints, it's a freestanding function so I'd be amazed if it didn't work on those targets. You also need to add it to the yaml if you want it to actually show up when it's installed.

@hulxv hulxv requested a review from jhuber6 March 22, 2025 04:03
@hulxv hulxv requested a review from lntue March 22, 2025 14:44
@hulxv hulxv force-pushed the libc/feat/memalignment branch from ca4dbcc to 6a7d28d Compare March 22, 2025 15:26
@hulxv hulxv force-pushed the libc/feat/memalignment branch from 6a7d28d to edc13a9 Compare March 22, 2025 15:27
@hulxv hulxv requested a review from michaelrj-google March 25, 2025 19:13
@hulxv hulxv requested a review from jhuber6 March 26, 2025 16:55
Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you're making good progress, just a bit more and this should be ready to land

@hulxv
Copy link
Member Author

hulxv commented Mar 28, 2025

@michaelrj-google all done now?

@jhuber6
Copy link
Contributor

jhuber6 commented Mar 28, 2025

FAILED: libc/test/src/stdlib/libc.test.src.stdlib.memalignment_test.__unit__.__build__ 
: && /usr/bin/clang++ -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -g -fpie -DLIBC_FULL_BUILD -ffreestanding -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti -Wconversion -Wno-sign-conversion -Wimplicit-fallthrough -Wwrite-strings -Wno-c99-extensions -Wno-gnu-imaginary-constant -Wno-pedantic -Wstrict-prototypes -Wextra-semi -Wnewline-eof -Wnonportable-system-include-path -Wthread-safety -Xlinker --dependency-file=libc/test/src/stdlib/CMakeFiles/libc.test.src.stdlib.memalignment_test.__unit__.__build__.dir/link.d libc/test/src/stdlib/CMakeFiles/libc.test.src.stdlib.memalignment_test.__unit__.__build__.dir/memalignment_test.cpp.o -o libc/test/src/stdlib/libc.test.src.stdlib.memalignment_test.__unit__.__build__  libc/src/stdlib/CMakeFiles/libc.src.stdlib.memalignment.__internal__.dir/./memalignment.cpp.o  libc/src/errno/CMakeFiles/libc.src.errno.errno.__internal__.dir/./libc_errno.cpp.o  libc/src/__support/StringUtil/CMakeFiles/libc.src.__support.StringUtil.error_to_string.dir/./error_to_string.cpp.o  libc/src/__support/OSUtil/linux/CMakeFiles/libc.src.__support.OSUtil.linux.linux_util.dir/./exit.cpp.o  libc/src/__support/OSUtil/linux/CMakeFiles/libc.src.__support.OSUtil.linux.linux_util.dir/./fcntl.cpp.o  libc/test/UnitTest/libLibcDeathTestExecutors.unit.a  libc/test/UnitTest/libLibcTest.unit.a && :
/usr/bin/ld: libc/test/src/stdlib/CMakeFiles/libc.test.src.stdlib.memalignment_test.__unit__.__build__.dir/memalignment_test.cpp.o: in function `LlvmLibcMemAlignmentTest_MallocedPointers::Run()':
/home/runner/work/llvm-project/llvm-project/libc/test/src/stdlib/memalignment_test.cpp:22:(.text+0xb4): undefined reference to `__llvm_libc_21_0_0_git::malloc(unsigned long)'
/usr/bin/ld: /home/runner/work/llvm-project/llvm-project/libc/test/src/stdlib/memalignment_test.cpp:28:(.text+0x1a4): undefined reference to `__llvm_libc_21_0_0_git::free(void*)'
/usr/bin/ld: /home/runner/work/llvm-project/llvm-project/libc/test/src/stdlib/memalignment_test.cpp:32:(.text+0x1ac): undefined reference to `__llvm_libc_21_0_0_git::malloc(unsigned long)'
/usr/bin/ld: /home/runner/work/llvm-project/llvm-project/libc/test/src/stdlib/memalignment_test.cpp:40:(.text+0x2fc): undefined reference to `__llvm_libc_21_0_0_git::free(void*)'
/usr/bin/ld: libc/test/src/stdlib/libc.test.src.stdlib.memalignment_test.__unit__.__build__: hidden symbol `_ZN22__llvm_libc_21_0_0_git4freeEPv' isn't defined
/usr/bin/ld: final link failed: bad value

Bot fails tests. Honestly you should probably just remove the dependencies since this doesn't need malloc to be tested (we have alignas).

@arsenm
Copy link
Contributor

arsenm commented Mar 28, 2025

This should probably be an intrinsic so we don't introduce the ptrtoint, it's the opposite of llvm.ptrmask

@jhuber6
Copy link
Contributor

jhuber6 commented Mar 28, 2025

This should probably be an intrinsic so we don't introduce the ptrtoint, it's the opposite of llvm.ptrmask

Presumably we'd want a fallback for GCC, but that definitely sounds compelling considering that this is a freestanding function, so we could just implement it as a builitin in a header for that case.

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One tweak, then this is good to land.

Do you have commit access or do you need me to merge it for you?

@hulxv
Copy link
Member Author

hulxv commented Mar 28, 2025

Do you have commit access or do you need me to merge it for you?

No, I don't have access. Please merge it

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to fix the buildbots before merging. One of the parts of the test is failing.

@hulxv hulxv requested a review from michaelrj-google March 28, 2025 20:01
@hulxv
Copy link
Member Author

hulxv commented Mar 28, 2025

It passed the tests

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for getting this done!

@michaelrj-google michaelrj-google merged commit 4840895 into llvm:main Mar 28, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[libc] implement memalignment

6 participants