ARMv8 NEON compile errors (using both Android NDK & Xcode)
Submitted by Michael Hofmann
Assigned to Konstantinos Margaritis
Link to original bugzilla bug (#907)
Version: 3.3 (current stable)
Operating system: Android
Description
When trying to compile a project using Eigen including NEON support on ARM64-v8a, I am encountering a whole bunch of compilation errors. These occur both when compiling with the Android NDK (for Android devices) as well as when compiling with Apple's Xcode (for iOS devices).
As I'm not sure how to fix these (several, seemingly unrelated?) errors, I can just list the partial compiler errors I have encountered so far:
When using Xcode 6.1 (Clang 3.5) / arm64-v8a:
In file included from ../External/src/Eigen/Eigen/Core:304:
../External/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:549:42: error: use of undeclared identifier 'vreinterpretq_u64_f64'; did you mean 'vreinterpretq_u64_s64'?
return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
^~~~~~~~~~~~~~~~~~~~~
vreinterpretq_u64_s64
In file included from ../External/src/Eigen/Eigen/Core:186:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include/arm_neon.h:28:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include/arm64_neon_internal.h:5176:17: note: 'vreinterpretq_u64_s64' declared here
__ai uint64x2_t vreinterpretq_u64_s64(int64x2_t __a) {
^
In file included from ../External/src/Eigen/Eigen/Core:304:
../External/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:549:67: error: use of undeclared identifier 'vreinterpretq_u64_f64'; did you mean 'vreinterpretq_u64_s64'?
return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
^~~~~~~~~~~~~~~~~~~~~
vreinterpretq_u64_s64
[……]
When using Android NDK r10c / arm64-v8a / GCC 4.9:
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h: In function 'Packet Eigen::internal::pand(const Packet&, const Packet&) [with Packet = __vector(2) __builtin_aarch64_simd_df]':
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:549:65: error: 'vreinterpretq_u64_f64' was not declared in this scope
return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
^
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:549:92: error: 'vreinterpretq_f64_u64' was not declared in this scope
return vreinterpretq_f64_u64(vandq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
^
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h: In function 'Packet Eigen::internal::por(const Packet&, const Packet&) [with Packet = __vector(2) __builtin_aarch64_simd_df]':
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:554:65: error: 'vreinterpretq_u64_f64' was not declared in this scope
return vreinterpretq_f64_u64(vorrq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
^
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:554:92: error: 'vreinterpretq_f64_u64' was not declared in this scope
return vreinterpretq_f64_u64(vorrq_u64(vreinterpretq_u64_f64(a),vreinterpretq_u64_f64(b)));
[……]
When using Android NDK r10c / arm64-v8a / Clang 3.5:
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:245:78: error: variable 'res' is uninitialized when used here [-Werror,-Wuninitialized]
res = extension ({ float32_t __s0 = from[0*stride]; float32x4_t __s1 = res; float32x4_t __ret; __ret = (float32x4_t) __builtin_neon_vsetq_lane_f32(__s0, (int8x16_t)__s1, 0); __ret; });
^~~
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:244:3: note: variable 'res' is declared here
Packet4f res;
^
[……]
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:600:71: error: cannot initialize return object of type 'double' with an rvalue of type 'float64x1_t' (vector of 1 'float64_t' value)
template<> inline double predux<Packet2d>(const Packet2d& a) { return vget_low_f64(a) + vget_high_f64(a); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../external/src/Eigen/Eigen/src/Core/arch/NEON/PacketMath.h:616:75: error: cannot initialize return object of type 'double' with an rvalue of type 'float64x1_t' (vector of 1 'float64_t' value)
template<> inline double predux_mul<Packet2d>(const Packet2d& a) { return vget_low_f64(a) * vget_high_f64(a); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[……]
Note that there is a difference when compiling using Clang vs. GCC in the Android NDK; the former does seem to have intrinsic declarations that neither the NDK GCC toolchain nor the Apple Clang toolchain seem to have. Indeed, when doing a grep on 'vreinterpretq_u64_f64' in the Android NDK file structure, I can see matches for Clang-only:
android-ndk-r10c $ find . -type f -name ".h" -exec grep -Hni "vreinterpretq_u64_f64" {} ;
./toolchains/llvm-3.4/prebuilt/darwin-x86_64/lib/clang/3.4/include/arm_neon.h:6721:__ai uint64x2_t vreinterpretq_u64_f64(float64x2_t __a) {
./toolchains/llvm-3.5/prebuilt/darwin-x86_64/lib/clang/3.5/include/arm_neon.h:35922:__ai uint64x2_t vreinterpretq_u64_f64(float64x2_t __p0) {
./toolchains/llvm-3.5/prebuilt/darwin-x86_64/lib/clang/3.5/include/arm_neon.h:35928:__ai uint64x2_t vreinterpretq_u64_f64(float64x2_t __p0) {
My version of Eigen is 722916e1 (default, 6 Nov 2014).