Skip to content

Commit 029eb91

Browse files
AntoinePrvclaude
andcommitted
Fix NEON intrinsic wrappers for MSVC ARM64
On MSVC ARM64, NEON intrinsics are defined as function-like macros in arm64_neon.h. The previous `(OP##_u8)(a, b)` pattern suppresses macro expansion (a function-like macro only expands when its name is directly followed by `(`), causing 'undeclared identifier' errors. Replace with `::OP##_u8(a, b)` to allow macro expansion while explicitly qualifying to global scope, matching the pattern already used in xsimd_neon64.hpp for its WRAP_REDUCER macros. Also add a CI sanity-check step that compiles and runs a minimal NEON program before the full build, making it easier to diagnose compiler or include-path issues independently of xsimd. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent e8f03e6 commit 029eb91

2 files changed

Lines changed: 32 additions & 18 deletions

File tree

.github/workflows/windows.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ jobs:
1919
python3 -m pip install ninja
2020
- name: Checkout xsimd
2121
uses: actions/checkout@v6
22+
- name: Sanity check NEON intrinsics
23+
run: |
24+
cat > sanity_neon.cpp << 'EOF'
25+
#include <arm_neon.h>
26+
int main() {
27+
uint8x16_t a = vdupq_n_u8(1);
28+
uint8x16_t b = vdupq_n_u8(2);
29+
uint8x16_t c = vaddq_u8(a, b);
30+
(void)c;
31+
return 0;
32+
}
33+
EOF
34+
cl /nologo /EHsc sanity_neon.cpp /Fe:sanity_neon.exe
35+
./sanity_neon.exe
2236
- name: Setup
2337
run: cmake -B _build -DBUILD_TESTS=ON -DDOWNLOAD_DOCTEST=ON -DBUILD_BENCHMARK=ON -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release -G Ninja
2438
- name: Build

include/xsimd/arch/xsimd_neon.hpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@
3333
{ \
3434
XSIMD_INLINE auto(x_##OP##_u8)(uint8x16_t a, uint8x16_t b) noexcept -> RT<uint8x16_t> \
3535
{ \
36-
return (OP##_u8)(a, b); \
36+
return ::OP##_u8(a, b); \
3737
} \
3838
XSIMD_INLINE auto(x_##OP##_u16)(uint16x8_t a, uint16x8_t b) noexcept -> RT<uint16x8_t> \
3939
{ \
40-
return (OP##_u16)(a, b); \
40+
return ::OP##_u16(a, b); \
4141
} \
4242
XSIMD_INLINE auto(x_##OP##_u32)(uint32x4_t a, uint32x4_t b) noexcept -> RT<uint32x4_t> \
4343
{ \
44-
return (OP##_u32)(a, b); \
44+
return ::OP##_u32(a, b); \
4545
} \
4646
}
4747

@@ -51,15 +51,15 @@
5151
{ \
5252
XSIMD_INLINE auto(x_##OP##_s8)(int8x16_t a, int8x16_t b) noexcept -> RT<int8x16_t> \
5353
{ \
54-
return (OP##_s8)(a, b); \
54+
return ::OP##_s8(a, b); \
5555
} \
5656
XSIMD_INLINE auto(x_##OP##_s16)(int16x8_t a, int16x8_t b) noexcept -> RT<int16x8_t> \
5757
{ \
58-
return (OP##_s16)(a, b); \
58+
return ::OP##_s16(a, b); \
5959
} \
6060
XSIMD_INLINE auto(x_##OP##_s32)(int32x4_t a, int32x4_t b) noexcept -> RT<int32x4_t> \
6161
{ \
62-
return (OP##_s32)(a, b); \
62+
return ::OP##_s32(a, b); \
6363
} \
6464
}
6565

@@ -69,11 +69,11 @@
6969
{ \
7070
XSIMD_INLINE auto(x_##OP##_u64)(uint64x2_t a, uint64x2_t b) noexcept -> RT<uint64x2_t> \
7171
{ \
72-
return (OP##_u64)(a, b); \
72+
return ::OP##_u64(a, b); \
7373
} \
7474
XSIMD_INLINE auto(x_##OP##_s64)(int64x2_t a, int64x2_t b) noexcept -> RT<int64x2_t> \
7575
{ \
76-
return (OP##_s64)(a, b); \
76+
return ::OP##_s64(a, b); \
7777
} \
7878
}
7979

@@ -82,7 +82,7 @@
8282
{ \
8383
XSIMD_INLINE auto(x_##OP##_f32)(float32x4_t a, float32x4_t b) noexcept -> RT<float32x4_t> \
8484
{ \
85-
return (OP##_f32)(a, b); \
85+
return ::OP##_f32(a, b); \
8686
} \
8787
}
8888

@@ -91,27 +91,27 @@
9191
{ \
9292
XSIMD_INLINE auto(x_##OP##_u8)(uint8x16_t a) noexcept -> uint8x16_t \
9393
{ \
94-
return (OP##_u8)(a); \
94+
return ::OP##_u8(a); \
9595
} \
9696
XSIMD_INLINE auto(x_##OP##_s8)(int8x16_t a) noexcept -> int8x16_t \
9797
{ \
98-
return (OP##_s8)(a); \
98+
return ::OP##_s8(a); \
9999
} \
100100
XSIMD_INLINE auto(x_##OP##_u16)(uint16x8_t a) noexcept -> uint16x8_t \
101101
{ \
102-
return (OP##_u16)(a); \
102+
return ::OP##_u16(a); \
103103
} \
104104
XSIMD_INLINE auto(x_##OP##_s16)(int16x8_t a) noexcept -> int16x8_t \
105105
{ \
106-
return (OP##_s16)(a); \
106+
return ::OP##_s16(a); \
107107
} \
108108
XSIMD_INLINE auto(x_##OP##_u32)(uint32x4_t a) noexcept -> uint32x4_t \
109109
{ \
110-
return (OP##_u32)(a); \
110+
return ::OP##_u32(a); \
111111
} \
112112
XSIMD_INLINE auto(x_##OP##_s32)(int32x4_t a) noexcept -> int32x4_t \
113113
{ \
114-
return (OP##_s32)(a); \
114+
return ::OP##_s32(a); \
115115
} \
116116
}
117117

@@ -121,11 +121,11 @@
121121
{ \
122122
XSIMD_INLINE auto(x_##OP##_u64)(uint64x2_t a) noexcept -> uint64x2_t \
123123
{ \
124-
return (OP##_u64)(a); \
124+
return ::OP##_u64(a); \
125125
} \
126126
XSIMD_INLINE auto(x_##OP##_s64)(int64x2_t a) noexcept -> int64x2_t \
127127
{ \
128-
return (OP##_s64)(a); \
128+
return ::OP##_s64(a); \
129129
} \
130130
}
131131

@@ -134,7 +134,7 @@
134134
{ \
135135
XSIMD_INLINE auto(x_##OP##_f32)(float32x4_t a) noexcept -> float32x4_t \
136136
{ \
137-
return (OP##_f32)(a); \
137+
return ::OP##_f32(a); \
138138
} \
139139
}
140140

0 commit comments

Comments
 (0)