From 8115b45e503705d01fae5d4e1e23cc92c0dda87b Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen <4643818-rmlarsen1@users.noreply.gitlab.com> Date: Fri, 20 Mar 2026 17:27:02 -0700 Subject: [PATCH] Fix integer sanitizer issues in shifts and test ranges libeigen/eigen!2320 Co-authored-by: Rasmus Munk Larsen --- Eigen/src/Core/MathFunctions.h | 3 ++- test/numext.cpp | 18 +++++++++++++++--- test/product.h | 11 ++++++++++- test/redux.cpp | 7 ++++++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 54da17cc1..c428a58f3 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -1923,7 +1923,8 @@ EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE double fmod(const double& a, const double& template ::value>> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar logical_shift_left(const Scalar& a, int n) { - return a << n; + using UnsignedScalar = typename numext::get_integer_by_size::unsigned_type; + return bit_cast(bit_cast(a) << n); } template ::value>> diff --git a/test/numext.cpp b/test/numext.cpp index ebe9fb069..98ffdcc4f 100644 --- a/test/numext.cpp +++ b/test/numext.cpp @@ -44,6 +44,19 @@ void check_negate() { } } +template +std::enable_if_t::IsInteger, T> random_abs2_input() { + const T safeAbs2Input = static_cast(std::sqrt(static_cast(NumTraits::highest()))); + return NumTraits::IsSigned ? internal::random(-safeAbs2Input, safeAbs2Input) + : internal::random(T(0), safeAbs2Input); +} + +template +std::enable_if_t::IsInteger, T> random_abs2_input() { + typedef typename NumTraits::Real Real; + return internal::random() / Real(2); +} + template void check_abs() { typedef typename NumTraits::Real Real; @@ -54,8 +67,7 @@ void check_abs() { VERIFY_IS_EQUAL(numext::abs(T(1)), T(1)); for (int k = 0; k < 100; ++k) { - T x = internal::random(); - x = x / Real(2); + T x = random_abs2_input(); if (NumTraits::IsSigned) { VERIFY_IS_EQUAL(numext::abs(x), numext::abs(numext::negate(x))); VERIFY(numext::abs(numext::negate(x)) >= zero); @@ -301,7 +313,7 @@ void check_shift() { const T a = internal::random(); for (int s = 1; s < kNumBits; s++) { T a_bsll = numext::logical_shift_left(a, s); - T a_bsll_ref = a << s; + T a_bsll_ref = numext::bit_cast(numext::bit_cast(a) << s); VERIFY_IS_EQUAL(a_bsll, a_bsll_ref); T a_bsrl = numext::logical_shift_right(a, s); T a_bsrl_ref = numext::bit_cast(numext::bit_cast(a) >> s); diff --git a/test/product.h b/test/product.h index 00e67efe3..0449a5af7 100644 --- a/test/product.h +++ b/test/product.h @@ -81,15 +81,24 @@ void product(const MatrixType& m) { // Prevent overflows for integer types. if (Eigen::NumTraits::IsInteger) { - Scalar kMaxVal = Scalar(10000); + Scalar kMaxVal = Scalar(8); m1.array() = m1.array() - kMaxVal * (m1.array() / kMaxVal); m2.array() = m2.array() - kMaxVal * (m2.array() / kMaxVal); + square.array() = square.array() - kMaxVal * (square.array() / kMaxVal); + res.array() = res.array() - kMaxVal * (res.array() / kMaxVal); + square2.array() = square2.array() - kMaxVal * (square2.array() / kMaxVal); + res2.array() = res2.array() - kMaxVal * (res2.array() / kMaxVal); v1.array() = v1.array() - kMaxVal * (v1.array() / kMaxVal); + vc2.array() = vc2.array() - kMaxVal * (vc2.array() / kMaxVal); } OtherMajorMatrixType tm1 = m1; Scalar s1 = internal::random(); + if (Eigen::NumTraits::IsInteger) { + Scalar kMaxVal = Scalar(8); + s1 = s1 - kMaxVal * (s1 / kMaxVal); + } Index r = internal::random(0, rows - 1), c = internal::random(0, cols - 1), c2 = internal::random(0, cols - 1); diff --git a/test/redux.cpp b/test/redux.cpp index ad3ff1fe2..d0cefb064 100644 --- a/test/redux.cpp +++ b/test/redux.cpp @@ -32,7 +32,7 @@ void matrixRedux(const MatrixType& m) { m2.setRandom(); // Prevent overflows for integer types. if (Eigen::NumTraits::IsInteger) { - Scalar kMaxVal = Scalar(10000); + Scalar kMaxVal = Scalar(8); m1.array() = m1.array() - kMaxVal * (m1.array() / kMaxVal); m2.array() = m2.array() - kMaxVal * (m2.array() / kMaxVal); } @@ -98,6 +98,11 @@ void vectorRedux(const VectorType& w) { VectorType v = VectorType::Random(size); VectorType v_for_prod = VectorType::Ones(size) + Scalar(0.2) * v; // see comment above declaration of m1_for_prod + if (Eigen::NumTraits::IsInteger) { + Scalar kMaxVal = Scalar(8); + v.array() = v.array() - kMaxVal * (v.array() / kMaxVal); + v_for_prod = VectorType::Ones(size) + Scalar(0.2) * v; + } for (int i = 1; i < size; i++) { Scalar s(0), p(1);