[libc-commits] [libc] [libc] Add Endian::from_{big, little}_endian (PR #203895)

Pavel Labath via libc-commits libc-commits at lists.llvm.org
Mon Jun 15 06:11:33 PDT 2026


https://github.com/labath created https://github.com/llvm/llvm-project/pull/203895

This is actually the same function as its to_ counterpart, but it lets us correctly express the intent.

The functions are already useful for implementing ntoh?, but I'll add other uses of them soon.

>From ee0ce2fc29daf4e8cfdeb7d6b76cb3079579d40e Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Mon, 15 Jun 2026 12:57:17 +0000
Subject: [PATCH] [libc] Add Endian::from_{big,little}_endian

This is actually the same function as its to_ counterpart, but it lets
us correctly express the intent.

The functions are already useful for implementing ntoh?, but I'll add
other uses of them soon.
---
 libc/src/__support/endian_internal.h             | 10 ++++++++++
 libc/src/arpa/inet/ntohl.cpp                     |  5 +----
 libc/src/arpa/inet/ntohs.cpp                     |  5 +----
 libc/test/src/__support/endian_internal_test.cpp |  4 ++++
 4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/libc/src/__support/endian_internal.h b/libc/src/__support/endian_internal.h
index 8d81329fd243d..0173cb5748b58 100644
--- a/libc/src/__support/endian_internal.h
+++ b/libc/src/__support/endian_internal.h
@@ -41,6 +41,16 @@ template <unsigned ORDER> struct Endian {
   static constexpr const bool IS_BIG = ORDER == __ORDER_BIG_ENDIAN__;
   template <typename T> LIBC_INLINE static T to_big_endian(T value);
   template <typename T> LIBC_INLINE static T to_little_endian(T value);
+
+  // Converting "to" and "from" a given endianness is actually the same
+  // operation, but we provide dedicated functions to let the user express their
+  // intent clearly.
+  template <typename T> LIBC_INLINE static T from_big_endian(T value) {
+    return to_big_endian(value);
+  }
+  template <typename T> LIBC_INLINE static T from_little_endian(T value) {
+    return to_little_endian(value);
+  }
 };
 
 // Little Endian specializations
diff --git a/libc/src/arpa/inet/ntohl.cpp b/libc/src/arpa/inet/ntohl.cpp
index d472107a1988c..255c24dcff81a 100644
--- a/libc/src/arpa/inet/ntohl.cpp
+++ b/libc/src/arpa/inet/ntohl.cpp
@@ -14,10 +14,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(uint32_t, ntohl, (uint32_t netlong)) {
-  if constexpr (Endian::IS_LITTLE)
-    return __builtin_bswap32(netlong);
-  else
-    return netlong;
+  return Endian::from_big_endian(netlong);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/arpa/inet/ntohs.cpp b/libc/src/arpa/inet/ntohs.cpp
index 9082ed928778e..79c9fb9e436da 100644
--- a/libc/src/arpa/inet/ntohs.cpp
+++ b/libc/src/arpa/inet/ntohs.cpp
@@ -14,10 +14,7 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(uint16_t, ntohs, (uint16_t netshort)) {
-  if constexpr (Endian::IS_LITTLE)
-    return __builtin_bswap16(netshort);
-  else
-    return netshort;
+  return Endian::from_big_endian(netshort);
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/test/src/__support/endian_internal_test.cpp b/libc/test/src/__support/endian_internal_test.cpp
index eab0f376e7495..a8a1df2262012 100644
--- a/libc/test/src/__support/endian_internal_test.cpp
+++ b/libc/test/src/__support/endian_internal_test.cpp
@@ -16,11 +16,15 @@ struct LlvmLibcEndian : testing::Test {
   template <typename T> void check(const T original, const T swapped) {
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     EXPECT_EQ(Endian::to_little_endian(original), original);
+    EXPECT_EQ(Endian::from_little_endian(original), original);
     EXPECT_EQ(Endian::to_big_endian(original), swapped);
+    EXPECT_EQ(Endian::from_big_endian(swapped), original);
 #endif
 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     EXPECT_EQ(Endian::to_big_endian(original), original);
+    EXPECT_EQ(Endian::from_big_endian(original), original);
     EXPECT_EQ(Endian::to_little_endian(original), swapped);
+    EXPECT_EQ(Endian::from_little_endian(swapped), original);
 #endif
   }
 };



More information about the libc-commits mailing list