[libc] [llvm] [libc] implement `memalignment` (PR #132493)

Mohamed Emad via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 23 08:55:05 PDT 2025


https://github.com/hulxv updated https://github.com/llvm/llvm-project/pull/132493

>From 152894ee1076d18efed7730bed774e0f2b5aa9f9 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 01:33:30 +0200
Subject: [PATCH 01/15] [libc] implement `memalignment`

---
 libc/src/stdlib/memalignment.c | 19 +++++++++++++++++++
 libc/src/stdlib/memalignment.h | 22 ++++++++++++++++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 libc/src/stdlib/memalignment.c
 create mode 100644 libc/src/stdlib/memalignment.h

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
+

>From 000e4e2a874dcd5faeb2df5f6544b02bd9215b10 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 01:44:12 +0200
Subject: [PATCH 02/15] chore: fix formatting of `memalignment.h`

---
 libc/src/stdlib/memalignment.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/src/stdlib/memalignment.h b/libc/src/stdlib/memalignment.h
index 8ed900122a153..b50aa02d5050e 100644
--- a/libc/src/stdlib/memalignment.h
+++ b/libc/src/stdlib/memalignment.h
@@ -1,4 +1,5 @@
-//===-- Implementation header for memalignment --------------------------*- C++ -*-===//
+//===-- 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.
@@ -14,9 +15,8 @@
 
 namespace LIBC_NAMESPACE_DECL {
 
-size_t memalignment(const void* p);
+size_t memalignment(const void *p);
 
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SRC_STDLIB_LDIV_H
-

>From 845184e4b21c3d52f7c127b2aa6d7688cc29745e Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 01:47:15 +0200
Subject: [PATCH 03/15] test: adding tests for `memalignment`

---
 libc/test/src/stdlib/CMakeLists.txt        | 12 ++++
 libc/test/src/stdlib/memalignment_test.cpp | 67 ++++++++++++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 libc/test/src/stdlib/memalignment_test.cpp

diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 90d7b7a55dbe6..93324a836f555 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -457,4 +457,16 @@ if(LLVM_LIBC_FULL_BUILD)
         libc.src.stdlib.free
     )
   endif()
+  add_libc_test(
+    memalignment_test
+    # The EXPECT_EXITS test is only availible for unit tests.
+    UNIT_TEST_ONLY
+    SUITE
+      libc-stdlib-tests
+    SRCS
+      memalignment_test.cpp
+    DEPENDS
+      libc.include.stdlib
+      libc.src.stdlib.memalignment
+  )
 endif()
diff --git a/libc/test/src/stdlib/memalignment_test.cpp b/libc/test/src/stdlib/memalignment_test.cpp
new file mode 100644
index 0000000000000..d0405a4cb5e11
--- /dev/null
+++ b/libc/test/src/stdlib/memalignment_test.cpp
@@ -0,0 +1,67 @@
+//===-- Unittests for memalignment ---------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdlib/memalignment.h"
+#include "src/stdlib/malloc.h"
+#include "src/stdlib/free.h"
+#include "test/UnitTest/Test.h"
+
+#include <stdint.h>
+
+TEST(LlvmLibcMemAlignmentTest, NullPointer) {
+  void *ptr = nullptr;
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr), static_cast<size_t>(0));
+}
+
+TEST(LlvmLibcMemAlignmentTest, MallocedPointers) {
+  int *int_ptr = reinterpret_cast<int *>(LIBC_NAMESPACE::malloc(sizeof(int)));
+  EXPECT_NE(reinterpret_cast<void *>(int_ptr), static_cast<void *>(nullptr));
+  
+  size_t int_alignment = LIBC_NAMESPACE::memalignment(int_ptr);
+  EXPECT_GE(int_alignment, alignof(int));
+  
+  
+  LIBC_NAMESPACE::free(int_ptr);
+  
+  // Allocate a double (typically 8-byte aligned)
+  double *double_ptr = reinterpret_cast<double *>(LIBC_NAMESPACE::malloc(sizeof(double)));
+  EXPECT_NE(reinterpret_cast<void *>(double_ptr), static_cast<void *>(nullptr));
+  
+  size_t double_alignment = LIBC_NAMESPACE::memalignment(double_ptr);
+  EXPECT_GE(double_alignment, alignof(double));
+ 
+  EXPECT_EQ(double_alignment & (double_alignment - 1), static_cast<size_t>(0));
+  
+  LIBC_NAMESPACE::free(double_ptr);
+}
+
+TEST(LlvmLibcMemAlignmentTest, SpecificAlignment) {
+  
+  // These addresses have known alignment patterns - if we can construct them
+  uintptr_t addr_align2 = 0x2;    // 2-byte aligned
+  uintptr_t addr_align4 = 0x4;    // 4-byte aligned
+  uintptr_t addr_align8 = 0x8;    // 8-byte aligned
+  uintptr_t addr_align16 = 0x10;  // 16-byte aligned
+  uintptr_t addr_align32 = 0x20;  // 32-byte aligned
+  
+  void *ptr_align2 = reinterpret_cast<void *>(addr_align2);
+  void *ptr_align4 = reinterpret_cast<void *>(addr_align4);
+  void *ptr_align8 = reinterpret_cast<void *>(addr_align8);
+  void *ptr_align16 = reinterpret_cast<void *>(addr_align16);
+  void *ptr_align32 = reinterpret_cast<void *>(addr_align32);
+  
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align2), static_cast<size_t>(2));
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align4), static_cast<size_t>(4));
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align8), static_cast<size_t>(8));
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align16), static_cast<size_t>(16));
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align32), static_cast<size_t>(32));
+  
+  uintptr_t addr_complex = 0x1234560;  // 16-byte aligned (ends in 0)
+  void *ptr_complex = reinterpret_cast<void *>(addr_complex);
+  EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_complex), static_cast<size_t>(16));
+}
\ No newline at end of file

>From 224d7923f160d737776a80e2a3475d0e4605d456 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 01:52:33 +0200
Subject: [PATCH 04/15] chore: fix formatting of `memalignment_test.cpp`

---
 libc/test/src/stdlib/memalignment_test.cpp | 40 +++++++++++-----------
 1 file changed, 20 insertions(+), 20 deletions(-)

diff --git a/libc/test/src/stdlib/memalignment_test.cpp b/libc/test/src/stdlib/memalignment_test.cpp
index d0405a4cb5e11..91df893cb5f8f 100644
--- a/libc/test/src/stdlib/memalignment_test.cpp
+++ b/libc/test/src/stdlib/memalignment_test.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/stdlib/memalignment.h"
-#include "src/stdlib/malloc.h"
 #include "src/stdlib/free.h"
+#include "src/stdlib/malloc.h"
+#include "src/stdlib/memalignment.h"
 #include "test/UnitTest/Test.h"
 
 #include <stdint.h>
@@ -21,47 +21,47 @@ TEST(LlvmLibcMemAlignmentTest, NullPointer) {
 TEST(LlvmLibcMemAlignmentTest, MallocedPointers) {
   int *int_ptr = reinterpret_cast<int *>(LIBC_NAMESPACE::malloc(sizeof(int)));
   EXPECT_NE(reinterpret_cast<void *>(int_ptr), static_cast<void *>(nullptr));
-  
+
   size_t int_alignment = LIBC_NAMESPACE::memalignment(int_ptr);
   EXPECT_GE(int_alignment, alignof(int));
-  
-  
+
   LIBC_NAMESPACE::free(int_ptr);
-  
+
   // Allocate a double (typically 8-byte aligned)
-  double *double_ptr = reinterpret_cast<double *>(LIBC_NAMESPACE::malloc(sizeof(double)));
+  double *double_ptr =
+      reinterpret_cast<double *>(LIBC_NAMESPACE::malloc(sizeof(double)));
   EXPECT_NE(reinterpret_cast<void *>(double_ptr), static_cast<void *>(nullptr));
-  
+
   size_t double_alignment = LIBC_NAMESPACE::memalignment(double_ptr);
   EXPECT_GE(double_alignment, alignof(double));
- 
+
   EXPECT_EQ(double_alignment & (double_alignment - 1), static_cast<size_t>(0));
-  
+
   LIBC_NAMESPACE::free(double_ptr);
 }
 
 TEST(LlvmLibcMemAlignmentTest, SpecificAlignment) {
-  
+
   // These addresses have known alignment patterns - if we can construct them
-  uintptr_t addr_align2 = 0x2;    // 2-byte aligned
-  uintptr_t addr_align4 = 0x4;    // 4-byte aligned
-  uintptr_t addr_align8 = 0x8;    // 8-byte aligned
-  uintptr_t addr_align16 = 0x10;  // 16-byte aligned
-  uintptr_t addr_align32 = 0x20;  // 32-byte aligned
-  
+  uintptr_t addr_align2 = 0x2;   // 2-byte aligned
+  uintptr_t addr_align4 = 0x4;   // 4-byte aligned
+  uintptr_t addr_align8 = 0x8;   // 8-byte aligned
+  uintptr_t addr_align16 = 0x10; // 16-byte aligned
+  uintptr_t addr_align32 = 0x20; // 32-byte aligned
+
   void *ptr_align2 = reinterpret_cast<void *>(addr_align2);
   void *ptr_align4 = reinterpret_cast<void *>(addr_align4);
   void *ptr_align8 = reinterpret_cast<void *>(addr_align8);
   void *ptr_align16 = reinterpret_cast<void *>(addr_align16);
   void *ptr_align32 = reinterpret_cast<void *>(addr_align32);
-  
+
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align2), static_cast<size_t>(2));
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align4), static_cast<size_t>(4));
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align8), static_cast<size_t>(8));
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align16), static_cast<size_t>(16));
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_align32), static_cast<size_t>(32));
-  
-  uintptr_t addr_complex = 0x1234560;  // 16-byte aligned (ends in 0)
+
+  uintptr_t addr_complex = 0x1234560; // 16-byte aligned (ends in 0)
   void *ptr_complex = reinterpret_cast<void *>(addr_complex);
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_complex), static_cast<size_t>(16));
 }
\ No newline at end of file

>From 76b752d13cc1a47b85d8bff458e060e87224eeba Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 02:02:33 +0200
Subject: [PATCH 05/15] [libc] add `memalignment` to `x86_64` entrypoints

---
 libc/config/linux/x86_64/entrypoints.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 5abe6957d2e3c..551556dc03cc2 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -214,6 +214,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.free
     libc.src.stdlib.malloc
     libc.src.stdlib.realloc
+    libc.src.stdlib.memalignment
 
     # stdio.h entrypoints
     libc.src.stdio.fprintf

>From 40ed080b0541d2fba8902ed61c1acc7cb75faefc Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 05:15:17 +0200
Subject: [PATCH 06/15] [libc] fix header of `memalignment`

---
 libc/src/stdlib/memalignment.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/libc/src/stdlib/memalignment.h b/libc/src/stdlib/memalignment.h
index b50aa02d5050e..1166854fea054 100644
--- a/libc/src/stdlib/memalignment.h
+++ b/libc/src/stdlib/memalignment.h
@@ -1,5 +1,4 @@
-//===-- Implementation header for memalignment --------------------------*- C++
-//-*-===//
+//===-- 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.

>From ce731cc310e41328c3d5a05fd61054b1ff1cbb68 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 05:42:29 +0200
Subject: [PATCH 07/15] [libc] add `memalignment` to other architectures
 entrypoints

---
 libc/config/baremetal/aarch64/entrypoints.txt | 1 +
 libc/config/darwin/arm/entrypoints.txt        | 1 +
 libc/config/darwin/x86_64/entrypoints.txt     | 1 +
 libc/config/gpu/amdgpu/entrypoints.txt        | 1 +
 libc/config/gpu/nvptx/entrypoints.txt         | 1 +
 libc/config/linux/aarch64/entrypoints.txt     | 1 +
 libc/config/linux/arm/entrypoints.txt         | 1 +
 libc/config/linux/riscv/entrypoints.txt       | 1 +
 libc/config/linux/x86_64/entrypoints.txt      | 2 +-
 libc/config/windows/entrypoints.txt           | 1 +
 10 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt
index 8b51942d30fe8..9e9de9ed1569d 100644
--- a/libc/config/baremetal/aarch64/entrypoints.txt
+++ b/libc/config/baremetal/aarch64/entrypoints.txt
@@ -231,6 +231,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.llabs
     libc.src.stdlib.lldiv
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.qsort
     libc.src.stdlib.rand
     libc.src.stdlib.realloc
diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt
index 7972d285f963a..5eba2850affa3 100644
--- a/libc/config/darwin/arm/entrypoints.txt
+++ b/libc/config/darwin/arm/entrypoints.txt
@@ -95,6 +95,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdlib.h external entrypoints
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.calloc
     libc.src.stdlib.realloc
     libc.src.stdlib.free
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 19230cde47198..cb19aa4b56c6c 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -89,6 +89,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdlib.h external entrypoints
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.calloc
     libc.src.stdlib.realloc
     libc.src.stdlib.free
diff --git a/libc/config/gpu/amdgpu/entrypoints.txt b/libc/config/gpu/amdgpu/entrypoints.txt
index 291d86b4dd587..bf13edab1c2d3 100644
--- a/libc/config/gpu/amdgpu/entrypoints.txt
+++ b/libc/config/gpu/amdgpu/entrypoints.txt
@@ -200,6 +200,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.calloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.realloc
 
     # errno.h entrypoints
diff --git a/libc/config/gpu/nvptx/entrypoints.txt b/libc/config/gpu/nvptx/entrypoints.txt
index 1ea0d9b03b37e..ef2b0e2ec622f 100644
--- a/libc/config/gpu/nvptx/entrypoints.txt
+++ b/libc/config/gpu/nvptx/entrypoints.txt
@@ -200,6 +200,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.calloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.realloc
 
     # errno.h entrypoints
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 431975463fbad..404a233537f43 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -212,6 +212,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.calloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.realloc
 
     # stdio.h entrypoints
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 170525c5529a0..6c0c8a5a9437e 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -170,6 +170,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.aligned_alloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
 
     # sys/mman.h entrypoints
     libc.src.sys.mman.mmap
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index c234ea2560043..8ae485fa969c8 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -208,6 +208,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.calloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.realloc
 
     # stdio.h entrypoints
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 551556dc03cc2..9a7628dc31b4a 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -213,8 +213,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.stdlib.calloc
     libc.src.stdlib.free
     libc.src.stdlib.malloc
-    libc.src.stdlib.realloc
     libc.src.stdlib.memalignment
+    libc.src.stdlib.realloc
 
     # stdio.h entrypoints
     libc.src.stdio.fprintf
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index aad320995d339..583ccf6745e8b 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -90,6 +90,7 @@ set(TARGET_LIBC_ENTRYPOINTS
 
     # stdlib.h external entrypoints
     libc.src.stdlib.malloc
+    libc.src.stdlib.memalignment
     libc.src.stdlib.calloc
     libc.src.stdlib.realloc
     libc.src.stdlib.aligned_alloc

>From 45935348860b97eb3ffc848183accaae5b489cda Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 05:51:45 +0200
Subject: [PATCH 08/15] [libc] add `memalignment` to `stdlib-mallic.yaml`

---
 libc/include/stdlib-malloc.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/libc/include/stdlib-malloc.yaml b/libc/include/stdlib-malloc.yaml
index 51c11f5602e2c..597ebc30df764 100644
--- a/libc/include/stdlib-malloc.yaml
+++ b/libc/include/stdlib-malloc.yaml
@@ -40,6 +40,12 @@ functions:
     arguments:
       - type: size_t
       - type: size_t
+  - name: memalignment
+    standards:
+      - gnu
+    return_type: size_t
+    arguments:
+      - type: const void *
   - name: realloc
     standards:
       - stdc

>From 8b50acb68422028a5c4c54ce610302593c36e5ef Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 06:01:48 +0200
Subject: [PATCH 09/15] [libc] improve `memalignment`

---
 libc/src/stdlib/memalignment.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/libc/src/stdlib/memalignment.c b/libc/src/stdlib/memalignment.c
index bf182f16ea138..a55d9f3b9b0a7 100644
--- a/libc/src/stdlib/memalignment.c
+++ b/libc/src/stdlib/memalignment.c
@@ -4,16 +4,12 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(size_t, memalignment, (const void *p)) {
-  if (p == NULL) {
+  if (p == NULL)
     return 0;
-  }
 
-  uintptr_t addr = (uintptr_t)p;
+  uintptr_t addr = reinterpret_cast<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);
+  return 1 << __builtin_ctzg(addr);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From a2ae994785ccad31cd9d824a6703120f3ca03060 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 16:28:38 +0200
Subject: [PATCH 10/15] chore: correct file extension of `memalignment`

---
 libc/src/stdlib/{memalignment.c => memalignment.cpp} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename libc/src/stdlib/{memalignment.c => memalignment.cpp} (100%)

diff --git a/libc/src/stdlib/memalignment.c b/libc/src/stdlib/memalignment.cpp
similarity index 100%
rename from libc/src/stdlib/memalignment.c
rename to libc/src/stdlib/memalignment.cpp

>From 931115f140912b05850f1e5bfaa3a35b1b0ebf98 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 16:41:47 +0200
Subject: [PATCH 11/15] refactor: use `cpp::countr_zero` instead of
 `__builtin_ctzg`

---
 libc/src/stdlib/memalignment.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/libc/src/stdlib/memalignment.cpp b/libc/src/stdlib/memalignment.cpp
index a55d9f3b9b0a7..9eba4928d8616 100644
--- a/libc/src/stdlib/memalignment.cpp
+++ b/libc/src/stdlib/memalignment.cpp
@@ -1,15 +1,15 @@
 #include "src/stdlib/memalignment.h"
 #include "src/__support/macros/config.h"
-
+#include "src/__support/CPP/bit.h"
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(size_t, memalignment, (const void *p)) {
-  if (p == NULL)
+  if (p == nullptr)
     return 0;
 
   uintptr_t addr = reinterpret_cast<uintptr_t>(p);
 
-  return 1 << __builtin_ctzg(addr);
+  return 1 << cpp::countr_zero(addr);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From ff7a9bca3cefd4dcc89d9f4d5948fc466724887a Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 16:42:16 +0200
Subject: [PATCH 12/15] build: add `memalignment` to `CMakeLists.txt`

---
 libc/src/stdlib/CMakeLists.txt | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 63eb358717656..5afb06ecc4332 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -385,6 +385,11 @@ if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
       DEPENDS
         ${SCUDO_DEPS}
     )
+    add_entrypoint_external(
+      memalignment
+      DEPENDS
+        ${SCUDO_DEPS}
+    )
     add_entrypoint_external(
       calloc
       DEPENDS
@@ -414,6 +419,9 @@ if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
     add_entrypoint_external(
       malloc
     )
+    add_entrypoint_external(
+      memalignment
+    )
     add_entrypoint_external(
       calloc
     )
@@ -524,6 +532,12 @@ if(LIBC_TARGET_OS_IS_BAREMETAL OR LIBC_TARGET_OS_IS_GPU)
     DEPENDS
       .${LIBC_TARGET_OS}.malloc
   )
+  add_entrypoint_object(
+    memalignment
+    ALIAS
+    DEPENDS
+      .${LIBC_TARGET_OS}.memalignment
+  )
   add_entrypoint_object(
     free
     ALIAS

>From edc13a92605ef749e5372f58e154dc60f8fa48b3 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 17:27:08 +0200
Subject: [PATCH 13/15] chore: add new line to the EOF of
 `memalignment_test.cpp`

---
 libc/test/src/stdlib/memalignment_test.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/test/src/stdlib/memalignment_test.cpp b/libc/test/src/stdlib/memalignment_test.cpp
index 91df893cb5f8f..9f3fb820ea080 100644
--- a/libc/test/src/stdlib/memalignment_test.cpp
+++ b/libc/test/src/stdlib/memalignment_test.cpp
@@ -64,4 +64,5 @@ TEST(LlvmLibcMemAlignmentTest, SpecificAlignment) {
   uintptr_t addr_complex = 0x1234560; // 16-byte aligned (ends in 0)
   void *ptr_complex = reinterpret_cast<void *>(addr_complex);
   EXPECT_EQ(LIBC_NAMESPACE::memalignment(ptr_complex), static_cast<size_t>(16));
-}
\ No newline at end of file
+} 
+ 
\ No newline at end of file

>From 5ab7da57417cf02eb24bb80207bf2bed2c48684a Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sat, 22 Mar 2025 19:27:15 +0200
Subject: [PATCH 14/15] fix: `memalignment` build entrypoints

---
 libc/src/stdlib/CMakeLists.txt      | 11 ++++++-----
 libc/test/src/stdlib/CMakeLists.txt | 23 +++++++++++------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
index 5afb06ecc4332..20448c47f0e63 100644
--- a/libc/src/stdlib/CMakeLists.txt
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -345,6 +345,12 @@ add_entrypoint_object(
     .rand_util
 )
 
+add_entrypoint_external(
+  memalignment
+  DEPENDS
+    ${SCUDO_DEPS}
+)
+
 if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
   if(LLVM_LIBC_INCLUDE_SCUDO)
     set(SCUDO_DEPS "")
@@ -385,11 +391,6 @@ if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU)
       DEPENDS
         ${SCUDO_DEPS}
     )
-    add_entrypoint_external(
-      memalignment
-      DEPENDS
-        ${SCUDO_DEPS}
-    )
     add_entrypoint_external(
       calloc
       DEPENDS
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
index 93324a836f555..302971a078c17 100644
--- a/libc/test/src/stdlib/CMakeLists.txt
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -368,6 +368,17 @@ add_libc_test(
     libc.src.stdlib.srand
 )
 
+add_libc_test(
+  memalignment_test
+  SUITE
+    libc-stdlib-tests
+  SRCS
+    memalignment_test.cpp
+  DEPENDS
+    libc.include.stdlib
+    libc.src.stdlib.memalignment
+)
+
 if(LLVM_LIBC_FULL_BUILD)
 
   add_libc_test(
@@ -457,16 +468,4 @@ if(LLVM_LIBC_FULL_BUILD)
         libc.src.stdlib.free
     )
   endif()
-  add_libc_test(
-    memalignment_test
-    # The EXPECT_EXITS test is only availible for unit tests.
-    UNIT_TEST_ONLY
-    SUITE
-      libc-stdlib-tests
-    SRCS
-      memalignment_test.cpp
-    DEPENDS
-      libc.include.stdlib
-      libc.src.stdlib.memalignment
-  )
 endif()

>From 51de1430dde907f51c848ab513ae23985599afe0 Mon Sep 17 00:00:00 2001
From: hulxv <hulxxv at gmail.com>
Date: Sun, 23 Mar 2025 17:54:15 +0200
Subject: [PATCH 15/15] fix: correct the standard of   `memalignment`

---
 .gitignore                      | 4 ++++
 libc/include/stdlib-malloc.yaml | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index a84268a7f6863..78e9694bcf3a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,3 +73,7 @@ pythonenv*
 /clang/utils/analyzer/projects/*/RefScanBuildResults
 # automodapi puts generated documentation files here.
 /lldb/docs/python_api/
+
+
+build*
+/.gitignore
\ No newline at end of file
diff --git a/libc/include/stdlib-malloc.yaml b/libc/include/stdlib-malloc.yaml
index 597ebc30df764..35cd9146170b3 100644
--- a/libc/include/stdlib-malloc.yaml
+++ b/libc/include/stdlib-malloc.yaml
@@ -42,7 +42,7 @@ functions:
       - type: size_t
   - name: memalignment
     standards:
-      - gnu
+      - stdc
     return_type: size_t
     arguments:
       - type: const void *



More information about the llvm-commits mailing list