[compiler-rt] [Compiler-rt] Implement AEABI Unaligned Read/Write Helpers in compiler-rt (PR #167913)

Simi Pallipurath via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 19 06:13:59 PST 2025


https://github.com/simpal01 updated https://github.com/llvm/llvm-project/pull/167913

>From ce6febc9728cde08e667e02da2ee0796d01c5987 Mon Sep 17 00:00:00 2001
From: Simi Pallipurath <simi.pallipurath at arm.com>
Date: Thu, 13 Nov 2025 14:50:54 +0000
Subject: [PATCH 1/2] [Compiler-rt] Implement AEABI Unaligned Read/Write
 Helpers in compiler-rt

This patch adds implementations for the __aeabi_uread
and __aeabi_uwrite helper functions to compiler-rt..
---
 compiler-rt/lib/builtins/CMakeLists.txt       |  4 +
 compiler-rt/lib/builtins/arm/aeabi_uread4.c   | 21 +++++
 compiler-rt/lib/builtins/arm/aeabi_uread8.c   | 21 +++++
 compiler-rt/lib/builtins/arm/aeabi_uwrite4.c  | 23 +++++
 compiler-rt/lib/builtins/arm/aeabi_uwrite8.c  | 23 +++++
 .../Unit/arm/aeabi_unaligned_access_test.c    | 88 +++++++++++++++++++
 6 files changed, 180 insertions(+)
 create mode 100644 compiler-rt/lib/builtins/arm/aeabi_uread4.c
 create mode 100644 compiler-rt/lib/builtins/arm/aeabi_uread8.c
 create mode 100644 compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
 create mode 100644 compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
 create mode 100644 compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c

diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
index 02e6ecfbdb60e..ebda0c87785c2 100644
--- a/compiler-rt/lib/builtins/CMakeLists.txt
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
@@ -470,6 +470,10 @@ set(arm_EABI_RT_SOURCES
   arm/aeabi_ldivmod.S
   arm/aeabi_uidivmod.S
   arm/aeabi_uldivmod.S
+  arm/aeabi_uread4.c
+  arm/aeabi_uread8.c
+  arm/aeabi_uwrite4.c
+  arm/aeabi_uwrite8.c
 )
 
 set(arm_EABI_CLIB_SOURCES
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread4.c b/compiler-rt/lib/builtins/arm/aeabi_uread4.c
new file mode 100644
index 0000000000000..4d333b4fdafc2
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_uread4.c
@@ -0,0 +1,21 @@
+//===-- aeabi_uread4.c - ARM EABI Helper — Unaligned 4-Byte Memory Read --===//
+//
+// 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
+//
+//===-----------------------------------------------------------------------------===//
+
+typedef struct {
+  char v[4];
+} v4;
+
+int __aeabi_uread4(void *p) {
+  union {
+    v4 v;
+    int u;
+  } u;
+
+  u.v = *(v4 *)p;
+  return u.u;
+}
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread8.c b/compiler-rt/lib/builtins/arm/aeabi_uread8.c
new file mode 100644
index 0000000000000..7d0d60df343b3
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_uread8.c
@@ -0,0 +1,21 @@
+//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 8-Byte Memory Read --===//
+//
+// 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
+//
+//===-----------------------------------------------------------------------------===//
+
+typedef struct {
+  char v[8];
+} v8;
+
+long long __aeabi_uread8(void *p) {
+  union {
+    v8 v;
+    long long u;
+  } u;
+
+  u.v = *(v8 *)p;
+  return u.u;
+}
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
new file mode 100644
index 0000000000000..0736fdb821dc6
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
@@ -0,0 +1,23 @@
+//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 4-Byte Memory Write --===//
+//
+// 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
+//
+//===-----------------------------------------------------------------------------===//
+
+typedef struct {
+  char v[4];
+} v4;
+
+int __aeabi_uwrite4(int val, void *p) {
+  union {
+    v4 v;
+    int u;
+  } u;
+
+  u.u = val;
+  *(v4 *)p = u.v;
+
+  return val;
+}
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
new file mode 100644
index 0000000000000..a482a652682cc
--- /dev/null
+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
@@ -0,0 +1,23 @@
+//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 8-Byte Memory Write --===//
+//
+// 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
+//
+//===-----------------------------------------------------------------------------===//
+
+typedef struct {
+  char v[8];
+} v8;
+
+long long __aeabi_uwrite8(long long val, void *p) {
+  union {
+    v8 v;
+    long long u;
+  } u;
+
+  u.u = val;
+  *(v8 *)p = u.v;
+
+  return val;
+}
diff --git a/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c b/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c
new file mode 100644
index 0000000000000..cda714e91e46c
--- /dev/null
+++ b/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c
@@ -0,0 +1,88 @@
+// REQUIRES: arm-target-arch || armv6m-target-arch
+// RUN: %clang_builtins %s %librt -o %t && %run %t
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+extern int __aeabi_uread4(void *);
+extern int __aeabi_uwrite4(int, void *);
+extern long long __aeabi_uread8(void *);
+extern long long __aeabi_uwrite8(long long, void *);
+
+#define lenof(x) (sizeof((x)) / sizeof(*(x)))
+
+int test_unaligned(void) {
+  long long target8;
+  int target4;
+  const char source[] = "abcdefghijklmno";
+  static char dest1[lenof(source)], dest2[lenof(source)];
+  int i, j;
+
+  for (i = 0; i < 7; i++) {
+    memcpy(&target8, source + i, 8);
+    if (__aeabi_uread8(source + i) != target8) {
+      printf("error in __aeabi_uread8 => output = %llx, expected %llx\n",
+             __aeabi_uread8(source + i), target8);
+      return 1;
+    }
+
+    memcpy(dest1, source, lenof(source));
+    memcpy(dest2, source, lenof(source));
+    target8 = 0x4142434445464748ULL;
+    if (__aeabi_uwrite8(target8, dest1 + i) != target8) {
+      printf("error in __aeabi_uwrite8 => output = %llx, expected %llx\n",
+             __aeabi_uwrite8(target8, dest1 + i), target8);
+      return 1;
+    }
+    memcpy(dest2 + i, &target8, 8);
+    if (memcmp(dest1, dest2, lenof(source)) != 0) {
+      int pos = -1;
+      printf("error in __aeabi_uwrite8: memcmp failed: buffers differ!\n");
+      for (int j = 0; j < 8; ++j) {
+        if (dest1[j] != dest2[j]) {
+          pos = j;
+          break;
+        }
+      }
+      printf("error: 8-byte write mismatch at offset %d\n", pos);
+      return 1;
+    }
+
+    memcpy(&target4, source + i, 4);
+    if (__aeabi_uread4(source + i) != target4) {
+      printf("error in __aeabi_uread4 => output = %x, expected %x\n",
+             __aeabi_uread4(source + i), target4);
+      return 1;
+    }
+
+    memcpy(dest1, source, lenof(source));
+    memcpy(dest2, source, lenof(source));
+    target4 = 0x414243444;
+    if (__aeabi_uwrite4(target4, dest1 + i) != target4) {
+      printf("error in __aeabi_uwrite4 => output = %x, expected %x\n",
+             __aeabi_uwrite4(target4, dest1 + i), target4);
+      return 1;
+    }
+    memcpy(dest2 + i, &target4, 4);
+    if (memcmp(dest1, dest2, lenof(source)) != 0) {
+      int pos = -1;
+      printf("error in __aeabi_uwrite4: memcmp failed: buffers differ!\n");
+      for (int j = 0; j < 4; ++j) {
+        if (dest1[j] != dest2[j]) {
+          pos = j;
+          break;
+        }
+      }
+      printf("error: 4-byte write mismatch at offset %d\n", pos);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int main() {
+  if (test_unaligned())
+    return 1;
+  return 0;
+}

>From 4a69df0696852540e5082df8d9631efc869eb889 Mon Sep 17 00:00:00 2001
From: Simi Pallipurath <simi.pallipurath at arm.com>
Date: Wed, 19 Nov 2025 14:13:05 +0000
Subject: [PATCH 2/2] fixup! [Compiler-rt] Implement AEABI Unaligned Read/Write
 Helpers in compiler-rt

---
 compiler-rt/lib/builtins/arm/aeabi_uread4.c      |  7 +++++--
 compiler-rt/lib/builtins/arm/aeabi_uread8.c      |  7 +++++--
 compiler-rt/lib/builtins/arm/aeabi_uwrite4.c     |  7 +++++--
 compiler-rt/lib/builtins/arm/aeabi_uwrite8.c     |  7 +++++--
 .../Unit/arm/aeabi_unaligned_access_test.c       | 16 +++++++---------
 5 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread4.c b/compiler-rt/lib/builtins/arm/aeabi_uread4.c
index 4d333b4fdafc2..d6ec0e83fc45a 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uread4.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uread4.c
@@ -1,10 +1,13 @@
-//===-- aeabi_uread4.c - ARM EABI Helper — Unaligned 4-Byte Memory Read --===//
+//===-- aeabi_uread4.c - ARM EABI Helper — Unaligned 4-Byte Memory Read ------------------===//
 //
 // 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
 //
-//===-----------------------------------------------------------------------------===//
+// Implements __aeabi_uread4 for unaligned memory accesses.
+// Reference: Arm RTABI32 Specification.
+// https://github.com/ARM-software/abi-aa/blob/main/rtabi32/rtabi32.rst#unaligned-memory-access
+//===-------------------------------------------------------------------------------------===//
 
 typedef struct {
   char v[4];
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread8.c b/compiler-rt/lib/builtins/arm/aeabi_uread8.c
index 7d0d60df343b3..5274d28405a0c 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uread8.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uread8.c
@@ -1,10 +1,13 @@
-//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 8-Byte Memory Read --===//
+//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 8-Byte Memory Read -----------------===//
 //
 // 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
 //
-//===-----------------------------------------------------------------------------===//
+// Implements __aeabi_uread8 for unaligned memory accesses.
+// Reference: Arm RTABI32 Specification.
+// https://github.com/ARM-software/abi-aa/blob/main/rtabi32/rtabi32.rst#unaligned-memory-access
+//===-------------------------------------------------------------------------------------===//
 
 typedef struct {
   char v[8];
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
index 0736fdb821dc6..bc7bc983f9b67 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
@@ -1,10 +1,13 @@
-//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 4-Byte Memory Write --===//
+//===-- aeabi_uwrite4.c - ARM EABI Helper — Unaligned 4-Byte Memory Write ---------------===//
 //
 // 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
 //
-//===-----------------------------------------------------------------------------===//
+// Implements __aeabi_uwrite4 for unaligned memory accesses.
+// Reference: Arm RTABI32 Specification.
+// https://github.com/ARM-software/abi-aa/blob/main/rtabi32/rtabi32.rst#unaligned-memory-access
+//===-------------------------------------------------------------------------------------===//
 
 typedef struct {
   char v[4];
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
index a482a652682cc..9584da54a8940 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
@@ -1,10 +1,13 @@
-//===-- aeabi_uread8.c - ARM EABI Helper — Unaligned 8-Byte Memory Write --===//
+//===-- aeabi_uwrite8.c - ARM EABI Helper — Unaligned 8-Byte Memory Write ---------------===//
 //
 // 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
 //
-//===-----------------------------------------------------------------------------===//
+// Implements __aeabi_uwrite8 for unaligned memory accesses.
+// Reference: Arm RTABI32 Specification.
+// https://github.com/ARM-software/abi-aa/blob/main/rtabi32/rtabi32.rst#unaligned-memory-access
+//===-------------------------------------------------------------------------------------===//
 
 typedef struct {
   char v[8];
diff --git a/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c b/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c
index cda714e91e46c..a947e097b9c03 100644
--- a/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c
+++ b/compiler-rt/test/builtins/Unit/arm/aeabi_unaligned_access_test.c
@@ -10,13 +10,11 @@ extern int __aeabi_uwrite4(int, void *);
 extern long long __aeabi_uread8(void *);
 extern long long __aeabi_uwrite8(long long, void *);
 
-#define lenof(x) (sizeof((x)) / sizeof(*(x)))
-
 int test_unaligned(void) {
   long long target8;
   int target4;
   const char source[] = "abcdefghijklmno";
-  static char dest1[lenof(source)], dest2[lenof(source)];
+  static char dest1[_Countof(source)], dest2[_Countof(source)];
   int i, j;
 
   for (i = 0; i < 7; i++) {
@@ -27,8 +25,8 @@ int test_unaligned(void) {
       return 1;
     }
 
-    memcpy(dest1, source, lenof(source));
-    memcpy(dest2, source, lenof(source));
+    memcpy(dest1, source, _Countof(source));
+    memcpy(dest2, source, _Countof(source));
     target8 = 0x4142434445464748ULL;
     if (__aeabi_uwrite8(target8, dest1 + i) != target8) {
       printf("error in __aeabi_uwrite8 => output = %llx, expected %llx\n",
@@ -36,7 +34,7 @@ int test_unaligned(void) {
       return 1;
     }
     memcpy(dest2 + i, &target8, 8);
-    if (memcmp(dest1, dest2, lenof(source)) != 0) {
+    if (memcmp(dest1, dest2, _Countof(source)) != 0) {
       int pos = -1;
       printf("error in __aeabi_uwrite8: memcmp failed: buffers differ!\n");
       for (int j = 0; j < 8; ++j) {
@@ -56,8 +54,8 @@ int test_unaligned(void) {
       return 1;
     }
 
-    memcpy(dest1, source, lenof(source));
-    memcpy(dest2, source, lenof(source));
+    memcpy(dest1, source, _Countof(source));
+    memcpy(dest2, source, _Countof(source));
     target4 = 0x414243444;
     if (__aeabi_uwrite4(target4, dest1 + i) != target4) {
       printf("error in __aeabi_uwrite4 => output = %x, expected %x\n",
@@ -65,7 +63,7 @@ int test_unaligned(void) {
       return 1;
     }
     memcpy(dest2 + i, &target4, 4);
-    if (memcmp(dest1, dest2, lenof(source)) != 0) {
+    if (memcmp(dest1, dest2, _Countof(source)) != 0) {
       int pos = -1;
       printf("error in __aeabi_uwrite4: memcmp failed: buffers differ!\n");
       for (int j = 0; j < 4; ++j) {



More information about the llvm-commits mailing list