Skip to content

Commit 6840b7d

Browse files
committed
BUG: Fix LUT compile failures on MSVC and Highway debug builds
Two portability issues in the transposed-load LUT path: - kTransposeLength evaluated to 0 when kInitTranspose is false (kRows < kTransposeBy), producing a zero-size array that MSVC rejects. Clamp it to 1 as an unused placeholder. - Lanes(du) is not constexpr in Highway debug builds, so it cannot initialize a constexpr size_t. Use the HWY_LANES(T) macro, which is a compile-time constant in all build modes. Also cleaned up the surrounding code: - Removed the LoadTranspose_ helper and inlined its body into the Load path. It was an extra indirection that only forwarded to LoadTransposeX2_/X4_ or fell back to LoadRow_; the dispatch reads clearer inline. - Dropped the static_assert(kTransposeBy == 4) in that helper. Older compilers evaluate it eagerly in the discarded if-constexpr branch even though it is guarded, so it fired spuriously."
1 parent 5f1646d commit 6840b7d

1 file changed

Lines changed: 20 additions & 33 deletions

File tree

npsr/lut-inl.h

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,16 @@ class Lut {
4444
// Implementation details for transposition optimization
4545
static constexpr size_t kTransposeBy = HWY_LANES(T);
4646
static constexpr size_t kTransposeTail = kRows % kTransposeBy;
47-
static constexpr size_t kTransposeLength = (kRows - kTransposeTail) * kCols;
48-
4947
// Determine at compile-time if transposition optimization is viable
5048
static constexpr bool kInitTranspose = !HWY_HAVE_SCALABLE && (
5149
kRows / kTransposeBy > 0 && kCols % kTransposeBy == 0 &&
5250
(kTransposeBy == 2 || kTransposeBy == 4) // Currently supports 2x or 4x unrolling
5351
);
52+
// When kInitTranspose is false kTransposeLength would be 0 (kRows < kTransposeBy),
53+
// which would produce a zero-size array (MSVC forbid it) — use 1 as a placeholder instead.
54+
static constexpr size_t kTransposeLength = kInitTranspose
55+
? (kRows - kTransposeTail) * kCols
56+
: 1;
5457

5558
/**
5659
* @brief Constructs the table from row arrays.
@@ -89,8 +92,19 @@ class Lut {
8992

9093
#if !HWY_HAVE_SCALABLE
9194
// Try optimized transposed load first
92-
if constexpr (kInitTranspose) {
93-
LoadTranspose_(idx, out...);
95+
using DU = DFromV<VU>;
96+
const DU du;
97+
constexpr size_t kLanes = HWY_LANES(TU);
98+
// Try optimized transposed load first
99+
if constexpr (kInitTranspose && kLanes == kTransposeBy) {
100+
HWY_ALIGN TU s_idx[kLanes];
101+
Store(ShiftLeft<kTransposeBy/2>(idx), du, s_idx);
102+
if constexpr (kTransposeBy == 2) {
103+
LoadTransposeX2_(s_idx, idx, out...);
104+
}
105+
else {
106+
LoadTransposeX4_(s_idx, idx, out...);
107+
}
94108
}
95109
#else
96110
if constexpr (0) {}
@@ -137,33 +151,6 @@ class Lut {
137151
}
138152

139153
// --- Transposed Load Implementation ---
140-
141-
template <size_t Off = 0, typename VU, typename... OutV>
142-
HWY_INLINE void LoadTranspose_(const VU &idx, OutV &...out) const {
143-
using namespace hn;
144-
using DU = DFromV<VU>;
145-
using TU = TFromD<DU>;
146-
const DU du;
147-
148-
constexpr size_t kLanes = Lanes(du);
149-
150-
// Only use transposed load if vector lanes match the transpose blocking factor
151-
if constexpr (kLanes == kTransposeBy) {
152-
HWY_ALIGN TU s_idx[kLanes];
153-
Store(ShiftLeft<kTransposeBy/2>(idx), du, s_idx);
154-
if constexpr (kTransposeBy == 2) {
155-
LoadTransposeX2_(s_idx, idx, out...);
156-
}
157-
else {
158-
static_assert(kTransposeBy == 4, "It's already guarded by kInitTranspose");
159-
LoadTransposeX4_(s_idx, idx, out...);
160-
}
161-
}
162-
else {
163-
LoadRow_(idx, out...);
164-
}
165-
}
166-
167154
// 2-wide transposed load optimization
168155
template <size_t Off = 0, typename TU, typename VU, typename OutV0, typename... OutV>
169156
HWY_INLINE void LoadTransposeX2_(const TU *trans_idx, const VU &idx,
@@ -226,6 +213,7 @@ class Lut {
226213
// Selects the best row loading strategy based on vector size vs table width
227214
template <size_t Off = 0, typename VU, typename... OutV>
228215
HWY_INLINE void LoadRow_(const VU& idx, OutV& ...out) const {
216+
#if !HWY_HAVE_SCALABLE
229217
using namespace hn;
230218
using DU = DFromV<VU>;
231219
const DU du;
@@ -236,8 +224,7 @@ class Lut {
236224
using M = MFromD<D>;
237225
const D d;
238226

239-
#if !HWY_HAVE_SCALABLE
240-
constexpr size_t kLanes = Lanes(du);
227+
constexpr size_t kLanes = HWY_LANES(TI);
241228
// Strategy 1: Vector size equals table width (Single Table Lookup)
242229
if constexpr (kLanes == kCols) {
243230
const auto ind = IndicesFromVec(d, idx);

0 commit comments

Comments
 (0)