From 66b9f4ed5c4baac8de7b277f20a2259449ba86be Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 21 Nov 2023 16:09:12 +0000 Subject: [PATCH] Fix (u)int64_t->float conversion on arm --- Eigen/src/Core/arch/NEON/TypeCasting.h | 8 ++-- test/CMakeLists.txt | 1 + test/float_conversion.cpp | 51 ++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 test/float_conversion.cpp diff --git a/Eigen/src/Core/arch/NEON/TypeCasting.h b/Eigen/src/Core/arch/NEON/TypeCasting.h index a265e4d10..de29d5760 100644 --- a/Eigen/src/Core/arch/NEON/TypeCasting.h +++ b/Eigen/src/Core/arch/NEON/TypeCasting.h @@ -1111,11 +1111,11 @@ struct type_casting_traits { }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2l& a, const Packet2l& b) { - return vcvtq_f32_s32(vcombine_s32(vmovn_s64(a), vmovn_s64(b))); + return vcombine_f32(vcvt_f32_f64(vcvtq_f64_s64(a)), vcvt_f32_f64(vcvtq_f64_s64(b))); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet2l& a) { - return vcvt_f32_s32(vmovn_s64(a)); + return vcvt_f32_f64(vcvtq_f64_s64(a)); } @@ -1233,11 +1233,11 @@ struct type_casting_traits { }; template <> EIGEN_STRONG_INLINE Packet4f pcast(const Packet2ul& a, const Packet2ul& b) { - return vcvtq_f32_u32(vcombine_u32(vmovn_u64(a), vmovn_u64(b))); + return vcombine_f32(vcvt_f32_f64(vcvtq_f64_u64(a)), vcvt_f32_f64(vcvtq_f64_u64(b))); } template <> EIGEN_STRONG_INLINE Packet2f pcast(const Packet2ul& a) { - return vcvt_f32_u32(vmovn_u64(a)); + return vcvt_f32_f64(vcvtq_f64_u64(a)); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0614a20ae..fbbc98a7b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -182,6 +182,7 @@ ei_add_test(first_aligned) ei_add_test(type_alias) ei_add_test(nullary) ei_add_test(mixingtypes) +ei_add_test(float_conversion) ei_add_test(io) ei_add_test(packetmath "-DEIGEN_FAST_MATH=1") ei_add_test(vectorization_logic) diff --git a/test/float_conversion.cpp b/test/float_conversion.cpp new file mode 100644 index 000000000..fd8d45db5 --- /dev/null +++ b/test/float_conversion.cpp @@ -0,0 +1,51 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// This Source Code Form is subject to the terms of the Mozilla +// Public License v. 2.0. If a copy of the MPL was not distributed +// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "main.h" + +template +void test_conversion() { + typedef Array ArrayXFrom; + typedef Array ArrayXTo; + typedef Array ArrayXDouble; + + Index size = internal::random(1, EIGEN_TEST_MAX_SIZE); + double from_min = static_cast((std::numeric_limits::min)()); + double from_range = static_cast((std::numeric_limits::max)()) - from_min; + + // ArrayXFrom::Random() only generates 32-bit values (#2749), so we generate + // doubles and scale to fit the range. + ArrayXDouble doubles = (ArrayXDouble::Random(size)+1.0)*(from_range/2.0) + from_min; + ArrayXFrom from = doubles.template cast(); + ArrayXTo to(size); + for (Index i = 0; i < size; ++i) { + to(i) = static_cast(from(i)); + } + VERIFY_IS_APPROX(from.template cast(), to); +} + +template +void test_conversion_to() { + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); + CALL_SUBTEST((test_conversion())); +} + +EIGEN_DECLARE_TEST(float_conversion) +{ + for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST(test_conversion_to()); + CALL_SUBTEST(test_conversion_to()); + } +}