From 1e65707aa20603fc2ee9c2ac21c466ef57d23e10 Mon Sep 17 00:00:00 2001 From: Charles Schlosser Date: Wed, 23 Jul 2025 22:26:40 +0000 Subject: [PATCH] Suppress Warray-bounds warning in generic ploaduSegment, fix edge case for vectorized cast --- Eigen/src/Core/CoreEvaluators.h | 6 +++--- Eigen/src/Core/GenericPacketMath.h | 11 +++++++---- test/packet_segment.cpp | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 63f1895d2..ec731acd5 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -707,7 +707,7 @@ struct unary_evaluator, ArgType>, In Index packetOffset = offset * PacketSize; Index actualRow = IsRowMajor ? row : row + packetOffset; Index actualCol = IsRowMajor ? col + packetOffset : col; - eigen_assert(check_array_bounds(actualRow, actualCol, 0, count) && "Array index out of bounds"); + eigen_assert(check_array_bounds(actualRow, actualCol, begin, count) && "Array index out of bounds"); return m_argImpl.template packetSegment(actualRow, actualCol, begin, count); } template @@ -715,8 +715,8 @@ struct unary_evaluator, ArgType>, In Index offset) const { constexpr int PacketSize = unpacket_traits::size; Index packetOffset = offset * PacketSize; - Index actualIndex = index + packetOffset + begin; - eigen_assert(check_array_bounds(actualIndex, 0, count) && "Array index out of bounds"); + Index actualIndex = index + packetOffset; + eigen_assert(check_array_bounds(actualIndex, begin, count) && "Array index out of bounds"); return m_argImpl.template packetSegment(actualIndex, begin, count); } diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index e1d62fa17..de599a15c 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -1596,9 +1596,10 @@ EIGEN_DEVICE_FUNC inline Packet ploaduSegment(const typename unpacket_traits::type; constexpr Index PacketSize = unpacket_traits::size; eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) && "invalid range"); - Scalar aux[PacketSize]; - memset(static_cast(aux), 0x00, sizeof(Scalar) * PacketSize); - smart_copy(from + begin, from + begin + count, aux + begin); + Scalar aux[PacketSize] = {}; + for (Index k = begin; k < begin + count; k++) { + aux[k] = from[k]; + } return ploadu(aux); } @@ -1619,7 +1620,9 @@ EIGEN_DEVICE_FUNC inline void pstoreuSegment(Scalar* to, const Packet& from, Ind eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) && "invalid range"); Scalar aux[PacketSize]; pstoreu(aux, from); - smart_copy(aux + begin, aux + begin + count, to + begin); + for (Index k = begin; k < begin + count; k++) { + to[k] = aux[k]; + } } /** \internal copy the packet \a from in the range [begin, begin + count) to \a *to. diff --git a/test/packet_segment.cpp b/test/packet_segment.cpp index 6fa6a290d..8a5469cb4 100644 --- a/test/packet_segment.cpp +++ b/test/packet_segment.cpp @@ -142,6 +142,21 @@ struct packet_segment_test_driver { static void run() {} }; +template ::Vectorizable> +void testReverseEdgeCase() { + // this reversed cast uses a non-zero offset for ploadSegment + Index size = 16 * internal::packet_traits::size + 1; + VectorX v1(size); + VectorX v2(size), v3(size); + v1.setRandom(); + v2 = v1.reverse().cast(); + v3 = v1.cast().reverse(); + VERIFY_IS_EQUAL(v2, v3); +} + +template <> +void testReverseEdgeCase() {} + template void test_packet_segment() { packet_segment_test_driver::size>::run(); @@ -164,5 +179,6 @@ EIGEN_DECLARE_TEST(packet_segment) { test_packet_segment(); test_packet_segment>(); test_packet_segment>(); + testReverseEdgeCase(); } }