Skip to content

Commit 26c651c

Browse files
committed
deps: V8: cherry-pick 1b3a4f0c34a1
Original commit message: [msvc] fix build with neon intrinsics This compilation error was found by NodeJS when updating V8: nodejs/node-v8#240 MSVC reports an error with "too many initializer" for type uint32x4_t. --- Under gcc/clang, this is a typedef to a builtin type. For MSVC, it is a typedef to this union: typedef union __n128 { unsigned __int64 n128_u64[2]; unsigned __int32 n128_u32[4]; ... } __n128; C++ mandates that only first member of union can be initialized at declaration. Thus, it can only be initialized with {uint64_t, uint64_t}. VS people proposed to use designated initializer instead: var = {.n128_u32={1, 2, 3, 8}} https://developercommunity.visualstudio.com/t/error-c2078-too-many-initializers-when-using-arm-n/402911 But, you need to use /std:c++20 for this, which is not the case in v8. --- Thus, the only solution is to implement a hack specifically for MSVC, where you build two uint64, from four uint32. --------------------------------------- Once solved, another error is reported: templated function extract_first_nonzero_index is specialized twice. This is because, with MSVC, uint32x4_t and uint64x2_t are typedef to the same __n128 union. The fix is to drop templates, and use explicit function names instead. Bug: v8:13312 Change-Id: I231d8cf01c05af01af319d56d5666c415f8b989b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3913035 Reviewed-by: Igor Sheludko <[email protected]> Reviewed-by: Jakob Kummerow <[email protected]> Commit-Queue: Jakob Kummerow <[email protected]> Cr-Commit-Position: refs/heads/main@{#83404} Refs: v8/v8@1b3a4f0 PR-URL: #44741 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Jiawen Geng <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent c8ff2df commit 26c651c

File tree

2 files changed

+20
-12
lines changed

2 files changed

+20
-12
lines changed

common.gypi

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.8',
39+
'v8_embedder_string': '-node.9',
4040

4141
##### V8 defaults for Node.js #####
4242

deps/v8/src/objects/simd.cc

+19-11
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,29 @@ inline uintptr_t slow_search(T* array, uintptr_t array_len, uintptr_t index,
8989
// max(v & mask) = 4
9090
// index of the first match = 4-max = 4-4 = 0
9191
//
92-
template <typename T>
93-
inline int extract_first_nonzero_index(T v) {
94-
UNREACHABLE();
95-
}
9692

97-
template <>
98-
V8_ALLOW_UNUSED inline int extract_first_nonzero_index(uint32x4_t v) {
99-
uint32x4_t mask = {4, 3, 2, 1};
93+
// With MSVC, uint32x4_t and uint64x2_t typedef to a union, where first member
94+
// is uint64_t[2], and not uint32_t[4].
95+
// C++ standard dictates that a union can only be initialized through its first
96+
// member, which forces us to have uint64_t[2] for definition.
97+
#if defined(_MSC_VER)
98+
#define PACK32x4(w, x, y, z) \
99+
{ ((w) + (uint64_t(x) << 32)), ((y) + (uint64_t(z) << 32)) }
100+
#else
101+
#define PACK32x4(w, x, y, z) \
102+
{ (w), (x), (y), (z) }
103+
#endif // MSVC workaround
104+
105+
V8_ALLOW_UNUSED inline int extract_first_nonzero_index_uint32x4_t(
106+
uint32x4_t v) {
107+
uint32x4_t mask = PACK32x4(4, 3, 2, 1);
100108
mask = vandq_u32(mask, v);
101109
return 4 - vmaxvq_u32(mask);
102110
}
103111

104-
template <>
105-
inline int extract_first_nonzero_index(uint64x2_t v) {
106-
uint32x4_t mask = {2, 0, 1, 0}; // Could also be {2,2,1,1} or {0,2,0,1}
112+
inline int extract_first_nonzero_index_uint64x2_t(uint64x2_t v) {
113+
uint32x4_t mask =
114+
PACK32x4(2, 0, 1, 0); // Could also be {2,2,1,1} or {0,2,0,1}
107115
mask = vandq_u32(mask, vreinterpretq_u32_u64(v));
108116
return 2 - vmaxvq_u32(mask);
109117
}
@@ -122,7 +130,7 @@ inline int32_t reinterpret_vmaxvq_u64(uint64x2_t v) {
122130
type_load vector = *reinterpret_cast<type_load*>(&array[index]); \
123131
type_eq eq = cmp(vector, search_element_vec); \
124132
if (movemask(eq)) { \
125-
return index + extract_first_nonzero_index(eq); \
133+
return index + extract_first_nonzero_index_##type_eq(eq); \
126134
} \
127135
} \
128136
}

0 commit comments

Comments
 (0)