Update Eigen to commit:7fd305ecae2410714cde018cb6851f49138568c8

CHANGELOG
=========
7fd305eca - Fix GPU builds.
c8267654f - Don't use __builtin_alloca_with_align with nvc++
84c446df2 - Fix macro redefinition warning in FFTW test
a9584d8e3 - Fix clang6 failures.
dd4c2805d - Fix clang6 failures.
9e962d9c5 - Fix OOB access in triangular matrix multiplication.
695e49d1b - Fix NVCC builds for CUDA 10+.
dae09773f - Don't pass matrices by value.
c23ec3420 - Add tests for sizeof() with one dynamic dimension.
58b252e5b - Fix typo in PacketMath.h
6c04d0cd6 - Add missing exp2 definition for Altivec.
b15ebb1c2 - add nextafter for bfloat16
53b83cddf - Include <type_traits> in main.h for std::is_trivial*
37563856c - Fix stack allocation assert
3f067c485 - Add exp2() as a packet op and array method.
4e5136d23 - make fixed size matrices and arrays trivially_default_constructible

PiperOrigin-RevId: 693033345
Change-Id: I9316de3727feb01f71e21e186576a4fa1a14e06d
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index c808b63..2098749 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -117,16 +117,12 @@
    *
    * \sa resize(Index,Index)
    */
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Array() : Base() { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  // FIXME is it still needed ??
-  /** \internal */
-  EIGEN_DEVICE_FUNC Array(internal::constructor_without_unaligned_array_assert)
-      : Base(internal::constructor_without_unaligned_array_assert()){EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED}
+#ifdef EIGEN_INITIALIZE_COEFFS
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array() : Base() { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
+#else
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array() = default;
 #endif
-
-        EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array(Array && other) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array(Array&&) = default;
   EIGEN_DEVICE_FUNC Array& operator=(Array&& other) EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value) {
     Base::operator=(std::move(other));
     return *this;
@@ -230,7 +226,7 @@
   }
 
   /** Copy constructor */
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array(const Array& other) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Array(const Array&) = default;
 
  private:
   struct PrivateType {};
diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h
index 49c4099..90bc94e 100644
--- a/Eigen/src/Core/DenseStorage.h
+++ b/Eigen/src/Core/DenseStorage.h
@@ -27,15 +27,22 @@
 
 namespace internal {
 
-struct constructor_without_unaligned_array_assert {};
-
-template <typename T, int Size>
-EIGEN_DEVICE_FUNC constexpr void check_static_allocation_size() {
-// if EIGEN_STACK_ALLOCATION_LIMIT is defined to 0, then no limit
-#if EIGEN_STACK_ALLOCATION_LIMIT
-  EIGEN_STATIC_ASSERT(Size * sizeof(T) <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG);
+#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
+#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(Alignment)
+#else
+#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(Alignment)                                              \
+  eigen_assert((internal::is_constant_evaluated() || (std::uintptr_t(array) % Alignment == 0)) && \
+               "this assertion is explained here: "                                               \
+               "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html"       \
+               " **** READ THIS WEB PAGE !!! ****");
 #endif
-}
+
+#if EIGEN_STACK_ALLOCATION_LIMIT
+#define EIGEN_MAKE_STACK_ALLOCATION_ASSERT(X) \
+  EIGEN_STATIC_ASSERT(X <= EIGEN_STACK_ALLOCATION_LIMIT, OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG)
+#else
+#define EIGEN_MAKE_STACK_ALLOCATION_ASSERT(X)
+#endif
 
 /** \internal
  * Static array. If the MatrixOrArrayOptions require auto-alignment, the array will be automatically aligned:
@@ -44,112 +51,113 @@
 template <typename T, int Size, int MatrixOrArrayOptions,
           int Alignment = (MatrixOrArrayOptions & DontAlign) ? 0 : compute_default_alignment<T, Size>::value>
 struct plain_array {
-  T array[Size];
-
-  EIGEN_DEVICE_FUNC constexpr plain_array() { check_static_allocation_size<T, Size>(); }
-
-  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
-    check_static_allocation_size<T, Size>();
-  }
-};
-
-#if defined(EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT)
-#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
+  EIGEN_ALIGN_TO_BOUNDARY(Alignment) T array[Size];
+#if defined(EIGEN_NO_DEBUG) || defined(EIGEN_TESTING_PLAINOBJECT_CTOR)
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default;
 #else
-#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)                                                \
-  eigen_assert((internal::is_constant_evaluated() || (std::uintptr_t(array) & (sizemask)) == 0) && \
-               "this assertion is explained here: "                                                \
-               "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html"        \
-               " **** READ THIS WEB PAGE !!! ****");
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() {
+    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(Alignment)
+    EIGEN_MAKE_STACK_ALLOCATION_ASSERT(Size * sizeof(T))
+  }
 #endif
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 8> {
-  EIGEN_ALIGN_TO_BOUNDARY(8) T array[Size];
-
-  EIGEN_DEVICE_FUNC constexpr plain_array() {
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(7);
-    check_static_allocation_size<T, Size>();
-  }
-
-  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
-    check_static_allocation_size<T, Size>();
-  }
 };
 
 template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 16> {
-  EIGEN_ALIGN_TO_BOUNDARY(16) T array[Size];
-
-  EIGEN_DEVICE_FUNC constexpr plain_array() {
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(15);
-    check_static_allocation_size<T, Size>();
-  }
-
-  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
-    check_static_allocation_size<T, Size>();
-  }
-};
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 32> {
-  EIGEN_ALIGN_TO_BOUNDARY(32) T array[Size];
-
-  EIGEN_DEVICE_FUNC constexpr plain_array() {
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(31);
-    check_static_allocation_size<T, Size>();
-  }
-
-  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
-    check_static_allocation_size<T, Size>();
-  }
-};
-
-template <typename T, int Size, int MatrixOrArrayOptions>
-struct plain_array<T, Size, MatrixOrArrayOptions, 64> {
-  EIGEN_ALIGN_TO_BOUNDARY(64) T array[Size];
-
-  EIGEN_DEVICE_FUNC constexpr plain_array() {
-    EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(63);
-    check_static_allocation_size<T, Size>();
-  }
-
-  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {
-    check_static_allocation_size<T, Size>();
-  }
+struct plain_array<T, Size, MatrixOrArrayOptions, 0> {
+  T array[Size];
+#if defined(EIGEN_NO_DEBUG) || defined(EIGEN_TESTING_PLAINOBJECT_CTOR)
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default;
+#else
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() { EIGEN_MAKE_STACK_ALLOCATION_ASSERT(Size * sizeof(T)) }
+#endif
 };
 
 template <typename T, int MatrixOrArrayOptions, int Alignment>
 struct plain_array<T, 0, MatrixOrArrayOptions, Alignment> {
   T array[1];
-  EIGEN_DEVICE_FUNC constexpr plain_array() {}
-  EIGEN_DEVICE_FUNC constexpr plain_array(constructor_without_unaligned_array_assert) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr plain_array() = default;
 };
 
-struct plain_array_helper {
-  template <typename T, int Size, int MatrixOrArrayOptions, int Alignment>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static void copy(
-      const plain_array<T, Size, MatrixOrArrayOptions, Alignment>& src, const Eigen::Index size,
-      plain_array<T, Size, MatrixOrArrayOptions, Alignment>& dst) {
-    smart_copy(src.array, src.array + size, dst.array);
-  }
+// this class is intended to be inherited by DenseStorage to take advantage of empty base optimization
+template <int Rows, int Cols>
+struct DenseStorageIndices {
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices() = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(Index /*rows*/, Index /*cols*/) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index rows() const { return Rows; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index cols() const { return Cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index size() const { return Rows * Cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void set(Index /*rows*/, Index /*cols*/) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseStorageIndices& /*other*/) noexcept {}
+};
+template <int Rows>
+struct DenseStorageIndices<Rows, Dynamic> {
+  Index m_cols;
 
-  template <typename T, int Size, int MatrixOrArrayOptions, int Alignment>
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static void swap(plain_array<T, Size, MatrixOrArrayOptions, Alignment>& a,
-                                                         const Eigen::Index a_size,
-                                                         plain_array<T, Size, MatrixOrArrayOptions, Alignment>& b,
-                                                         const Eigen::Index b_size) {
-    if (a_size < b_size) {
-      std::swap_ranges(b.array, b.array + a_size, a.array);
-      smart_move(b.array + a_size, b.array + b_size, a.array + a_size);
-    } else if (a_size > b_size) {
-      std::swap_ranges(a.array, a.array + b_size, b.array);
-      smart_move(a.array + b_size, a.array + a_size, b.array + b_size);
-    } else {
-      std::swap_ranges(a.array, a.array + a_size, b.array);
-    }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices() : m_cols(0) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(Index /*rows*/, Index cols) : m_cols(cols) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index rows() const { return Rows; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index cols() const { return m_cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index size() const { return Rows * m_cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void set(Index /*rows*/, Index cols) { m_cols = cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseStorageIndices& other) noexcept {
+    numext::swap(m_cols, other.m_cols);
   }
 };
+template <int Cols>
+struct DenseStorageIndices<Dynamic, Cols> {
+  Index m_rows;
+
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices() : m_rows(0) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(Index rows, Index /*cols*/) : m_rows(rows) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index rows() const { return m_rows; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index cols() const { return Cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index size() const { return m_rows * Cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void set(Index rows, Index /*cols*/) { m_rows = rows; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseStorageIndices& other) noexcept {
+    numext::swap(m_rows, other.m_rows);
+  }
+};
+template <>
+struct DenseStorageIndices<Dynamic, Dynamic> {
+  Index m_rows;
+  Index m_cols;
+
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices() : m_rows(0), m_cols(0) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(const DenseStorageIndices&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices& operator=(DenseStorageIndices&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorageIndices(Index rows, Index cols)
+      : m_rows(rows), m_cols(cols) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index rows() const { return m_rows; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index cols() const { return m_cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index size() const { return m_rows * m_cols; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void set(Index rows, Index cols) {
+    m_rows = rows;
+    m_cols = cols;
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void swap(DenseStorageIndices& other) noexcept {
+    numext::swap(m_rows, other.m_rows);
+    numext::swap(m_cols, other.m_cols);
+  }
+};
+
+template <int Size, int Rows, int Cols>
+struct use_trivial_ctors {
+  static constexpr bool value = (Size >= 0) && (Rows >= 0) && (Cols >= 0) && (Size == Rows * Cols);
+};
 
 }  // end namespace internal
 
@@ -165,486 +173,202 @@
  *
  * \sa Matrix
  */
-template <typename T, int Size, int Rows_, int Cols_, int Options_>
+template <typename T, int Size, int Rows, int Cols, int Options,
+          bool Trivial = internal::use_trivial_ctors<Size, Rows, Cols>::value>
 class DenseStorage;
 
-// purely fixed-size matrix
-template <typename T, int Size, int Rows_, int Cols_, int Options_>
-class DenseStorage {
-  internal::plain_array<T, Size, Options_> m_data;
+// fixed-size storage with fixed dimensions
+template <typename T, int Size, int Rows, int Cols, int Options>
+class DenseStorage<T, Size, Rows, Cols, Options, true> : internal::DenseStorageIndices<Rows, Cols> {
+  using Base = internal::DenseStorageIndices<Rows, Cols>;
+
+  internal::plain_array<T, Size, Options> m_data;
 
  public:
-  constexpr EIGEN_DEVICE_FUNC DenseStorage(){EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(
-      Index size =
-          Size)} EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()) {}
-#if defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
-      : m_data(other.m_data){EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)}
+  using Base::cols;
+  using Base::rows;
+#ifndef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseStorage() = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(const DenseStorage&) = default;
 #else
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseStorage() { EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size) }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(const DenseStorage& other)
+      : Base(other), m_data(other.m_data) {
+    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = Size)
+  }
 #endif
-        EIGEN_DEVICE_FUNC constexpr DenseStorage
-        &
-        operator=(const DenseStorage&) = default;
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(DenseStorage&&) = default;
-  EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(DenseStorage&&) = default;
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols) {
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(DenseStorage&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(const DenseStorage&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(DenseStorage&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(Index size, Index rows, Index cols) : Base(rows, cols) {
     EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-    eigen_internal_assert(size == rows * cols && rows == Rows_ && cols == Cols_);
     EIGEN_UNUSED_VARIABLE(size);
-    EIGEN_UNUSED_VARIABLE(rows);
-    EIGEN_UNUSED_VARIABLE(cols);
   }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { numext::swap(m_data, other.m_data); }
-  EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; }
-  EIGEN_DEVICE_FUNC static constexpr Index cols(void) EIGEN_NOEXCEPT { return Cols_; }
-  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index, Index) {}
-  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index) {}
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
-};
-
-// null matrix
-template <typename T, int Rows_, int Cols_, int Options_>
-class DenseStorage<T, 0, Rows_, Cols_, Options_> {
- public:
-  static_assert(Rows_ * Cols_ == 0, "The fixed number of rows times columns must equal the storage size.");
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() {}
-  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) {}
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage&) {}
-  EIGEN_DEVICE_FUNC constexpr DenseStorage& operator=(const DenseStorage&) { return *this; }
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index, Index) {}
-  EIGEN_DEVICE_FUNC constexpr void swap(DenseStorage&) {}
-  EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; }
-  EIGEN_DEVICE_FUNC static constexpr Index cols(void) EIGEN_NOEXCEPT { return Cols_; }
-  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index, Index) {}
-  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index) {}
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return 0; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return 0; }
-};
-
-// more specializations for null matrices; these are necessary to resolve ambiguities
-template <typename T, int Options_>
-class DenseStorage<T, 0, Dynamic, Dynamic, Options_> {
-  Index m_rows;
-  Index m_cols;
-
- public:
-  EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0), m_cols(0) {}
-  EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : DenseStorage() {}
-  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_rows(other.m_rows), m_cols(other.m_cols) {}
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    m_rows = other.m_rows;
-    m_cols = other.m_cols;
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {
-    eigen_assert(m_rows * m_cols == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
-    numext::swap(m_rows, other.m_rows);
-    numext::swap(m_cols, other.m_cols);
-  }
-  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_rows; }
-  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_cols; }
-  EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index cols) {
-    m_rows = rows;
-    m_cols = cols;
-    eigen_assert(m_rows * m_cols == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index cols) {
-    m_rows = rows;
-    m_cols = cols;
-    eigen_assert(m_rows * m_cols == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
-};
-
-template <typename T, int Rows_, int Options_>
-class DenseStorage<T, 0, Rows_, Dynamic, Options_> {
-  Index m_cols;
-
- public:
-  EIGEN_DEVICE_FUNC DenseStorage() : m_cols(0) {}
-  EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : DenseStorage() {}
-  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_cols(other.m_cols) {}
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    m_cols = other.m_cols;
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {
-    eigen_assert(Rows_ * m_cols == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { numext::swap(m_cols, other.m_cols); }
-  EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index rows(void) EIGEN_NOEXCEPT { return Rows_; }
-  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols(void) const EIGEN_NOEXCEPT { return m_cols; }
-  EIGEN_DEVICE_FUNC void conservativeResize(Index, Index, Index cols) {
-    m_cols = cols;
-    eigen_assert(Rows_ * m_cols == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC void resize(Index, Index, Index cols) {
-    m_cols = cols;
-    eigen_assert(Rows_ * m_cols == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
-};
-
-template <typename T, int Cols_, int Options_>
-class DenseStorage<T, 0, Dynamic, Cols_, Options_> {
-  Index m_rows;
-
- public:
-  EIGEN_DEVICE_FUNC DenseStorage() : m_rows(0) {}
-  EIGEN_DEVICE_FUNC explicit DenseStorage(internal::constructor_without_unaligned_array_assert) : DenseStorage() {}
-  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other) : m_rows(other.m_rows) {}
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    m_rows = other.m_rows;
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(Index, Index rows, Index) : m_rows(rows) {
-    eigen_assert(m_rows * Cols_ == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) { numext::swap(m_rows, other.m_rows); }
-  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows(void) const EIGEN_NOEXCEPT { return m_rows; }
-  EIGEN_DEVICE_FUNC static EIGEN_CONSTEXPR Index cols(void) EIGEN_NOEXCEPT { return Cols_; }
-  EIGEN_DEVICE_FUNC void conservativeResize(Index, Index rows, Index) {
-    m_rows = rows;
-    eigen_assert(m_rows * Cols_ == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC void resize(Index, Index rows, Index) {
-    m_rows = rows;
-    eigen_assert(m_rows * Cols_ == 0 && "The number of rows times columns must equal the storage size.");
-  }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return nullptr; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return nullptr; }
-};
-
-// dynamic-size matrix with fixed-size storage
-template <typename T, int Size, int Options_>
-class DenseStorage<T, Size, Dynamic, Dynamic, Options_> {
-  internal::plain_array<T, Size, Options_> m_data;
-  Index m_rows;
-  Index m_cols;
-
- public:
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(), m_rows(0), m_cols(0) {}
-  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows), m_cols(other.m_cols) {
-    internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    if (this != &other) {
-      m_rows = other.m_rows;
-      m_cols = other.m_cols;
-      internal::plain_array_helper::copy(other.m_data, m_rows * m_cols, m_data);
-    }
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index rows, Index cols) : m_rows(rows), m_cols(cols) {}
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
-    internal::plain_array_helper::swap(m_data, m_rows * m_cols, other.m_data, other.m_rows * other.m_cols);
-    numext::swap(m_rows, other.m_rows);
-    numext::swap(m_cols, other.m_cols);
-  }
-  EIGEN_DEVICE_FUNC constexpr Index rows() const { return m_rows; }
-  EIGEN_DEVICE_FUNC constexpr Index cols() const { return m_cols; }
-  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index rows, Index cols) {
-    m_rows = rows;
-    m_cols = cols;
-  }
-  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index rows, Index cols) {
-    m_rows = rows;
-    m_cols = cols;
-  }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
-};
-
-// dynamic-size matrix with fixed-size storage and fixed width
-template <typename T, int Size, int Cols_, int Options_>
-class DenseStorage<T, Size, Dynamic, Cols_, Options_> {
-  internal::plain_array<T, Size, Options_> m_data;
-  Index m_rows;
-
- public:
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_rows(0) {}
-  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_rows(other.m_rows) {
-    internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
-  }
-
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    if (this != &other) {
-      m_rows = other.m_rows;
-      internal::plain_array_helper::copy(other.m_data, m_rows * Cols_, m_data);
-    }
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index, Index rows, Index) : m_rows(rows) {}
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
-    internal::plain_array_helper::swap(m_data, m_rows * Cols_, other.m_data, other.m_rows * Cols_);
-    numext::swap(m_rows, other.m_rows);
-  }
-  EIGEN_DEVICE_FUNC constexpr Index rows(void) const EIGEN_NOEXCEPT { return m_rows; }
-  EIGEN_DEVICE_FUNC constexpr Index cols(void) const EIGEN_NOEXCEPT { return Cols_; }
-  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index rows, Index) { m_rows = rows; }
-  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index rows, Index) { m_rows = rows; }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
-};
-
-// dynamic-size matrix with fixed-size storage and fixed height
-template <typename T, int Size, int Rows_, int Options_>
-class DenseStorage<T, Size, Rows_, Dynamic, Options_> {
-  internal::plain_array<T, Size, Options_> m_data;
-  Index m_cols;
-
- public:
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_cols(0) {}
-  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(const DenseStorage& other)
-      : m_data(internal::constructor_without_unaligned_array_assert()), m_cols(other.m_cols) {
-    internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    if (this != &other) {
-      m_cols = other.m_cols;
-      internal::plain_array_helper::copy(other.m_data, Rows_ * m_cols, m_data);
-    }
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(Index, Index, Index cols) : m_cols(cols) {}
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
-    internal::plain_array_helper::swap(m_data, Rows_ * m_cols, other.m_data, Rows_ * other.m_cols);
-    numext::swap(m_cols, other.m_cols);
-  }
-  EIGEN_DEVICE_FUNC constexpr Index rows(void) const EIGEN_NOEXCEPT { return Rows_; }
-  EIGEN_DEVICE_FUNC constexpr Index cols(void) const EIGEN_NOEXCEPT { return m_cols; }
-  EIGEN_DEVICE_FUNC constexpr void conservativeResize(Index, Index, Index cols) { m_cols = cols; }
-  EIGEN_DEVICE_FUNC constexpr void resize(Index, Index, Index cols) { m_cols = cols; }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data.array; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data.array; }
-};
-
-// purely dynamic matrix.
-template <typename T, int Options_>
-class DenseStorage<T, Dynamic, Dynamic, Dynamic, Options_> {
-  T* m_data;
-  Index m_rows;
-  Index m_cols;
-
- public:
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
-  EIGEN_DEVICE_FUNC explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(0), m_rows(0), m_cols(0) {}
-  EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
-      : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)),
-        m_rows(rows),
-        m_cols(cols) {
-    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-    eigen_internal_assert(size == rows * cols && rows >= 0 && cols >= 0);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
-      : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(other.m_rows * other.m_cols)),
-        m_rows(other.m_rows),
-        m_cols(other.m_cols) {
-    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows * m_cols)
-    internal::smart_copy(other.m_data, other.m_data + other.m_rows * other.m_cols, m_data);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    if (this != &other) {
-      DenseStorage tmp(other);
-      this->swap(tmp);
-    }
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT : m_data(std::move(other.m_data)),
-                                                                        m_rows(std::move(other.m_rows)),
-                                                                        m_cols(std::move(other.m_cols)) {
-    other.m_data = nullptr;
-    other.m_rows = 0;
-    other.m_cols = 0;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT {
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage& other) {
     numext::swap(m_data, other.m_data);
-    numext::swap(m_rows, other.m_rows);
-    numext::swap(m_cols, other.m_cols);
+    Base::swap(other);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index /*size*/, Index rows, Index cols) {
+    Base::set(rows, cols);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index /*size*/, Index rows, Index cols) {
+    Base::set(rows, cols);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr T* data() { return m_data.array; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const T* data() const { return m_data.array; }
+};
+// fixed-size storage with dynamic dimensions
+template <typename T, int Size, int Rows, int Cols, int Options>
+class DenseStorage<T, Size, Rows, Cols, Options, false> : internal::DenseStorageIndices<Rows, Cols> {
+  using Base = internal::DenseStorageIndices<Rows, Cols>;
+
+  internal::plain_array<T, Size, Options> m_data;
+
+ public:
+  using Base::cols;
+  using Base::rows;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DenseStorage() = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(const DenseStorage& other) : Base(other), m_data() {
+    Index size = other.size();
+    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+    internal::smart_copy(other.m_data.array, other.m_data.array + size, m_data.array);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(DenseStorage&& other) : Base(other), m_data() {
+    Index size = other.size();
+    internal::smart_move(other.m_data.array, other.m_data.array + size, m_data.array);
+    other.resize(Size, 0, 0);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(const DenseStorage& other) {
+    Base::set(other.rows(), other.cols());
+    Index size = other.size();
+    internal::smart_copy(other.m_data.array, other.m_data.array + size, m_data.array);
     return *this;
   }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(DenseStorage&& other) {
+    Base::set(other.rows(), other.cols());
+    Index size = other.size();
+    internal::smart_move(other.m_data.array, other.m_data.array + size, m_data.array);
+    other.resize(Size, 0, 0);
+    return *this;
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(Index size, Index rows, Index cols) : Base(rows, cols) {
+    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+    EIGEN_UNUSED_VARIABLE(size);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage& other) {
+    Index thisSize = this->size();
+    Index otherSize = other.size();
+    Index commonSize = numext::mini(thisSize, otherSize);
+    std::swap_ranges(m_data.array, m_data.array + commonSize, other.m_data.array);
+    if (thisSize > otherSize)
+      internal::smart_move(m_data.array + commonSize, m_data.array + thisSize, other.m_data.array + commonSize);
+    else if (otherSize > thisSize)
+      internal::smart_move(other.m_data.array + commonSize, other.m_data.array + otherSize, m_data.array + commonSize);
+    Base::swap(other);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index /*size*/, Index rows, Index cols) {
+    Base::set(rows, cols);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index /*size*/, Index rows, Index cols) {
+    Base::set(rows, cols);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr T* data() { return m_data.array; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const T* data() const { return m_data.array; }
+};
+// null matrix specialization
+template <typename T, int Rows, int Cols, int Options>
+class DenseStorage<T, 0, Rows, Cols, Options, true> : internal::DenseStorageIndices<Rows, Cols> {
+  using Base = internal::DenseStorageIndices<Rows, Cols>;
+
+ public:
+  using Base::cols;
+  using Base::rows;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage() = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(const DenseStorage&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(DenseStorage&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(const DenseStorage&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(DenseStorage&&) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(Index /*size*/, Index rows, Index cols)
+      : Base(rows, cols) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage& other) noexcept { Base::swap(other); }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index /*size*/, Index rows, Index cols) {
+    Base::set(rows, cols);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index /*size*/, Index rows, Index cols) {
+    Base::set(rows, cols);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr T* data() { return nullptr; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const T* data() const { return nullptr; }
+};
+// dynamic matrix specialization
+template <typename T, int Rows, int Cols, int Options>
+class DenseStorage<T, Dynamic, Rows, Cols, Options, false> : internal::DenseStorageIndices<Rows, Cols> {
+  using Base = internal::DenseStorageIndices<Rows, Cols>;
+  static constexpr int Size = Dynamic;
+  static constexpr bool Align = (Options & DontAlign) == 0;
+
+  T* m_data;
+
+ public:
+  using Base::cols;
+  using Base::rows;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage() : m_data(nullptr) {}
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(const DenseStorage& other)
+      : Base(other), m_data(internal::conditional_aligned_new_auto<T, Align>(other.size())) {
+    Index size = other.size();
+    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+    internal::smart_copy(other.m_data, other.m_data + size, m_data);
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(DenseStorage&& other) noexcept
+      : Base(other), m_data(other.m_data) {
+    other.set(0, 0);
+    other.m_data = nullptr;
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(const DenseStorage& other) {
+    Base::set(other.rows(), other.cols());
+    Index size = other.size();
+    m_data = internal::conditional_aligned_new_auto<T, Align>(size);
+    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+    internal::smart_copy(other.m_data, other.m_data + size, m_data);
+    return *this;
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage& operator=(DenseStorage&& other) noexcept {
+    this->swap(other);
+    return *this;
+  }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr DenseStorage(Index size, Index rows, Index cols)
+      : Base(rows, cols), m_data(internal::conditional_aligned_new_auto<T, Align>(size)) {
+    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+  }
   EIGEN_DEVICE_FUNC ~DenseStorage() {
-    internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, m_rows * m_cols);
+    Index size = this->size();
+    internal::conditional_aligned_delete_auto<T, Align>(m_data, size);
   }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void swap(DenseStorage& other) noexcept {
     numext::swap(m_data, other.m_data);
-    numext::swap(m_rows, other.m_rows);
-    numext::swap(m_cols, other.m_cols);
+    Base::swap(other);
   }
-  EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT { return m_rows; }
-  EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT { return m_cols; }
-  void conservativeResize(Index size, Index rows, Index cols) {
-    m_data =
-        internal::conditional_aligned_realloc_new_auto<T, (Options_ & DontAlign) == 0>(m_data, size, m_rows * m_cols);
-    m_rows = rows;
-    m_cols = cols;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void conservativeResize(Index size, Index rows, Index cols) {
+    Index oldSize = this->size();
+    m_data = internal::conditional_aligned_realloc_new_auto<T, Align>(m_data, size, oldSize);
+    Base::set(rows, cols);
   }
-  EIGEN_DEVICE_FUNC void resize(Index size, Index rows, Index cols) {
-    if (size != m_rows * m_cols) {
-      internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, m_rows * m_cols);
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr void resize(Index size, Index rows, Index cols) {
+    Index oldSize = this->size();
+    if (size != oldSize) {
+      internal::conditional_aligned_delete_auto<T, Align>(m_data, oldSize);
       if (size > 0)  // >0 and not simply !=0 to let the compiler knows that size cannot be negative
-        m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size);
-      else
-        m_data = 0;
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+      {
+        m_data = internal::conditional_aligned_new_auto<T, Align>(size);
+        EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
+      } else
+        m_data = nullptr;
     }
-    m_rows = rows;
-    m_cols = cols;
+    Base::set(rows, cols);
   }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr T* data() { return m_data; }
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr const T* data() const { return m_data; }
 };
-
-// matrix with dynamic width and fixed height (so that matrix has dynamic size).
-template <typename T, int Rows_, int Options_>
-class DenseStorage<T, Dynamic, Rows_, Dynamic, Options_> {
-  T* m_data;
-  Index m_cols;
-
- public:
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_cols(0) {}
-  explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
-  EIGEN_DEVICE_FUNC DenseStorage(Index size, Index rows, Index cols)
-      : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)), m_cols(cols) {
-    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-    eigen_internal_assert(size == rows * cols && rows == Rows_ && cols >= 0);
-    EIGEN_UNUSED_VARIABLE(rows);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
-      : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(Rows_ * other.m_cols)),
-        m_cols(other.m_cols) {
-    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_cols * Rows_)
-    internal::smart_copy(other.m_data, other.m_data + Rows_ * m_cols, m_data);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    if (this != &other) {
-      DenseStorage tmp(other);
-      this->swap(tmp);
-    }
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT : m_data(std::move(other.m_data)),
-                                                                        m_cols(std::move(other.m_cols)) {
-    other.m_data = nullptr;
-    other.m_cols = 0;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT {
-    numext::swap(m_data, other.m_data);
-    numext::swap(m_cols, other.m_cols);
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC ~DenseStorage() {
-    internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, Rows_ * m_cols);
-  }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
-    numext::swap(m_data, other.m_data);
-    numext::swap(m_cols, other.m_cols);
-  }
-  EIGEN_DEVICE_FUNC static constexpr Index rows(void) EIGEN_NOEXCEPT { return Rows_; }
-  EIGEN_DEVICE_FUNC Index cols(void) const EIGEN_NOEXCEPT { return m_cols; }
-  EIGEN_DEVICE_FUNC void conservativeResize(Index size, Index, Index cols) {
-    m_data =
-        internal::conditional_aligned_realloc_new_auto<T, (Options_ & DontAlign) == 0>(m_data, size, Rows_ * m_cols);
-    m_cols = cols;
-  }
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index, Index cols) {
-    if (size != Rows_ * m_cols) {
-      internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, Rows_ * m_cols);
-      if (size > 0)  // >0 and not simply !=0 to let the compiler knows that size cannot be negative
-        m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size);
-      else
-        m_data = 0;
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-    }
-    m_cols = cols;
-  }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data; }
-};
-
-// matrix with dynamic height and fixed width (so that matrix has dynamic size).
-template <typename T, int Cols_, int Options_>
-class DenseStorage<T, Dynamic, Dynamic, Cols_, Options_> {
-  T* m_data;
-  Index m_rows;
-
- public:
-  EIGEN_DEVICE_FUNC constexpr DenseStorage() : m_data(0), m_rows(0) {}
-  explicit constexpr DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
-  EIGEN_DEVICE_FUNC constexpr DenseStorage(Index size, Index rows, Index cols)
-      : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)), m_rows(rows) {
-    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-    eigen_internal_assert(size == rows * cols && rows >= 0 && cols == Cols_);
-    EIGEN_UNUSED_VARIABLE(cols);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(const DenseStorage& other)
-      : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(other.m_rows * Cols_)),
-        m_rows(other.m_rows) {
-    EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN(Index size = m_rows * Cols_)
-    internal::smart_copy(other.m_data, other.m_data + other.m_rows * Cols_, m_data);
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(const DenseStorage& other) {
-    if (this != &other) {
-      DenseStorage tmp(other);
-      this->swap(tmp);
-    }
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage(DenseStorage&& other) EIGEN_NOEXCEPT : m_data(std::move(other.m_data)),
-                                                                        m_rows(std::move(other.m_rows)) {
-    other.m_data = nullptr;
-    other.m_rows = 0;
-  }
-  EIGEN_DEVICE_FUNC DenseStorage& operator=(DenseStorage&& other) EIGEN_NOEXCEPT {
-    numext::swap(m_data, other.m_data);
-    numext::swap(m_rows, other.m_rows);
-    return *this;
-  }
-  EIGEN_DEVICE_FUNC ~DenseStorage() {
-    internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, Cols_ * m_rows);
-  }
-  EIGEN_DEVICE_FUNC void swap(DenseStorage& other) {
-    numext::swap(m_data, other.m_data);
-    numext::swap(m_rows, other.m_rows);
-  }
-  EIGEN_DEVICE_FUNC Index rows(void) const EIGEN_NOEXCEPT { return m_rows; }
-  EIGEN_DEVICE_FUNC static constexpr Index cols(void) { return Cols_; }
-  void conservativeResize(Index size, Index rows, Index) {
-    m_data =
-        internal::conditional_aligned_realloc_new_auto<T, (Options_ & DontAlign) == 0>(m_data, size, m_rows * Cols_);
-    m_rows = rows;
-  }
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index size, Index rows, Index) {
-    if (size != m_rows * Cols_) {
-      internal::conditional_aligned_delete_auto<T, (Options_ & DontAlign) == 0>(m_data, Cols_ * m_rows);
-      if (size > 0)  // >0 and not simply !=0 to let the compiler knows that size cannot be negative
-        m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size);
-      else
-        m_data = 0;
-      EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN({})
-    }
-    m_rows = rows;
-  }
-  EIGEN_DEVICE_FUNC constexpr const T* data() const { return m_data; }
-  EIGEN_DEVICE_FUNC constexpr T* data() { return m_data; }
-};
-
 }  // end namespace Eigen
 
 #endif  // EIGEN_MATRIX_H
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h
index dc12481..e4c51d2 100644
--- a/Eigen/src/Core/GeneralProduct.h
+++ b/Eigen/src/Core/GeneralProduct.h
@@ -327,6 +327,7 @@
 
       if (!evalToDest) {
 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+        constexpr int Size = Dest::SizeAtCompileTime;
         Index size = dest.size();
         EIGEN_DENSE_STORAGE_CTOR_PLUGIN
 #endif
@@ -391,6 +392,7 @@
 
     if (!DirectlyUseRhs) {
 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+      constexpr int Size = ActualRhsTypeCleaned::SizeAtCompileTime;
       Index size = actualRhs.size();
       EIGEN_DENSE_STORAGE_CTOR_PLUGIN
 #endif
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h
index 1d79b4a..c7a9846 100644
--- a/Eigen/src/Core/GenericPacketMath.h
+++ b/Eigen/src/Core/GenericPacketMath.h
@@ -1083,8 +1083,13 @@
 /** \internal \returns the exp of \a a (coeff-wise) */
 template <typename Packet>
 EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp(const Packet& a) {
-  EIGEN_USING_STD(exp);
-  return exp(a);
+  return numext::exp(a);
+}
+
+/** \internal \returns the exp2 of \a a (coeff-wise) */
+template <typename Packet>
+EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp2(const Packet& a) {
+  return numext::exp2(a);
 }
 
 /** \internal \returns the expm1 of \a a (coeff-wise) */
@@ -1113,7 +1118,7 @@
   return log10(a);
 }
 
-/** \internal \returns the log10 of \a a (coeff-wise) */
+/** \internal \returns the log2 of \a a (coeff-wise) */
 template <typename Packet>
 EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog2(const Packet& a) {
   using Scalar = typename internal::unpacket_traits<Packet>::type;
diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h
index 3f147b8..df1098e 100644
--- a/Eigen/src/Core/GlobalFunctions.h
+++ b/Eigen/src/Core/GlobalFunctions.h
@@ -76,6 +76,7 @@
 EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(erfc, scalar_erfc_op, complement error function,\sa ArrayBase::erfc)
 EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ndtri, scalar_ndtri_op, inverse normal distribution function,\sa ArrayBase::ndtri)
 EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp, scalar_exp_op, exponential,\sa ArrayBase::exp)
+EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp2, scalar_exp2_op, exponential,\sa ArrayBase::exp2)
 EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(expm1, scalar_expm1_op, exponential of a value minus 1,\sa ArrayBase::expm1)
 EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log, scalar_log_op, natural logarithm,\sa Eigen::log10 DOXCOMMA ArrayBase::log)
 EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log1p, scalar_log1p_op, natural logarithm of 1 plus the value,\sa ArrayBase::log1p)
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index feb9099..57fb3bd 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -1477,6 +1477,63 @@
 }
 #endif
 
+template <typename T>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T exp2(const T& x) {
+  EIGEN_USING_STD(exp2);
+  return exp2(x);
+}
+
+// MSVC screws up some edge-cases for std::exp2(complex).
+#ifdef EIGEN_COMP_MSVC
+template <typename RealScalar>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::complex<RealScalar> exp2(const std::complex<RealScalar>& x) {
+  EIGEN_USING_STD(exp);
+  // If z is (x,±∞) (for any finite x), the result is (NaN,NaN) and FE_INVALID is raised.
+  // If z is (x,NaN) (for any finite x), the result is (NaN,NaN) and FE_INVALID may be raised.
+  if ((isfinite)(real_ref(x)) && !(isfinite)(imag_ref(x))) {
+    return std::complex<RealScalar>(NumTraits<RealScalar>::quiet_NaN(), NumTraits<RealScalar>::quiet_NaN());
+  }
+  // If z is (+∞,±∞), the result is (±∞,NaN) and FE_INVALID is raised (the sign of the real part is unspecified)
+  // If z is (+∞,NaN), the result is (±∞,NaN) (the sign of the real part is unspecified)
+  if ((real_ref(x) == NumTraits<RealScalar>::infinity() && !(isfinite)(imag_ref(x)))) {
+    return std::complex<RealScalar>(NumTraits<RealScalar>::infinity(), NumTraits<RealScalar>::quiet_NaN());
+  }
+  return exp2(x);
+}
+#endif
+
+#if defined(SYCL_DEVICE_ONLY)
+SYCL_SPECIALIZE_FLOATING_TYPES_UNARY(exp2, exp2)
+#endif
+
+#if defined(EIGEN_GPUCC)
+template <>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float exp2(const float& x) {
+  return ::exp2f(x);
+}
+
+template <>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE double exp2(const double& x) {
+  return ::exp2(x);
+}
+
+template <>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::complex<float> exp2(const std::complex<float>& x) {
+  float com = ::exp2f(x.real());
+  float res_real = com * ::cosf(static_cast<float>(EIGEN_LN2) * x.imag());
+  float res_imag = com * ::sinf(static_cast<float>(EIGEN_LN2) * x.imag());
+  return std::complex<float>(res_real, res_imag);
+}
+
+template <>
+EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::complex<double> exp2(const std::complex<double>& x) {
+  double com = ::exp2(x.real());
+  double res_real = com * ::cos(static_cast<double>(EIGEN_LN2) * x.imag());
+  double res_imag = com * ::sin(static_cast<double>(EIGEN_LN2) * x.imag());
+  return std::complex<double>(res_real, res_imag);
+}
+#endif
+
 template <typename Scalar>
 EIGEN_DEVICE_FUNC inline EIGEN_MATHFUNC_RETVAL(expm1, Scalar) expm1(const Scalar& x) {
   return EIGEN_MATHFUNC_IMPL(expm1, Scalar)::run(x);
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 2c64936..8b7f70c 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -250,15 +250,12 @@
    *
    * \sa resize(Index,Index)
    */
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix()
-      : Base(){EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED}
-
-        // FIXME is it still needed
-        EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr explicit Matrix(
-            internal::constructor_without_unaligned_array_assert)
-      : Base(internal::constructor_without_unaligned_array_assert()){EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED}
-
-        EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix(Matrix && other) = default;
+#if defined(EIGEN_INITIALIZE_COEFFS)
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix() { EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
+#else
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix() = default;
+#endif
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix(Matrix&&) = default;
   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix& operator=(Matrix&& other)
       EIGEN_NOEXCEPT_IF(std::is_nothrow_move_assignable<Scalar>::value) {
     Base::operator=(std::move(other));
@@ -377,7 +374,7 @@
   }
 
   /** \brief Copy constructor */
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix(const Matrix& other) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Matrix(const Matrix&) = default;
 
   /** \brief Copy constructor for generic expressions.
    * \sa MatrixBase::operator=(const EigenBase<OtherDerived>&)
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index 62195f4..8720c44 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -472,32 +472,17 @@
   // Prevent user from trying to instantiate PlainObjectBase objects
   // by making all its constructor protected. See bug 1074.
  protected:
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr PlainObjectBase() : m_storage() {
-    //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-  }
-
-#ifndef EIGEN_PARSED_BY_DOXYGEN
-  // FIXME is it still needed ?
-  /** \internal */
-  EIGEN_DEVICE_FUNC constexpr explicit PlainObjectBase(internal::constructor_without_unaligned_array_assert)
-      : m_storage(internal::constructor_without_unaligned_array_assert()) {
-    // EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-  }
-#endif
-
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr PlainObjectBase(PlainObjectBase&& other) = default;
-
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr PlainObjectBase() = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr PlainObjectBase(PlainObjectBase&&) = default;
   EIGEN_DEVICE_FUNC constexpr PlainObjectBase& operator=(PlainObjectBase&& other) EIGEN_NOEXCEPT {
     m_storage = std::move(other.m_storage);
     return *this;
   }
 
   /** Copy constructor */
-  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr PlainObjectBase(const PlainObjectBase& other) = default;
+  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr PlainObjectBase(const PlainObjectBase&) = default;
   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE PlainObjectBase(Index size, Index rows, Index cols)
-      : m_storage(size, rows, cols) {
-    //       EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED
-  }
+      : m_storage(size, rows, cols) {}
 
   /** \brief Construct a row of column vector with fixed size from an arbitrary number of coefficients.
    *
diff --git a/Eigen/src/Core/RandomImpl.h b/Eigen/src/Core/RandomImpl.h
index e82da96..76e43f5 100644
--- a/Eigen/src/Core/RandomImpl.h
+++ b/Eigen/src/Core/RandomImpl.h
@@ -115,6 +115,7 @@
   }
 };
 
+#if !EIGEN_COMP_NVCC
 // random implementation for long double
 // this specialization is not compatible with double-double scalars
 template <bool Specialize = (sizeof(long double) == 2 * sizeof(uint64_t)) &&
@@ -146,6 +147,7 @@
 };
 template <>
 struct random_float_impl<long double> : random_longdouble_impl<> {};
+#endif
 
 template <typename Scalar>
 struct random_default_impl<Scalar, false, false> {
diff --git a/Eigen/src/Core/arch/AVX/MathFunctions.h b/Eigen/src/Core/arch/AVX/MathFunctions.h
index 7b43fbb..a5c38e7 100644
--- a/Eigen/src/Core/arch/AVX/MathFunctions.h
+++ b/Eigen/src/Core/arch/AVX/MathFunctions.h
@@ -32,11 +32,8 @@
 EIGEN_DOUBLE_PACKET_FUNCTION(sin, Packet4d)
 EIGEN_DOUBLE_PACKET_FUNCTION(cos, Packet4d)
 #endif
-
-template <>
-EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED Packet4d patan<Packet4d>(const Packet4d& _x) {
-  return generic_patan(_x);
-}
+EIGEN_GENERIC_PACKET_FUNCTION(atan, Packet4d)
+EIGEN_GENERIC_PACKET_FUNCTION(exp2, Packet4d)
 
 // Notice that for newer processors, it is counterproductive to use Newton
 // iteration for square root. In particular, Skylake and Zen2 processors
@@ -99,6 +96,7 @@
 
 BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pcos)
 BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pexp)
+BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pexp2)
 BF16_PACKET_FUNCTION(Packet8f, Packet8bf, pexpm1)
 BF16_PACKET_FUNCTION(Packet8f, Packet8bf, plog)
 BF16_PACKET_FUNCTION(Packet8f, Packet8bf, plog1p)
@@ -110,6 +108,7 @@
 BF16_PACKET_FUNCTION(Packet8f, Packet8bf, ptanh)
 F16_PACKET_FUNCTION(Packet8f, Packet8h, pcos)
 F16_PACKET_FUNCTION(Packet8f, Packet8h, pexp)
+F16_PACKET_FUNCTION(Packet8f, Packet8h, pexp2)
 F16_PACKET_FUNCTION(Packet8f, Packet8h, pexpm1)
 F16_PACKET_FUNCTION(Packet8f, Packet8h, plog)
 F16_PACKET_FUNCTION(Packet8f, Packet8h, plog1p)
diff --git a/Eigen/src/Core/arch/AVX512/MathFunctions.h b/Eigen/src/Core/arch/AVX512/MathFunctions.h
index 0677248..6039254 100644
--- a/Eigen/src/Core/arch/AVX512/MathFunctions.h
+++ b/Eigen/src/Core/arch/AVX512/MathFunctions.h
@@ -108,6 +108,7 @@
 
 BF16_PACKET_FUNCTION(Packet16f, Packet16bf, pcos)
 BF16_PACKET_FUNCTION(Packet16f, Packet16bf, pexp)
+BF16_PACKET_FUNCTION(Packet16f, Packet16bf, pexp2)
 BF16_PACKET_FUNCTION(Packet16f, Packet16bf, pexpm1)
 BF16_PACKET_FUNCTION(Packet16f, Packet16bf, plog)
 BF16_PACKET_FUNCTION(Packet16f, Packet16bf, plog1p)
@@ -119,6 +120,7 @@
 BF16_PACKET_FUNCTION(Packet16f, Packet16bf, ptanh)
 F16_PACKET_FUNCTION(Packet16f, Packet16h, pcos)
 F16_PACKET_FUNCTION(Packet16f, Packet16h, pexp)
+F16_PACKET_FUNCTION(Packet16f, Packet16h, pexp2)
 F16_PACKET_FUNCTION(Packet16f, Packet16h, pexpm1)
 F16_PACKET_FUNCTION(Packet16f, Packet16h, plog)
 F16_PACKET_FUNCTION(Packet16f, Packet16h, plog1p)
diff --git a/Eigen/src/Core/arch/AltiVec/PacketMath.h b/Eigen/src/Core/arch/AltiVec/PacketMath.h
index 6998e7c..7401c0b 100644
--- a/Eigen/src/Core/arch/AltiVec/PacketMath.h
+++ b/Eigen/src/Core/arch/AltiVec/PacketMath.h
@@ -2310,6 +2310,11 @@
 }
 
 template <>
+EIGEN_STRONG_INLINE Packet8bf pexp2<Packet8bf>(const Packet8bf& a) {
+  BF16_TO_F32_UNARY_OP_WRAPPER(generic_exp2, a);
+}
+
+template <>
 EIGEN_STRONG_INLINE Packet4f pldexp<Packet4f>(const Packet4f& a, const Packet4f& exponent) {
   return pldexp_generic(a, exponent);
 }
diff --git a/Eigen/src/Core/arch/Default/BFloat16.h b/Eigen/src/Core/arch/Default/BFloat16.h
index 14f0524..b8d3b4f 100644
--- a/Eigen/src/Core/arch/Default/BFloat16.h
+++ b/Eigen/src/Core/arch/Default/BFloat16.h
@@ -613,6 +613,7 @@
   return numext::bit_cast<bfloat16>(x);
 }
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp(const bfloat16& a) { return bfloat16(::expf(float(a))); }
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp2(const bfloat16& a) { return bfloat16(::exp2f(float(a))); }
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 expm1(const bfloat16& a) { return bfloat16(numext::expm1(float(a))); }
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log(const bfloat16& a) { return bfloat16(::logf(float(a))); }
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 log1p(const bfloat16& a) { return bfloat16(numext::log1p(float(a))); }
@@ -762,6 +763,31 @@
   return Eigen::bfloat16_impl::raw_bfloat16_as_uint16(src);
 }
 
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 nextafter(const bfloat16& from, const bfloat16& to) {
+  if (numext::isnan EIGEN_NOT_A_MACRO(from)) {
+    return from;
+  }
+  if (numext::isnan EIGEN_NOT_A_MACRO(to)) {
+    return to;
+  }
+  if (from == to) {
+    return to;
+  }
+  uint16_t from_bits = numext::bit_cast<uint16_t>(from);
+  bool from_sign = from_bits >> 15;
+  // Whether we are adjusting toward the infinity with the same sign as from.
+  bool toward_inf = (to > from) == !from_sign;
+  if (toward_inf) {
+    ++from_bits;
+  } else if ((from_bits & 0x7fff) == 0) {
+    // Adjusting away from inf, but from is zero, so just toggle the sign.
+    from_bits ^= 0x8000;
+  } else {
+    --from_bits;
+  }
+  return numext::bit_cast<bfloat16>(from_bits);
+}
+
 }  // namespace numext
 }  // namespace Eigen
 
diff --git a/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h b/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
index c3270e1..a184931 100644
--- a/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
+++ b/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h
@@ -469,7 +469,7 @@
     See: http://www.plunk.org/~hatch/rightway.php
  */
 template <typename Packet>
-Packet generic_plog1p(const Packet& x) {
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_log1p(const Packet& x) {
   typedef typename unpacket_traits<Packet>::type ScalarType;
   const Packet one = pset1<Packet>(ScalarType(1));
   Packet xp1 = padd(x, one);
@@ -484,7 +484,7 @@
     See: http://www.plunk.org/~hatch/rightway.php
  */
 template <typename Packet>
-Packet generic_expm1(const Packet& x) {
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_expm1(const Packet& x) {
   typedef typename unpacket_traits<Packet>::type ScalarType;
   const Packet one = pset1<Packet>(ScalarType(1));
   const Packet neg_one = pset1<Packet>(ScalarType(-1));
@@ -1109,7 +1109,7 @@
 }
 
 template <typename Packet>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_patan(const Packet& x_in) {
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_atan(const Packet& x_in) {
   typedef typename unpacket_traits<Packet>::type Scalar;
 
   constexpr Scalar kPiOverTwo = static_cast<Scalar>(EIGEN_PI / 2);
@@ -1973,13 +1973,13 @@
   }
 };
 
-// This function computes exp2(x) (i.e. 2**x).
+// This function accurately computes exp2(x) for x in [-0.5:0.5], which is
+// needed in pow(x,y).
 template <typename Scalar>
 struct fast_accurate_exp2 {
   template <typename Packet>
   EIGEN_STRONG_INLINE Packet operator()(const Packet& x) {
-    // TODO(rmlarsen): Add a pexp2 packetop.
-    return pexp(pmul(pset1<Packet>(Scalar(EIGEN_LN2)), x));
+    return generic_exp2(x);
   }
 };
 
@@ -2464,6 +2464,32 @@
   }
 };
 
+// This function computes exp2(x) = exp(ln(2) * x).
+// To improve accuracy, the product ln(2)*x is computed using the twoprod
+// algorithm, such that ln(2) * x = p_hi + p_lo holds exactly. Then exp2(x) is
+// computed as exp2(x) = exp(p_hi) * exp(p_lo) ~= exp(p_hi) * (1 + p_lo). This
+// correction step this reduces the maximum absolute error as follows:
+//
+// type   | max error (simple product) | max error (twoprod) |
+// -----------------------------------------------------------
+// float  |       35 ulps              |       4 ulps        |
+// double |      363 ulps              |     110 ulps        |
+//
+template <typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_exp2(const Packet& _x) {
+  typedef typename unpacket_traits<Packet>::type Scalar;
+  constexpr int max_exponent = std::numeric_limits<Scalar>::max_exponent;
+  constexpr int digits = std::numeric_limits<Scalar>::digits;
+  constexpr Scalar max_cap = Scalar(max_exponent + 1);
+  constexpr Scalar min_cap = -Scalar(max_exponent + digits - 1);
+  Packet x = pmax(pmin(_x, pset1<Packet>(max_cap)), pset1<Packet>(min_cap));
+  Packet p_hi, p_lo;
+  twoprod(pset1<Packet>(Scalar(EIGEN_LN2)), x, p_hi, p_lo);
+  Packet exp2_hi = pexp(p_hi);
+  Packet exp2_lo = padd(pset1<Packet>(Scalar(1)), p_lo);
+  return pmul(exp2_hi, exp2_lo);
+}
+
 template <typename Packet>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet generic_rint(const Packet& a) {
   using Scalar = typename unpacket_traits<Packet>::type;
diff --git a/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h b/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
index f470c20..3b362f4 100644
--- a/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
+++ b/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h
@@ -60,15 +60,19 @@
 
 /** \internal \returns log(1 + x) */
 template <typename Packet>
-Packet generic_plog1p(const Packet& x);
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_log1p(const Packet& x);
 
 /** \internal \returns exp(x)-1 */
 template <typename Packet>
-Packet generic_expm1(const Packet& x);
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_expm1(const Packet& x);
 
 /** \internal \returns atan(x) */
 template <typename Packet>
-EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_patan(const Packet& x);
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_atan(const Packet& x);
+
+/** \internal \returns exp2(x) */
+template <typename Packet>
+EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet generic_exp2(const Packet& x);
 
 /** \internal \returns exp(x) for single precision float */
 template <typename Packet>
@@ -159,44 +163,41 @@
     return p##METHOD##_##SCALAR(_x);                                                              \
   }
 
+// Macros for instantiating these generic functions for different backends.
+#define EIGEN_GENERIC_PACKET_FUNCTION(METHOD, PACKET)                                             \
+  template <>                                                                                     \
+  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED PACKET p##METHOD<PACKET>(const PACKET& _x) { \
+    return generic_##METHOD(_x);                                                                  \
+  }
+
 #define EIGEN_FLOAT_PACKET_FUNCTION(METHOD, PACKET) EIGEN_PACKET_FUNCTION(METHOD, float, PACKET)
 #define EIGEN_DOUBLE_PACKET_FUNCTION(METHOD, PACKET) EIGEN_PACKET_FUNCTION(METHOD, double, PACKET)
 
-#define EIGEN_INSTANTIATE_GENERIC_MATH_FUNCS_FLOAT(PACKET)                                     \
-  EIGEN_FLOAT_PACKET_FUNCTION(sin, PACKET)                                                     \
-  EIGEN_FLOAT_PACKET_FUNCTION(cos, PACKET)                                                     \
-  EIGEN_FLOAT_PACKET_FUNCTION(asin, PACKET)                                                    \
-  EIGEN_FLOAT_PACKET_FUNCTION(acos, PACKET)                                                    \
-  EIGEN_FLOAT_PACKET_FUNCTION(tanh, PACKET)                                                    \
-  EIGEN_FLOAT_PACKET_FUNCTION(atanh, PACKET)                                                   \
-  EIGEN_FLOAT_PACKET_FUNCTION(log, PACKET)                                                     \
-  EIGEN_FLOAT_PACKET_FUNCTION(log2, PACKET)                                                    \
-  EIGEN_FLOAT_PACKET_FUNCTION(exp, PACKET)                                                     \
-  template <>                                                                                  \
-  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED PACKET pexpm1<PACKET>(const PACKET& _x) { \
-    return generic_expm1(_x);                                                                  \
-  }                                                                                            \
-  template <>                                                                                  \
-  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED PACKET plog1p<PACKET>(const PACKET& _x) { \
-    return generic_plog1p(_x);                                                                 \
-  }                                                                                            \
-  template <>                                                                                  \
-  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED PACKET patan<PACKET>(const PACKET& _x) {  \
-    return generic_patan(_x);                                                                  \
-  }
+#define EIGEN_INSTANTIATE_GENERIC_MATH_FUNCS_FLOAT(PACKET) \
+  EIGEN_FLOAT_PACKET_FUNCTION(sin, PACKET)                 \
+  EIGEN_FLOAT_PACKET_FUNCTION(cos, PACKET)                 \
+  EIGEN_FLOAT_PACKET_FUNCTION(asin, PACKET)                \
+  EIGEN_FLOAT_PACKET_FUNCTION(acos, PACKET)                \
+  EIGEN_FLOAT_PACKET_FUNCTION(tanh, PACKET)                \
+  EIGEN_FLOAT_PACKET_FUNCTION(atanh, PACKET)               \
+  EIGEN_FLOAT_PACKET_FUNCTION(log, PACKET)                 \
+  EIGEN_FLOAT_PACKET_FUNCTION(log2, PACKET)                \
+  EIGEN_FLOAT_PACKET_FUNCTION(exp, PACKET)                 \
+  EIGEN_GENERIC_PACKET_FUNCTION(expm1, PACKET)             \
+  EIGEN_GENERIC_PACKET_FUNCTION(exp2, PACKET)              \
+  EIGEN_GENERIC_PACKET_FUNCTION(log1p, PACKET)             \
+  EIGEN_GENERIC_PACKET_FUNCTION(atan, PACKET)
 
-#define EIGEN_INSTANTIATE_GENERIC_MATH_FUNCS_DOUBLE(PACKET)                                   \
-  EIGEN_DOUBLE_PACKET_FUNCTION(atanh, PACKET)                                                 \
-  EIGEN_DOUBLE_PACKET_FUNCTION(log, PACKET)                                                   \
-  EIGEN_DOUBLE_PACKET_FUNCTION(sin, PACKET)                                                   \
-  EIGEN_DOUBLE_PACKET_FUNCTION(cos, PACKET)                                                   \
-  EIGEN_DOUBLE_PACKET_FUNCTION(log2, PACKET)                                                  \
-  EIGEN_DOUBLE_PACKET_FUNCTION(exp, PACKET)                                                   \
-  EIGEN_DOUBLE_PACKET_FUNCTION(tanh, PACKET)                                                  \
-  template <>                                                                                 \
-  EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC EIGEN_UNUSED PACKET patan<PACKET>(const PACKET& _x) { \
-    return generic_patan(_x);                                                                 \
-  }
+#define EIGEN_INSTANTIATE_GENERIC_MATH_FUNCS_DOUBLE(PACKET) \
+  EIGEN_DOUBLE_PACKET_FUNCTION(atanh, PACKET)               \
+  EIGEN_DOUBLE_PACKET_FUNCTION(log, PACKET)                 \
+  EIGEN_DOUBLE_PACKET_FUNCTION(sin, PACKET)                 \
+  EIGEN_DOUBLE_PACKET_FUNCTION(cos, PACKET)                 \
+  EIGEN_DOUBLE_PACKET_FUNCTION(log2, PACKET)                \
+  EIGEN_DOUBLE_PACKET_FUNCTION(exp, PACKET)                 \
+  EIGEN_DOUBLE_PACKET_FUNCTION(tanh, PACKET)                \
+  EIGEN_GENERIC_PACKET_FUNCTION(atan, PACKET)               \
+  EIGEN_GENERIC_PACKET_FUNCTION(exp2, PACKET)
 
 }  // end namespace internal
 }  // end namespace Eigen
diff --git a/Eigen/src/Core/arch/Default/Half.h b/Eigen/src/Core/arch/Default/Half.h
index 1f314fa..a8cb228 100644
--- a/Eigen/src/Core/arch/Default/Half.h
+++ b/Eigen/src/Core/arch/Default/Half.h
@@ -672,6 +672,14 @@
   return half(::expf(float(a)));
 #endif
 }
+EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half exp2(const half& a) {
+#if (EIGEN_CUDA_SDK_VER >= 80000 && defined EIGEN_CUDA_ARCH && EIGEN_CUDA_ARCH >= 530) || \
+    defined(EIGEN_HIP_DEVICE_COMPILE)
+  return half(hexp2(a));
+#else
+  return half(::exp2f(float(a)));
+#endif
+}
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half expm1(const half& a) { return half(numext::expm1(float(a))); }
 EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half log(const half& a) {
 #if (defined(EIGEN_HAS_CUDA_FP16) && EIGEN_CUDA_SDK_VER >= 80000 && defined(EIGEN_CUDA_ARCH) && \
diff --git a/Eigen/src/Core/arch/GPU/MathFunctions.h b/Eigen/src/Core/arch/GPU/MathFunctions.h
index 606215f..81bc8bb 100644
--- a/Eigen/src/Core/arch/GPU/MathFunctions.h
+++ b/Eigen/src/Core/arch/GPU/MathFunctions.h
@@ -54,6 +54,17 @@
 }
 
 template <>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 pexp2<float4>(const float4& a) {
+  return make_float4(exp2f(a.x), exp2f(a.y), exp2f(a.z), exp2f(a.w));
+}
+
+template <>
+EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE double2 pexp2<double2>(const double2& a) {
+  using ::exp;
+  return make_double2(exp2(a.x), exp2(a.y));
+}
+
+template <>
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float4 pexpm1<float4>(const float4& a) {
   return make_float4(expm1f(a.x), expm1f(a.y), expm1f(a.z), expm1f(a.w));
 }
diff --git a/Eigen/src/Core/arch/NEON/MathFunctions.h b/Eigen/src/Core/arch/NEON/MathFunctions.h
index bebe081..0046e01 100644
--- a/Eigen/src/Core/arch/NEON/MathFunctions.h
+++ b/Eigen/src/Core/arch/NEON/MathFunctions.h
@@ -37,6 +37,7 @@
 BF16_PACKET_FUNCTION(Packet4f, Packet4bf, pcos)
 BF16_PACKET_FUNCTION(Packet4f, Packet4bf, plog)
 BF16_PACKET_FUNCTION(Packet4f, Packet4bf, pexp)
+BF16_PACKET_FUNCTION(Packet4f, Packet4bf, pexp2)
 BF16_PACKET_FUNCTION(Packet4f, Packet4bf, ptanh)
 
 template <>
diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h
index ce0d0ab..37f6048 100644
--- a/Eigen/src/Core/arch/SSE/PacketMath.h
+++ b/Eigen/src/Core/arch/SSE/PacketMath.h
@@ -1230,13 +1230,13 @@
 
 template <>
 EIGEN_STRONG_INLINE Packet4f pabs(const Packet4f& a) {
-  const Packet4f mask = _mm_castsi128_ps(_mm_setr_epi32(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF));
-  return _mm_and_ps(a, mask);
+  const __m128i mask = _mm_setr_epi32(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
+  return _mm_castsi128_ps(_mm_and_si128(mask, _mm_castps_si128(a)));
 }
 template <>
 EIGEN_STRONG_INLINE Packet2d pabs(const Packet2d& a) {
-  const Packet2d mask = _mm_castsi128_pd(_mm_setr_epi32(0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF));
-  return _mm_and_pd(a, mask);
+  const __m128i mask = _mm_setr_epi32(0xFFFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF);
+  return _mm_castsi128_pd(_mm_and_si128(mask, _mm_castpd_si128(a)));
 }
 template <>
 EIGEN_STRONG_INLINE Packet2l pabs(const Packet2l& a) {
diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h
index b3b7d79..defd3c2 100644
--- a/Eigen/src/Core/functors/UnaryFunctors.h
+++ b/Eigen/src/Core/functors/UnaryFunctors.h
@@ -376,6 +376,22 @@
   };
 };
 
+template <typename Scalar>
+struct scalar_exp2_op {
+  EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return internal::pexp2(a); }
+  template <typename Packet>
+  EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const {
+    return internal::pexp2(a);
+  }
+};
+template <typename Scalar>
+struct functor_traits<scalar_exp2_op<Scalar>> {
+  enum {
+    PacketAccess = packet_traits<Scalar>::HasExp,
+    Cost = functor_traits<scalar_exp_op<Scalar>>::Cost  // TODO measure cost of exp2
+  };
+};
+
 /** \internal
  *
  * \brief Template functor to compute the exponential of a scalar - 1.
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
index ac94b3f..f47615f 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
@@ -68,6 +68,10 @@
                                       const RhsScalar* rhs_, Index rhsStride, ResScalar* res_, Index resIncr,
                                       Index resStride, const ResScalar& alpha,
                                       level3_blocking<LhsScalar, RhsScalar>& blocking) {
+    if (size == 0) {
+      return;
+    }
+
     typedef gebp_traits<LhsScalar, RhsScalar> Traits;
 
     typedef const_blas_data_mapper<LhsScalar, Index, LhsStorageOrder> LhsMapper;
@@ -157,7 +161,7 @@
     gebp_kernel<LhsScalar, RhsScalar, Index, ResMapper, mr, nr, ConjLhs, ConjRhs> gebp_kernel1;
     gebp_kernel<LhsScalar, RhsScalar, Index, BufferMapper, mr, nr, ConjLhs, ConjRhs> gebp_kernel2;
 
-    Matrix<ResScalar, BlockSize, BlockSize, ColMajor> buffer((internal::constructor_without_unaligned_array_assert()));
+    Matrix<ResScalar, BlockSize, BlockSize, ColMajor> buffer;
 
     // let's process the block per panel of actual_mc x BlockSize,
     // again, each is split into three parts, etc.
diff --git a/Eigen/src/Core/products/SelfadjointMatrixVector.h b/Eigen/src/Core/products/SelfadjointMatrixVector.h
index 9333d16..10f6026 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixVector.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixVector.h
@@ -197,6 +197,7 @@
 
     if (!EvalToDest) {
 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+      constexpr int Size = Dest::SizeAtCompileTime;
       Index size = dest.size();
       EIGEN_DENSE_STORAGE_CTOR_PLUGIN
 #endif
@@ -205,6 +206,7 @@
 
     if (!UseRhs) {
 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+      constexpr int Size = ActualRhsTypeCleaned::SizeAtCompileTime;
       Index size = rhs.size();
       EIGEN_DENSE_STORAGE_CTOR_PLUGIN
 #endif
diff --git a/Eigen/src/Core/products/TriangularMatrixMatrix.h b/Eigen/src/Core/products/TriangularMatrixMatrix.h
index c541909..a0d05ef 100644
--- a/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ b/Eigen/src/Core/products/TriangularMatrixMatrix.h
@@ -113,13 +113,7 @@
   ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
   ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
 
-  // To work around an "error: member reference base type 'Matrix<...>
-  // (Eigen::internal::constructor_without_unaligned_array_assert (*)())' is
-  // not a structure or union" compilation error in nvcc (tested V8.0.61),
-  // create a dummy internal::constructor_without_unaligned_array_assert
-  // object to pass to the Matrix constructor.
-  internal::constructor_without_unaligned_array_assert a;
-  Matrix<Scalar, SmallPanelWidth, SmallPanelWidth, LhsStorageOrder> triangularBuffer(a);
+  Matrix<Scalar, SmallPanelWidth, SmallPanelWidth, LhsStorageOrder> triangularBuffer;
   triangularBuffer.setZero();
   if ((Mode & ZeroDiag) == ZeroDiag)
     triangularBuffer.diagonal().setZero();
@@ -245,8 +239,7 @@
   ei_declare_aligned_stack_constructed_variable(Scalar, blockA, sizeA, blocking.blockA());
   ei_declare_aligned_stack_constructed_variable(Scalar, blockB, sizeB, blocking.blockB());
 
-  internal::constructor_without_unaligned_array_assert a;
-  Matrix<Scalar, SmallPanelWidth, SmallPanelWidth, RhsStorageOrder> triangularBuffer(a);
+  Matrix<Scalar, SmallPanelWidth, SmallPanelWidth, RhsStorageOrder> triangularBuffer;
   triangularBuffer.setZero();
   if ((Mode & ZeroDiag) == ZeroDiag)
     triangularBuffer.diagonal().setZero();
diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h
index 05a5827..bef4cba 100644
--- a/Eigen/src/Core/products/TriangularMatrixVector.h
+++ b/Eigen/src/Core/products/TriangularMatrixVector.h
@@ -230,6 +230,7 @@
 
     if (!evalToDest) {
 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+      constexpr int Size = Dest::SizeAtCompileTime;
       Index size = dest.size();
       EIGEN_DENSE_STORAGE_CTOR_PLUGIN
 #endif
@@ -310,6 +311,7 @@
 #endif
       }
 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
+      constexpr int Size = ActualRhsTypeCleaned::SizeAtCompileTime;
       Index size = actualRhs.size();
       EIGEN_DENSE_STORAGE_CTOR_PLUGIN
 #endif
diff --git a/Eigen/src/Core/util/DisableStupidWarnings.h b/Eigen/src/Core/util/DisableStupidWarnings.h
index 32a427d..ab0c542 100644
--- a/Eigen/src/Core/util/DisableStupidWarnings.h
+++ b/Eigen/src/Core/util/DisableStupidWarnings.h
@@ -83,7 +83,7 @@
 #endif
 #endif
 
-#if defined __NVCC__
+#if defined __NVCC__ && defined __CUDACC__
 // MSVC 14.16 (required by CUDA 9.*) does not support the _Pragma keyword, so
 // we instead use Microsoft's __pragma extension.
 #if defined _MSC_VER
diff --git a/Eigen/src/Core/util/IndexedViewHelper.h b/Eigen/src/Core/util/IndexedViewHelper.h
index 59486ea..abf4b19 100644
--- a/Eigen/src/Core/util/IndexedViewHelper.h
+++ b/Eigen/src/Core/util/IndexedViewHelper.h
@@ -69,7 +69,7 @@
 #else
 // Using a FixedExpr<1> expression is important here to make sure the compiler
 // can fully optimize the computation starting indices with zero overhead.
-static constexpr lastp1_t lastp1(last + fix<1>());
+static constexpr lastp1_t lastp1 = lastp1_t{};
 #endif
 
 /** \var end
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 3bf5ec1..318b70d 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -1087,14 +1087,7 @@
 #define EIGEN_USING_STD(FUNC) using std::FUNC;
 #endif
 
-#if EIGEN_COMP_MSVC_STRICT && EIGEN_COMP_NVCC
-// Wwhen compiling with NVCC, using the base operator is necessary,
-//   otherwise we get duplicate definition errors
-// For later MSVC versions, we require explicit operator= definition, otherwise we get
-//   use of implicitly deleted operator errors.
-// (cf Bugs 920, 1000, 1324, 2291)
-#define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) using Base::operator=;
-#elif EIGEN_COMP_CLANG  // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
+#if EIGEN_COMP_CLANG  // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)
 #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)                                           \
   using Base::operator=;                                                                           \
   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) {                 \
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 7edd0a1..d59071f 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -765,7 +765,7 @@
 // We always manually re-align the result of EIGEN_ALLOCA.
 // If alloca is already aligned, the compiler should be smart enough to optimize away the re-alignment.
 
-#if (EIGEN_COMP_GNUC || EIGEN_COMP_CLANG)
+#if ((EIGEN_COMP_GNUC || EIGEN_COMP_CLANG) && !EIGEN_COMP_NVHPC)
 #define EIGEN_ALIGNED_ALLOCA(SIZE) __builtin_alloca_with_align(SIZE, CHAR_BIT* EIGEN_DEFAULT_ALIGN_BYTES)
 #else
 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void* eigen_aligned_alloca_helper(void* ptr) {
diff --git a/Eigen/src/Geometry/arch/Geometry_SIMD.h b/Eigen/src/Geometry/arch/Geometry_SIMD.h
index e8b210e..5601a47 100644
--- a/Eigen/src/Geometry/arch/Geometry_SIMD.h
+++ b/Eigen/src/Geometry/arch/Geometry_SIMD.h
@@ -74,7 +74,9 @@
     Packet4f mul1 = pmul(vec4f_swizzle1(a, 1, 2, 0, 3), vec4f_swizzle1(b, 2, 0, 1, 3));
     Packet4f mul2 = pmul(vec4f_swizzle1(a, 2, 0, 1, 3), vec4f_swizzle1(b, 1, 2, 0, 3));
     DstPlainType res;
-    pstoret<float, Packet4f, DstAlignment>(&res.x(), psub(mul1, mul2));
+    pstoret<float, Packet4f, DstAlignment>(res.data(), psub(mul1, mul2));
+    // Ensure last component is 0 in case original a or b contain inf/nan.
+    res[3] = 0.0f;
     return res;
   }
 };
diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.inc b/Eigen/src/plugins/ArrayCwiseUnaryOps.inc
index cc708fa..93f7eab 100644
--- a/Eigen/src/plugins/ArrayCwiseUnaryOps.inc
+++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.inc
@@ -11,6 +11,7 @@
 typedef CwiseUnaryOp<internal::scalar_bitwise_not_op<Scalar>, const Derived> BitwiseNotReturnType;
 
 typedef CwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived> ExpReturnType;
+typedef CwiseUnaryOp<internal::scalar_exp2_op<Scalar>, const Derived> Exp2ReturnType;
 typedef CwiseUnaryOp<internal::scalar_expm1_op<Scalar>, const Derived> Expm1ReturnType;
 typedef CwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived> LogReturnType;
 typedef CwiseUnaryOp<internal::scalar_log1p_op<Scalar>, const Derived> Log1pReturnType;
@@ -78,10 +79,20 @@
  * Example: \include Cwise_exp.cpp
  * Output: \verbinclude Cwise_exp.out
  *
- * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_exp">Math functions</a>, pow(), log(), sin(), cos()
+ * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_exp">Math functions</a>, exp2(), pow(), log(), sin(),
+ * cos()
  */
 EIGEN_DEVICE_FUNC inline const ExpReturnType exp() const { return ExpReturnType(derived()); }
 
+/** \returns an expression of the coefficient-wise exponential of *this.
+ *
+ * This function computes the coefficient-wise base2 exponential, i.e. 2^x.
+ *
+ * \sa <a href="group__CoeffwiseMathFunctions.html#cwisetable_exp">Math functions</a>, exp(), pow(), log(), sin(),
+ * cos()
+ */
+EIGEN_DEVICE_FUNC inline const Exp2ReturnType exp2() const { return Exp2ReturnType(derived()); }
+
 /** \returns an expression of the coefficient-wise exponential of *this minus 1.
  *
  * In exact arithmetic, \c x.expm1() is equivalent to \c x.exp() - 1,
diff --git a/test/array_cwise.cpp b/test/array_cwise.cpp
index cc901ff..cf0e6e4 100644
--- a/test/array_cwise.cpp
+++ b/test/array_cwise.cpp
@@ -181,6 +181,7 @@
   unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sqrt));
   unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cbrt));
   unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(exp));
+  unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(exp2));
   unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(log));
   unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(sin));
   unary_op_test<Scalar>(UNARY_FUNCTOR_TEST_ARGS(cos));
diff --git a/test/bfloat16_float.cpp b/test/bfloat16_float.cpp
index 5be49d9..12d6d86 100644
--- a/test/bfloat16_float.cpp
+++ b/test/bfloat16_float.cpp
@@ -353,6 +353,40 @@
   VERIFY_IS_APPROX(Ch.noalias() += Ah * Bh, (Cf.noalias() += Af * Bf).cast<bfloat16>());
 }
 
+void test_nextafter() {
+  VERIFY((numext::isnan)(numext::nextafter(std::numeric_limits<bfloat16>::quiet_NaN(), bfloat16(1.0f))));
+  VERIFY((numext::isnan)(numext::nextafter(bfloat16(1.0f), std::numeric_limits<bfloat16>::quiet_NaN())));
+  VERIFY(numext::nextafter(bfloat16(0.0f), bfloat16(0.0f)) == bfloat16(0.0f));
+  VERIFY(numext::nextafter(bfloat16(1.0f), bfloat16(1.0f)) == bfloat16(1.0f));
+  VERIFY(numext::nextafter(bfloat16(-1.0f), bfloat16(-1.0f)) == bfloat16(-1.0f));
+  VERIFY(numext::nextafter(std::numeric_limits<bfloat16>::infinity(), std::numeric_limits<bfloat16>::infinity()) ==
+         std::numeric_limits<bfloat16>::infinity());
+  VERIFY(numext::nextafter(std::numeric_limits<bfloat16>::infinity(), bfloat16(0.0f)) ==
+         (std::numeric_limits<bfloat16>::max)());
+  VERIFY(numext::nextafter(-std::numeric_limits<bfloat16>::infinity(), bfloat16(0.0f)) ==
+         -(std::numeric_limits<bfloat16>::max)());
+  VERIFY(numext::nextafter(bfloat16(1.0f), std::numeric_limits<bfloat16>::infinity()) ==
+         bfloat16(1.0f) + std::numeric_limits<bfloat16>::epsilon());
+  VERIFY(numext::nextafter(bfloat16(1.0f), -std::numeric_limits<bfloat16>::infinity()) ==
+         bfloat16(1.0f) - std::numeric_limits<bfloat16>::epsilon() / bfloat16(2.0f));
+  VERIFY(numext::nextafter(bfloat16(-1.0f), -std::numeric_limits<bfloat16>::infinity()) ==
+         bfloat16(-1.0f) - std::numeric_limits<bfloat16>::epsilon());
+  VERIFY(numext::nextafter(bfloat16(-1.0f), std::numeric_limits<bfloat16>::infinity()) ==
+         bfloat16(-1.0f) + std::numeric_limits<bfloat16>::epsilon() / bfloat16(2.0f));
+  VERIFY(numext::nextafter((std::numeric_limits<bfloat16>::max)(), std::numeric_limits<bfloat16>::infinity()) ==
+         std::numeric_limits<bfloat16>::infinity());
+  VERIFY(numext::nextafter(-(std::numeric_limits<bfloat16>::max)(), -std::numeric_limits<bfloat16>::infinity()) ==
+         -std::numeric_limits<bfloat16>::infinity());
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(1.0f)), 0x0001);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(1.0f)), 0x0000);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(-1.0f)), 0x8000);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(-1.0f)), 0x8001);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(-0.0f)), 0x8000);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(0.0f)), 0x0000);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(0.0f), bfloat16(0.0f)), 0x0000);
+  VERIFY_BFLOAT16_BITS_EQUAL(numext::nextafter(bfloat16(-0.0f), bfloat16(-0.0f)), 0x8000);
+}
+
 EIGEN_DECLARE_TEST(bfloat16_float) {
   CALL_SUBTEST(test_numtraits());
   for (int i = 0; i < g_repeat; i++) {
@@ -363,5 +397,6 @@
     CALL_SUBTEST(test_trigonometric_functions());
     CALL_SUBTEST(test_array());
     CALL_SUBTEST(test_product());
+    CALL_SUBTEST(test_nextafter());
   }
 }
diff --git a/test/dense_storage.cpp b/test/dense_storage.cpp
index 8d61e92..5d0083f 100644
--- a/test/dense_storage.cpp
+++ b/test/dense_storage.cpp
@@ -7,13 +7,15 @@
 // 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/.
 
+#define EIGEN_TESTING_PLAINOBJECT_CTOR
+
 #include "main.h"
 #include "AnnoyingScalar.h"
 #include "SafeScalar.h"
 
 #include <Eigen/Core>
 
-using DenseStorageD3x3 = Eigen::DenseStorage<double, 3, 3, 3, 3>;
+using DenseStorageD3x3 = Eigen::DenseStorage<double, 9, 3, 3, 0>;
 static_assert(std::is_trivially_move_constructible<DenseStorageD3x3>::value,
               "DenseStorage not trivially_move_constructible");
 static_assert(std::is_trivially_move_assignable<DenseStorageD3x3>::value, "DenseStorage not trivially_move_assignable");
@@ -24,6 +26,15 @@
 static_assert(std::is_trivially_copyable<DenseStorageD3x3>::value, "DenseStorage not trivially_copyable");
 #endif
 
+static_assert(std::is_trivially_move_constructible<Matrix4f>::value, "Matrix4f not trivially_move_constructible");
+static_assert(std::is_trivially_move_constructible<Array4f>::value, "Array4f not trivially_move_constructible");
+#if !defined(EIGEN_DENSE_STORAGE_CTOR_PLUGIN)
+static_assert(std::is_trivially_copy_constructible<Matrix4f>::value, "Matrix4f not trivially_copy_constructible");
+static_assert(std::is_trivially_copy_constructible<Array4f>::value, "Array4f not trivially_copy_constructible");
+#endif
+static_assert(std::is_trivially_default_constructible<Matrix4f>::value, "Matrix4f not trivially_default_constructible");
+static_assert(std::is_trivially_default_constructible<Array4f>::value, "Array4f not trivially_default_constructible");
+
 template <typename T, int Size, int Rows, int Cols>
 void dense_storage_copy(int rows, int cols) {
   typedef DenseStorage<T, Size, Rows, Cols, 0> DenseStorageType;
@@ -180,3 +191,5 @@
   dense_storage_tests<SafeScalar<float> >();
   dense_storage_tests<AnnoyingScalar>();
 }
+
+#undef EIGEN_TESTING_PLAINOBJECT_CTOR
\ No newline at end of file
diff --git a/test/main.h b/test/main.h
index c7cc531..a8e951f 100644
--- a/test/main.h
+++ b/test/main.h
@@ -18,6 +18,7 @@
 #include <sstream>
 #include <vector>
 #include <typeinfo>
+#include <type_traits>
 #include <functional>
 #ifdef EIGEN_USE_SYCL
 #include <CL/sycl.hpp>
@@ -142,14 +143,20 @@
 static long int nb_temporaries;
 static long int nb_temporaries_on_assert = -1;
 
-inline void on_temporary_creation(long int size) {
+#ifdef TEST_IGNORE_STACK_ALLOCATED_TEMPORARY
+inline void on_temporary_creation(long int size, int SizeAtCompileTime) {
+  // ignore stack-allocated temporaries
+  if (SizeAtCompileTime != -1) return;
+#else
+inline void on_temporary_creation(long int size, int) {
+#endif
   // here's a great place to set a breakpoint when debugging failures in this test!
   if (size != 0) nb_temporaries++;
   if (nb_temporaries_on_assert > 0) assert(nb_temporaries < nb_temporaries_on_assert);
 }
 
 #define EIGEN_DENSE_STORAGE_CTOR_PLUGIN \
-  { on_temporary_creation(size); }
+  { on_temporary_creation(size, Size); }
 
 #define VERIFY_EVALUATION_COUNT(XPR, N)                            \
   {                                                                \
@@ -333,7 +340,7 @@
 
 #endif  // EIGEN_NO_ASSERTION_CHECKING
 
-#ifndef EIGEN_TESTING_CONSTEXPR
+#if !defined(EIGEN_TESTING_CONSTEXPR) && !defined(EIGEN_TESTING_PLAINOBJECT_CTOR)
 #define EIGEN_INTERNAL_DEBUGGING
 #endif
 #include <Eigen/QR>  // required for createRandomPIMatrixOfRank and generateRandomMatrixSvs
diff --git a/test/packetmath.cpp b/test/packetmath.cpp
index 9afe470..e4d1b8c 100644
--- a/test/packetmath.cpp
+++ b/test/packetmath.cpp
@@ -931,6 +931,7 @@
     data1[0] = -NumTraits<Scalar>::infinity();
   }
   CHECK_CWISE1_IF(PacketTraits::HasExp, std::exp, internal::pexp);
+  CHECK_CWISE1_IF(PacketTraits::HasExp, std::exp2, internal::pexp2);
 
   CHECK_CWISE1_BYREF1_IF(PacketTraits::HasExp, REF_FREXP, internal::pfrexp);
   if (PacketTraits::HasExp) {
diff --git a/test/product.h b/test/product.h
index 74f01b0..f8eb5df 100644
--- a/test/product.h
+++ b/test/product.h
@@ -188,8 +188,10 @@
     VERIFY(areNotApprox(res2, square2 + m2.transpose() * m1, not_approx_epsilon));
   }
 
-  VERIFY_IS_APPROX(res.col(r).noalias() = square.adjoint() * square.col(r), (square.adjoint() * square.col(r)).eval());
-  VERIFY_IS_APPROX(res.col(r).noalias() = square * square.col(r), (square * square.col(r)).eval());
+  res.col(r).noalias() = square.adjoint() * square.col(r);
+  VERIFY_IS_APPROX(res.col(r), (square.adjoint() * square.col(r)).eval());
+  res.col(r).noalias() = square * square.col(r);
+  VERIFY_IS_APPROX(res.col(r), (square * square.col(r)).eval());
 
   // vector at runtime (see bug 1166)
   {
diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp
index c22ea13..84ce3c6 100644
--- a/test/product_notemporary.cpp
+++ b/test/product_notemporary.cpp
@@ -8,6 +8,7 @@
 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #define TEST_ENABLE_TEMPORARY_TRACKING
+#define TEST_IGNORE_STACK_ALLOCATED_TEMPORARY
 
 #include "main.h"
 
diff --git a/test/reshape.cpp b/test/reshape.cpp
index 7c76cd5..417d18a 100644
--- a/test/reshape.cpp
+++ b/test/reshape.cpp
@@ -19,7 +19,7 @@
 }
 
 template <int Order, typename MatType>
-void check_auto_reshape4x4(MatType m) {
+void check_auto_reshape4x4(const MatType& m) {
   internal::VariableAndFixedInt<MatType::SizeAtCompileTime == Dynamic ? -1 : 1> v1(1);
   internal::VariableAndFixedInt<MatType::SizeAtCompileTime == Dynamic ? -1 : 2> v2(2);
   internal::VariableAndFixedInt<MatType::SizeAtCompileTime == Dynamic ? -1 : 4> v4(4);
@@ -50,10 +50,10 @@
 }
 
 template <typename MatType>
-void check_direct_access_reshape4x4(MatType, internal::FixedInt<RowMajorBit>) {}
+void check_direct_access_reshape4x4(const MatType&, internal::FixedInt<RowMajorBit>) {}
 
 template <typename MatType>
-void check_direct_access_reshape4x4(MatType m, internal::FixedInt<0>) {
+void check_direct_access_reshape4x4(const MatType& m, internal::FixedInt<0>) {
   VERIFY_IS_EQUAL(m.reshaped(1, 16).data(), m.data());
   VERIFY_IS_EQUAL(m.reshaped(1, 16).innerStride(), 1);
 
@@ -64,8 +64,9 @@
 
 // just test a 4x4 matrix, enumerate all combination manually
 template <typename MatType>
-void reshape4x4(MatType m) {
+void reshape4x4(const MatType& m0) {
   typedef typename MatType::Scalar Scalar;
+  MatType m = m0;
 
   internal::VariableAndFixedInt<MatType::SizeAtCompileTime == Dynamic ? -1 : 1> v1(1);
   internal::VariableAndFixedInt<MatType::SizeAtCompileTime == Dynamic ? -1 : 2> v2(2);
diff --git a/test/sizeof.cpp b/test/sizeof.cpp
index 4820ee8..b75645f 100644
--- a/test/sizeof.cpp
+++ b/test/sizeof.cpp
@@ -15,6 +15,8 @@
   if (MatrixType::RowsAtCompileTime != Dynamic && MatrixType::ColsAtCompileTime != Dynamic)
     VERIFY_IS_EQUAL(std::ptrdiff_t(sizeof(MatrixType)),
                     std::ptrdiff_t(sizeof(Scalar)) * std::ptrdiff_t(MatrixType::SizeAtCompileTime));
+  else if (MatrixType::RowsAtCompileTime != Dynamic || MatrixType::ColsAtCompileTime != Dynamic)
+    VERIFY_IS_EQUAL(sizeof(MatrixType), sizeof(Scalar*) + sizeof(Index));
   else
     VERIFY_IS_EQUAL(sizeof(MatrixType), sizeof(Scalar*) + 2 * sizeof(Index));
 }
@@ -35,6 +37,8 @@
   CALL_SUBTEST(verifySizeOf(Vector2d()));
   CALL_SUBTEST(verifySizeOf(Vector4f()));
   CALL_SUBTEST(verifySizeOf(Matrix4d()));
+  CALL_SUBTEST(verifySizeOf(Matrix<float, 300, Eigen::Dynamic>()));
+  CALL_SUBTEST(verifySizeOf(Matrix<float, Eigen::Dynamic, 300>()));
   CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()));
   CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()));
   CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)));
diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h b/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
index fde1b82..9647976 100644
--- a/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
+++ b/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h
@@ -71,8 +71,6 @@
       m_data = internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(1);
     }
   }
-  EIGEN_DEVICE_FUNC TensorStorage(internal::constructor_without_unaligned_array_assert)
-      : m_data(0), m_dimensions(internal::template repeat<NumIndices_, Index>(0)) {}
   EIGEN_DEVICE_FUNC TensorStorage(Index size, const array<Index, NumIndices_>& dimensions)
       : m_data(internal::conditional_aligned_new_auto<T, (Options_ & DontAlign) == 0>(size)), m_dimensions(dimensions) {
     EIGEN_INTERNAL_TENSOR_STORAGE_CTOR_PLUGIN
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index 3a985cf..8af6130 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -69,9 +69,9 @@
   ei_add_property(EIGEN_TESTED_BACKENDS "fftw, ")
   include_directories( ${FFTW_INCLUDES} )
   if(FFTWL_LIB)
-    ei_add_test(FFTW  "-DEIGEN_FFTW_DEFAULT -DEIGEN_HAS_FFTWL" "${FFTW_LIBRARIES}" )
+    ei_add_test(FFTW  "-DEIGEN_HAS_FFTWL" "${FFTW_LIBRARIES}" )
   else()
-    ei_add_test(FFTW  "-DEIGEN_FFTW_DEFAULT" "${FFTW_LIBRARIES}" )
+    ei_add_test(FFTW  "${FFTW_LIBRARIES}" )
   endif()
 else()
   ei_add_property(EIGEN_MISSING_BACKENDS "fftw, ")
@@ -82,8 +82,8 @@
   if(EIGEN_TEST_CXX11)
     ei_add_property(EIGEN_TESTED_BACKENDS "pocketfft, ")
     include_directories( ${POCKETFFT} )
-    ei_add_test(pocketfft "-pthread" "${CMAKE_THREAD_LIBS_INIT}" "-DEIGEN_POCKETFFT_DEFAULT" )  
-  endif()  
+    ei_add_test(pocketfft "-pthread" "${CMAKE_THREAD_LIBS_INIT}" )
+  endif()
 else()
   ei_add_property(EIGEN_MISSING_BACKENDS "pocketfft, ")
 endif()