Suppress Warray-bounds warning in generic ploaduSegment, fix edge case for vectorized cast

This commit is contained in:
Charles Schlosser 2025-07-23 22:26:40 +00:00
parent abeba85356
commit 1e65707aa2
3 changed files with 26 additions and 7 deletions

View File

@ -707,7 +707,7 @@ struct unary_evaluator<CwiseUnaryOp<core_cast_op<SrcType, DstType>, 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<LoadMode, PacketType>(actualRow, actualCol, begin, count);
}
template <int LoadMode, typename PacketType = SrcPacketType>
@ -715,8 +715,8 @@ struct unary_evaluator<CwiseUnaryOp<core_cast_op<SrcType, DstType>, ArgType>, In
Index offset) const {
constexpr int PacketSize = unpacket_traits<PacketType>::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<LoadMode, PacketType>(actualIndex, begin, count);
}

View File

@ -1596,9 +1596,10 @@ EIGEN_DEVICE_FUNC inline Packet ploaduSegment(const typename unpacket_traits<Pac
using Scalar = typename unpacket_traits<Packet>::type;
constexpr Index PacketSize = unpacket_traits<Packet>::size;
eigen_assert((begin >= 0 && count >= 0 && begin + count <= PacketSize) && "invalid range");
Scalar aux[PacketSize];
memset(static_cast<void*>(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<Packet>(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<Scalar, Packet>(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.

View File

@ -142,6 +142,21 @@ struct packet_segment_test_driver<Scalar, 1> {
static void run() {}
};
template <bool Enable = internal::packet_traits<half>::Vectorizable>
void testReverseEdgeCase() {
// this reversed cast uses a non-zero offset for ploadSegment
Index size = 16 * internal::packet_traits<half>::size + 1;
VectorX<half> v1(size);
VectorX<float> v2(size), v3(size);
v1.setRandom();
v2 = v1.reverse().cast<float>();
v3 = v1.cast<float>().reverse();
VERIFY_IS_EQUAL(v2, v3);
}
template <>
void testReverseEdgeCase<false>() {}
template <typename Scalar>
void test_packet_segment() {
packet_segment_test_driver<Scalar, internal::packet_traits<Scalar>::size>::run();
@ -164,5 +179,6 @@ EIGEN_DECLARE_TEST(packet_segment) {
test_packet_segment<double>();
test_packet_segment<std::complex<float>>();
test_packet_segment<std::complex<double>>();
testReverseEdgeCase();
}
}