mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-01 23:24:06 +08:00
Fix Warray-bounds warning for fixed-size assignments
This commit is contained in:
parent
1d8b82b074
commit
151f6127df
@ -27,7 +27,7 @@ namespace internal {
|
|||||||
|
|
||||||
// copy_using_evaluator_traits is based on assign_traits
|
// copy_using_evaluator_traits is based on assign_traits
|
||||||
|
|
||||||
template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc, int MaxPacketSize = -1>
|
template <typename DstEvaluator, typename SrcEvaluator, typename AssignFunc, int MaxPacketSize = Dynamic>
|
||||||
struct copy_using_evaluator_traits {
|
struct copy_using_evaluator_traits {
|
||||||
using Src = typename SrcEvaluator::XprType;
|
using Src = typename SrcEvaluator::XprType;
|
||||||
using Dst = typename DstEvaluator::XprType;
|
using Dst = typename DstEvaluator::XprType;
|
||||||
@ -44,20 +44,23 @@ struct copy_using_evaluator_traits {
|
|||||||
static constexpr bool SrcIsRowMajor = bool(SrcFlags & RowMajorBit);
|
static constexpr bool SrcIsRowMajor = bool(SrcFlags & RowMajorBit);
|
||||||
static constexpr bool DstIsRowMajor = bool(DstFlags & RowMajorBit);
|
static constexpr bool DstIsRowMajor = bool(DstFlags & RowMajorBit);
|
||||||
static constexpr bool IsVectorAtCompileTime = Dst::IsVectorAtCompileTime;
|
static constexpr bool IsVectorAtCompileTime = Dst::IsVectorAtCompileTime;
|
||||||
static constexpr int RowsAtCompileTime = Dst::RowsAtCompileTime;
|
static constexpr int RowsAtCompileTime = size_prefer_fixed(Src::RowsAtCompileTime, Dst::RowsAtCompileTime);
|
||||||
static constexpr int ColsAtCompileTime = Dst::ColsAtCompileTime;
|
static constexpr int ColsAtCompileTime = size_prefer_fixed(Src::ColsAtCompileTime, Dst::ColsAtCompileTime);
|
||||||
static constexpr int SizeAtCompileTime = Dst::SizeAtCompileTime;
|
static constexpr int SizeAtCompileTime = size_at_compile_time(RowsAtCompileTime, ColsAtCompileTime);
|
||||||
static constexpr int MaxRowsAtCompileTime = Dst::MaxRowsAtCompileTime;
|
static constexpr int MaxRowsAtCompileTime =
|
||||||
static constexpr int MaxColsAtCompileTime = Dst::MaxColsAtCompileTime;
|
min_size_prefer_fixed(Src::MaxRowsAtCompileTime, Dst::MaxRowsAtCompileTime);
|
||||||
static constexpr int MaxSizeAtCompileTime = Dst::MaxSizeAtCompileTime;
|
static constexpr int MaxColsAtCompileTime =
|
||||||
|
min_size_prefer_fixed(Src::MaxColsAtCompileTime, Dst::MaxColsAtCompileTime);
|
||||||
|
static constexpr int MaxSizeAtCompileTime =
|
||||||
|
min_size_prefer_fixed(Src::MaxSizeAtCompileTime, Dst::MaxSizeAtCompileTime);
|
||||||
static constexpr int InnerSizeAtCompileTime = IsVectorAtCompileTime ? SizeAtCompileTime
|
static constexpr int InnerSizeAtCompileTime = IsVectorAtCompileTime ? SizeAtCompileTime
|
||||||
: DstIsRowMajor ? ColsAtCompileTime
|
: DstIsRowMajor ? ColsAtCompileTime
|
||||||
: RowsAtCompileTime;
|
: RowsAtCompileTime;
|
||||||
static constexpr int MaxInnerSizeAtCompileTime = IsVectorAtCompileTime ? MaxSizeAtCompileTime
|
static constexpr int MaxInnerSizeAtCompileTime = IsVectorAtCompileTime ? MaxSizeAtCompileTime
|
||||||
: DstIsRowMajor ? MaxColsAtCompileTime
|
: DstIsRowMajor ? MaxColsAtCompileTime
|
||||||
: MaxRowsAtCompileTime;
|
: MaxRowsAtCompileTime;
|
||||||
static constexpr int RestrictedInnerSize = min_size_prefer_fixed(InnerSizeAtCompileTime, MaxPacketSize);
|
static constexpr int RestrictedInnerSize = min_size_prefer_fixed(MaxInnerSizeAtCompileTime, MaxPacketSize);
|
||||||
static constexpr int RestrictedLinearSize = min_size_prefer_fixed(SizeAtCompileTime, MaxPacketSize);
|
static constexpr int RestrictedLinearSize = min_size_prefer_fixed(MaxSizeAtCompileTime, MaxPacketSize);
|
||||||
static constexpr int OuterStride = outer_stride_at_compile_time<Dst>::ret;
|
static constexpr int OuterStride = outer_stride_at_compile_time<Dst>::ret;
|
||||||
|
|
||||||
// TODO distinguish between linear traversal and inner-traversals
|
// TODO distinguish between linear traversal and inner-traversals
|
||||||
@ -78,17 +81,18 @@ struct copy_using_evaluator_traits {
|
|||||||
static constexpr bool MayInnerVectorize = MightVectorize && (InnerSizeAtCompileTime != Dynamic) &&
|
static constexpr bool MayInnerVectorize = MightVectorize && (InnerSizeAtCompileTime != Dynamic) &&
|
||||||
(InnerSizeAtCompileTime % InnerPacketSize == 0) &&
|
(InnerSizeAtCompileTime % InnerPacketSize == 0) &&
|
||||||
(OuterStride != Dynamic) && (OuterStride % InnerPacketSize == 0) &&
|
(OuterStride != Dynamic) && (OuterStride % InnerPacketSize == 0) &&
|
||||||
(EIGEN_UNALIGNED_VECTORIZE || JointAlignment >= InnerRequiredAlignment),
|
(EIGEN_UNALIGNED_VECTORIZE || JointAlignment >= InnerRequiredAlignment);
|
||||||
MayLinearize = StorageOrdersAgree && (DstFlags & SrcFlags & LinearAccessBit),
|
static constexpr bool MayLinearize = StorageOrdersAgree && (DstFlags & SrcFlags & LinearAccessBit);
|
||||||
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess &&
|
static constexpr bool MayLinearVectorize =
|
||||||
(EIGEN_UNALIGNED_VECTORIZE || (DstAlignment >= LinearRequiredAlignment) ||
|
MightVectorize && MayLinearize && DstHasDirectAccess &&
|
||||||
MaxSizeAtCompileTime == Dynamic);
|
(EIGEN_UNALIGNED_VECTORIZE || (DstAlignment >= LinearRequiredAlignment) || MaxSizeAtCompileTime == Dynamic) &&
|
||||||
|
(MaxSizeAtCompileTime == Dynamic || MaxSizeAtCompileTime >= LinearPacketSize);
|
||||||
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||||
so it's only good for large enough sizes. */
|
so it's only good for large enough sizes. */
|
||||||
|
static constexpr int InnerSizeThreshold = (EIGEN_UNALIGNED_VECTORIZE ? 1 : 3) * InnerPacketSize;
|
||||||
static constexpr bool MaySliceVectorize =
|
static constexpr bool MaySliceVectorize =
|
||||||
MightVectorize && DstHasDirectAccess &&
|
MightVectorize && DstHasDirectAccess &&
|
||||||
(MaxInnerSizeAtCompileTime == Dynamic ||
|
(MaxInnerSizeAtCompileTime == Dynamic || MaxInnerSizeAtCompileTime >= InnerSizeThreshold);
|
||||||
MaxInnerSizeAtCompileTime >= (EIGEN_UNALIGNED_VECTORIZE ? InnerPacketSize : (3 * InnerPacketSize)));
|
|
||||||
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||||
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||||
in a fixed-size matrix
|
in a fixed-size matrix
|
||||||
|
@ -697,6 +697,12 @@ inline constexpr int max_size_prefer_dynamic(A a, B b) {
|
|||||||
return plain_enum_max(a, b);
|
return plain_enum_max(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename A, typename B>
|
||||||
|
inline constexpr int size_prefer_fixed(A a, B b) {
|
||||||
|
plain_enum_asserts(a, b);
|
||||||
|
return int(a) == Dynamic ? int(b) : int(a);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
inline constexpr bool enum_eq_not_dynamic(A a, B b) {
|
inline constexpr bool enum_eq_not_dynamic(A a, B b) {
|
||||||
plain_enum_asserts(a, b);
|
plain_enum_asserts(a, b);
|
||||||
|
@ -251,6 +251,24 @@ struct vectorization_logic {
|
|||||||
(Matrix1::Flags & RowMajorBit) ? PacketSize : 2 > (1, 2), DefaultTraversal, CompleteUnrolling));
|
(Matrix1::Flags & RowMajorBit) ? PacketSize : 2 > (1, 2), DefaultTraversal, CompleteUnrolling));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the actual packet type used by the assignment evaluator is not necessarily PacketType for small fixed-size arrays
|
||||||
|
if (internal::unpacket_traits<typename internal::find_best_packet<Scalar, 2>::type>::size > 2) {
|
||||||
|
// the expression should not be vectorized if the size is too small
|
||||||
|
using Vector2 = Matrix<Scalar, 2, 1, ColMajor>;
|
||||||
|
using VectorMax3 = Matrix<Scalar, Dynamic, 1, ColMajor, 3, 1>;
|
||||||
|
VERIFY(test_assign(Vector2(), Vector2(), LinearTraversal, InnerUnrolling + CompleteUnrolling));
|
||||||
|
VERIFY(test_assign(VectorMax3(), Vector2(), LinearTraversal, InnerUnrolling + CompleteUnrolling));
|
||||||
|
VERIFY(test_assign(Vector2(), VectorMax3(), LinearTraversal, InnerUnrolling + CompleteUnrolling));
|
||||||
|
VERIFY(test_assign(VectorMax3(), VectorMax3(), LinearTraversal, NoUnrolling));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PacketSize > 1 && PacketSize < 8) {
|
||||||
|
// the size of the expression should be deduced at compile time by considering both the lhs and rhs
|
||||||
|
using Lhs = Matrix<Scalar, 7, Dynamic, ColMajor>;
|
||||||
|
using Rhs = Matrix<Scalar, Dynamic, 7, ColMajor>;
|
||||||
|
VERIFY(test_assign(Lhs(), Rhs(), -1, InnerUnrolling + CompleteUnrolling));
|
||||||
|
}
|
||||||
|
|
||||||
VERIFY(
|
VERIFY(
|
||||||
test_redux(Matrix44c().template block<2 * PacketSize, 1>(1, 2), LinearVectorizedTraversal, CompleteUnrolling));
|
test_redux(Matrix44c().template block<2 * PacketSize, 1>(1, 2), LinearVectorizedTraversal, CompleteUnrolling));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user