[llvm] [Support] Add SipHash-based 64-bit stable hash function (PR #160945)

via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 26 13:40:04 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-support

Author: Marco Elver (melver)

<details>
<summary>Changes</summary>

Factor out the 64-bit hash calculation in getPointerAuthStableSipHash()
as getStableSipHash(). This allows using the full 64-bit hash where we
require a stable hash.

Similar to getPointerAuthStableSipHash(), the new hash function is meant
to be stable across platforms and compiler versions.


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


3 Files Affected:

- (modified) llvm/include/llvm/Support/SipHash.h (+7) 
- (modified) llvm/lib/Support/SipHash.cpp (+8-3) 
- (modified) llvm/unittests/Support/SipHashTest.cpp (+7) 


``````````diff
diff --git a/llvm/include/llvm/Support/SipHash.h b/llvm/include/llvm/Support/SipHash.h
index 910cf59432c69..b090565641526 100644
--- a/llvm/include/llvm/Support/SipHash.h
+++ b/llvm/include/llvm/Support/SipHash.h
@@ -33,6 +33,13 @@ LLVM_ABI void getSipHash_2_4_64(ArrayRef<uint8_t> In, const uint8_t (&K)[16],
 LLVM_ABI void getSipHash_2_4_128(ArrayRef<uint8_t> In, const uint8_t (&K)[16],
                                  uint8_t (&Out)[16]);
 
+/// Compute a stable 64-bit hash of the given string.
+///
+/// The exact algorithm is the little-endian interpretation of the
+/// non-doubled (i.e. 64-bit) result of applying a SipHash-2-4 using
+/// a specific seed value which can be found in the source.
+LLVM_ABI uint64_t getStableSipHash(StringRef Str);
+
 /// Compute a stable non-zero 16-bit hash of the given string.
 ///
 /// The exact algorithm is the little-endian interpretation of the
diff --git a/llvm/lib/Support/SipHash.cpp b/llvm/lib/Support/SipHash.cpp
index 86dad66420435..382d36f0a8da5 100644
--- a/llvm/lib/Support/SipHash.cpp
+++ b/llvm/lib/Support/SipHash.cpp
@@ -35,14 +35,19 @@ void llvm::getSipHash_2_4_128(ArrayRef<uint8_t> In, const uint8_t (&K)[16],
   siphash<2, 4>(In.data(), In.size(), K, Out);
 }
 
-/// Compute an ABI-stable 16-bit hash of the given string.
-uint16_t llvm::getPointerAuthStableSipHash(StringRef Str) {
+/// Compute an ABI-stable 64-bit hash of the given string.
+uint64_t llvm::getStableSipHash(StringRef Str) {
   static const uint8_t K[16] = {0xb5, 0xd4, 0xc9, 0xeb, 0x79, 0x10, 0x4a, 0x79,
                                 0x6f, 0xec, 0x8b, 0x1b, 0x42, 0x87, 0x81, 0xd4};
 
   uint8_t RawHashBytes[8];
   getSipHash_2_4_64(arrayRefFromStringRef(Str), K, RawHashBytes);
-  uint64_t RawHash = endian::read64le(RawHashBytes);
+  return endian::read64le(RawHashBytes);
+}
+
+/// Compute an ABI-stable 16-bit hash of the given string.
+uint16_t llvm::getPointerAuthStableSipHash(StringRef Str) {
+  uint64_t RawHash = getStableSipHash(Str);
 
   // Produce a non-zero 16-bit discriminator.
   uint16_t Discriminator = (RawHash % 0xFFFF) + 1;
diff --git a/llvm/unittests/Support/SipHashTest.cpp b/llvm/unittests/Support/SipHashTest.cpp
index 7c557eb488acc..3037e6436e18d 100644
--- a/llvm/unittests/Support/SipHashTest.cpp
+++ b/llvm/unittests/Support/SipHashTest.cpp
@@ -50,6 +50,13 @@ TEST(SipHashTest, SipHash_2_4_128) {
   }
 }
 
+// Tests for the 64-bit stable SipHash wrapper.
+TEST(SipHashTest, StableSipHash) {
+  EXPECT_EQ(0xB2BB69BB0A2AC0F1UL, getStableSipHash(""));
+  EXPECT_EQ(0x9304ABFF427B72E8UL, getStableSipHash("strlen"));
+  EXPECT_EQ(0x55F45179A08AE51BUL, getStableSipHash("_ZN1 ind; f"));
+}
+
 // Tests for the ptrauth-specific SipHash wrapper.
 TEST(SipHashTest, PointerAuthSipHash) {
   // Test some basic cases.

``````````

</details>


https://github.com/llvm/llvm-project/pull/160945


More information about the llvm-commits mailing list