Skip to content

Commit 1d85610

Browse files
committed
[Support] Integrate SipHash.cpp into libSupport.
Start building it as part of the library, with some minor tweaks compared to the reference implementation: - templatize cROUNDS/dROUNDS, as well as 8B/16B result type - replace assert with static_assert - return the result directly, as uint64_t/uint128_t - remove big-endian support - use LLVM_FALLTHROUGH The siphash function itself isn't used yet, and will be in a follow-up commit.
1 parent a1dbd8a commit 1d85610

File tree

2 files changed

+22
-49
lines changed

2 files changed

+22
-49
lines changed

llvm/lib/Support/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,6 @@ endif()
127127

128128
add_subdirectory(BLAKE3)
129129

130-
# Temporarily ignore SipHash.cpp before we fully integrate it into LLVMSupport.
131-
set(LLVM_OPTIONAL_SOURCES SipHash.cpp)
132-
133130
add_llvm_component_library(LLVMSupport
134131
ABIBreak.cpp
135132
AMDGPUMetadata.cpp
@@ -226,6 +223,7 @@ add_llvm_component_library(LLVMSupport
226223
SHA1.cpp
227224
SHA256.cpp
228225
Signposts.cpp
226+
SipHash.cpp
229227
SmallPtrSet.cpp
230228
SmallVector.cpp
231229
SourceMgr.cpp

llvm/lib/Support/SipHash.cpp

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,15 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "siphash.h"
10-
#include <assert.h>
11-
#include <stddef.h>
12-
#include <stdint.h>
9+
#include "llvm/Support/Compiler.h"
10+
#include <cstdint>
11+
#include <cstring>
1312

1413
// Lightly adapted from the SipHash reference C implementation by
1514
// Jean-Philippe Aumasson and Daniel J. Bernstein.
1615

17-
/* default: SipHash-2-4 */
18-
#ifndef cROUNDS
19-
#define cROUNDS 2
20-
#endif
21-
#ifndef dROUNDS
22-
#define dROUNDS 4
23-
#endif
24-
2516
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
2617

27-
#define U32TO8_LE(p, v) \
28-
(p)[0] = (uint8_t)((v)); \
29-
(p)[1] = (uint8_t)((v) >> 8); \
30-
(p)[2] = (uint8_t)((v) >> 16); \
31-
(p)[3] = (uint8_t)((v) >> 24);
32-
33-
#define U64TO8_LE(p, v) \
34-
U32TO8_LE((p), (uint32_t)((v))); \
35-
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
36-
3718
#define U8TO64_LE(p) \
3819
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
3920
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
@@ -58,21 +39,15 @@
5839
v2 = ROTL(v2, 32); \
5940
} while (0)
6041

61-
/*
62-
Computes a SipHash value
63-
*in: pointer to input data (read-only)
64-
inlen: input data length in bytes (any size_t value)
65-
*k: pointer to the key data (read-only), must be 16 bytes
66-
*out: pointer to output data (write-only), outlen bytes must be allocated
67-
outlen: length of the output in bytes, must be 8 or 16
68-
*/
69-
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
70-
const size_t outlen) {
42+
template <int cROUNDS, int dROUNDS, class ResultTy>
43+
static inline ResultTy siphash(const unsigned char *in, uint64_t inlen,
44+
const unsigned char (&k)[16]) {
7145

7246
const unsigned char *ni = (const unsigned char *)in;
7347
const unsigned char *kk = (const unsigned char *)k;
7448

75-
assert((outlen == 8) || (outlen == 16));
49+
static_assert(sizeof(ResultTy) == 8 || sizeof(ResultTy) == 16,
50+
"result type should be uint64_t or uint128_t");
7651
uint64_t v0 = UINT64_C(0x736f6d6570736575);
7752
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
7853
uint64_t v2 = UINT64_C(0x6c7967656e657261);
@@ -89,7 +64,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
8964
v1 ^= k1;
9065
v0 ^= k0;
9166

92-
if (outlen == 16)
67+
if (sizeof(ResultTy) == 16)
9368
v1 ^= 0xee;
9469

9570
for (; ni != end; ni += 8) {
@@ -105,22 +80,22 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
10580
switch (left) {
10681
case 7:
10782
b |= ((uint64_t)ni[6]) << 48;
108-
/* FALLTHRU */
83+
LLVM_FALLTHROUGH;
10984
case 6:
11085
b |= ((uint64_t)ni[5]) << 40;
111-
/* FALLTHRU */
86+
LLVM_FALLTHROUGH;
11287
case 5:
11388
b |= ((uint64_t)ni[4]) << 32;
114-
/* FALLTHRU */
89+
LLVM_FALLTHROUGH;
11590
case 4:
11691
b |= ((uint64_t)ni[3]) << 24;
117-
/* FALLTHRU */
92+
LLVM_FALLTHROUGH;
11893
case 3:
11994
b |= ((uint64_t)ni[2]) << 16;
120-
/* FALLTHRU */
95+
LLVM_FALLTHROUGH;
12196
case 2:
12297
b |= ((uint64_t)ni[1]) << 8;
123-
/* FALLTHRU */
98+
LLVM_FALLTHROUGH;
12499
case 1:
125100
b |= ((uint64_t)ni[0]);
126101
break;
@@ -135,7 +110,7 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
135110

136111
v0 ^= b;
137112

138-
if (outlen == 16)
113+
if (sizeof(ResultTy) == 16)
139114
v2 ^= 0xee;
140115
else
141116
v2 ^= 0xff;
@@ -144,18 +119,18 @@ int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
144119
SIPROUND;
145120

146121
b = v0 ^ v1 ^ v2 ^ v3;
147-
U64TO8_LE(out, b);
148122

149-
if (outlen == 8)
150-
return 0;
123+
uint64_t firstHalf = b;
124+
if (sizeof(ResultTy) == 8)
125+
return firstHalf;
151126

152127
v1 ^= 0xdd;
153128

154129
for (i = 0; i < dROUNDS; ++i)
155130
SIPROUND;
156131

157132
b = v0 ^ v1 ^ v2 ^ v3;
158-
U64TO8_LE(out + 8, b);
133+
uint64_t secondHalf = b;
159134

160-
return 0;
135+
return firstHalf | (ResultTy(secondHalf) << (sizeof(ResultTy) == 8 ? 0 : 64));
161136
}

0 commit comments

Comments
 (0)