[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 07:35:09 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/3] [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/3] 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) {
>From a3ce141902bedaea0757462f7a6a531a3e2f7449 Mon Sep 17 00:00:00 2001
From: Simi Pallipurath <simi.pallipurath at arm.com>
Date: Wed, 19 Nov 2025 14:28:39 +0000
Subject: [PATCH 3/3] fixup! [Compiler-rt] Implement AEABI Unaligned Read/Write
Helpers in compiler-rt
Apply clang-format to address style issues in the previous patch.
---
compiler-rt/lib/builtins/arm/aeabi_uread4.c | 2 +-
compiler-rt/lib/builtins/arm/aeabi_uread8.c | 2 +-
compiler-rt/lib/builtins/arm/aeabi_uwrite4.c | 2 +-
compiler-rt/lib/builtins/arm/aeabi_uwrite8.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread4.c b/compiler-rt/lib/builtins/arm/aeabi_uread4.c
index d6ec0e83fc45a..564ae73b085a5 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uread4.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uread4.c
@@ -1,4 +1,4 @@
-//===-- 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.
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uread8.c b/compiler-rt/lib/builtins/arm/aeabi_uread8.c
index 5274d28405a0c..b9745191d9764 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uread8.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uread8.c
@@ -1,4 +1,4 @@
-//===-- 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.
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
index bc7bc983f9b67..a7312be94a0b0 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite4.c
@@ -1,4 +1,4 @@
-//===-- aeabi_uwrite4.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.
diff --git a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
index 9584da54a8940..3a29c690b4c80 100644
--- a/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
+++ b/compiler-rt/lib/builtins/arm/aeabi_uwrite8.c
@@ -1,4 +1,4 @@
-//===-- aeabi_uwrite8.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.
More information about the llvm-commits
mailing list