Enable direct access for IndexedView.
diff --git a/Eigen/src/Core/ArithmeticSequence.h b/Eigen/src/Core/ArithmeticSequence.h
index 0f45e89..055beab 100644
--- a/Eigen/src/Core/ArithmeticSequence.h
+++ b/Eigen/src/Core/ArithmeticSequence.h
@@ -226,6 +226,11 @@
   enum { value = get_fixed_value<IncrType, DynamicIndex>::value };
 };
 
+template <typename FirstType, typename SizeType, typename IncrType>
+constexpr Index get_runtime_incr(const ArithmeticSequence<FirstType, SizeType, IncrType>& x) EIGEN_NOEXCEPT {
+  return static_cast<Index>(x.incrObject());
+};
+
 }  // end namespace internal
 
 /** \namespace Eigen::indexing
diff --git a/Eigen/src/Core/IndexedView.h b/Eigen/src/Core/IndexedView.h
index 0a02417..b90ecb1 100644
--- a/Eigen/src/Core/IndexedView.h
+++ b/Eigen/src/Core/IndexedView.h
@@ -75,11 +75,11 @@
   typedef Block<XprType, RowsAtCompileTime, ColsAtCompileTime, IsInnerPannel> BlockType;
 };
 
-}  // namespace internal
-
-template <typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
+template <typename XprType, typename RowIndices, typename ColIndices, typename StorageKind, bool DirectAccess>
 class IndexedViewImpl;
 
+}  // namespace internal
+
 /** \class IndexedView
  * \ingroup Core_Module
  *
@@ -120,19 +120,36 @@
  */
 template <typename XprType, typename RowIndices, typename ColIndices>
 class IndexedView
-    : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind> {
+    : public internal::IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind,
+                                       (internal::traits<IndexedView<XprType, RowIndices, ColIndices>>::Flags &
+                                        DirectAccessBit) != 0> {
  public:
-  typedef
-      typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base
-          Base;
+  typedef typename internal::IndexedViewImpl<
+      XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind,
+      (internal::traits<IndexedView<XprType, RowIndices, ColIndices>>::Flags & DirectAccessBit) != 0>
+      Base;
   EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView)
   EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView)
 
+  template <typename T0, typename T1>
+  IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices) : Base(xpr, rowIndices, colIndices) {}
+};
+
+namespace internal {
+
+// Generic API dispatcher
+template <typename XprType, typename RowIndices, typename ColIndices, typename StorageKind, bool DirectAccess>
+class IndexedViewImpl : public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices>>::type {
+ public:
+  typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices>>::type Base;
   typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
   typedef internal::remove_all_t<XprType> NestedExpression;
+  typedef typename XprType::Scalar Scalar;
+
+  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedViewImpl)
 
   template <typename T0, typename T1>
-  IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices)
+  IndexedViewImpl(XprType& xpr, const T0& rowIndices, const T1& colIndices)
       : m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices) {}
 
   /** \returns number of rows */
@@ -153,20 +170,76 @@
   /** \returns a const reference to the object storing/generating the column indices */
   const ColIndices& colIndices() const { return m_colIndices; }
 
+  constexpr Scalar& coeffRef(Index rowId, Index colId) {
+    return nestedExpression().coeffRef(m_rowIndices[rowId], m_colIndices[colId]);
+  }
+
+  constexpr const Scalar& coeffRef(Index rowId, Index colId) const {
+    return nestedExpression().coeffRef(m_rowIndices[rowId], m_colIndices[colId]);
+  }
+
  protected:
   MatrixTypeNested m_xpr;
   RowIndices m_rowIndices;
   ColIndices m_colIndices;
 };
 
-// Generic API dispatcher
 template <typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
-class IndexedViewImpl : public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices>>::type {
+class IndexedViewImpl<XprType, RowIndices, ColIndices, StorageKind, true>
+    : public IndexedViewImpl<XprType, RowIndices, ColIndices, StorageKind, false> {
  public:
-  typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices>>::type Base;
-};
+  using Base = internal::IndexedViewImpl<XprType, RowIndices, ColIndices,
+                                         typename internal::traits<XprType>::StorageKind, false>;
+  using Derived = IndexedView<XprType, RowIndices, ColIndices>;
 
-namespace internal {
+  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedViewImpl)
+
+  template <typename T0, typename T1>
+  IndexedViewImpl(XprType& xpr, const T0& rowIndices, const T1& colIndices) : Base(xpr, rowIndices, colIndices) {}
+
+  Index rowIncrement() const {
+    if (traits<Derived>::RowIncr != DynamicIndex && traits<Derived>::RowIncr != UndefinedIncr) {
+      return traits<Derived>::RowIncr;
+    }
+    return get_runtime_incr(this->rowIndices());
+  }
+  Index colIncrement() const {
+    if (traits<Derived>::ColIncr != DynamicIndex && traits<Derived>::ColIncr != UndefinedIncr) {
+      return traits<Derived>::ColIncr;
+    }
+    return get_runtime_incr(this->colIndices());
+  }
+
+  Index innerIncrement() const { return traits<Derived>::IsRowMajor ? colIncrement() : rowIncrement(); }
+
+  Index outerIncrement() const { return traits<Derived>::IsRowMajor ? rowIncrement() : colIncrement(); }
+
+  std::decay_t<typename XprType::Scalar>* data() {
+    Index row_offset = this->rowIndices()[0] * this->nestedExpression().rowStride();
+    Index col_offset = this->colIndices()[0] * this->nestedExpression().colStride();
+    return this->nestedExpression().data() + row_offset + col_offset;
+  }
+
+  const std::decay_t<typename XprType::Scalar>* data() const {
+    Index row_offset = this->rowIndices()[0] * this->nestedExpression().rowStride();
+    Index col_offset = this->colIndices()[0] * this->nestedExpression().colStride();
+    return this->nestedExpression().data() + row_offset + col_offset;
+  }
+
+  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const EIGEN_NOEXCEPT {
+    if (traits<Derived>::InnerStrideAtCompileTime != Dynamic) {
+      return traits<Derived>::InnerStrideAtCompileTime;
+    }
+    return innerIncrement() * this->nestedExpression().innerStride();
+  }
+
+  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const EIGEN_NOEXCEPT {
+    if (traits<Derived>::OuterStrideAtCompileTime != Dynamic) {
+      return traits<Derived>::OuterStrideAtCompileTime;
+    }
+    return outerIncrement() * this->nestedExpression().outerStride();
+  }
+};
 
 template <typename ArgType, typename RowIndices, typename ColIndices>
 struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased>
diff --git a/Eigen/src/Core/util/IndexedViewHelper.h b/Eigen/src/Core/util/IndexedViewHelper.h
index 3b45108..00018a9 100644
--- a/Eigen/src/Core/util/IndexedViewHelper.h
+++ b/Eigen/src/Core/util/IndexedViewHelper.h
@@ -67,6 +67,11 @@
   enum { value = UndefinedIncr };
 };
 
+template <typename T>
+constexpr Index get_runtime_incr(const T&) EIGEN_NOEXCEPT {
+  return Index(1);
+};
+
 // Analogue of std::get<0>(x), but tailored for our needs.
 template <typename T>
 EIGEN_CONSTEXPR Index first(const T& x) EIGEN_NOEXCEPT {
diff --git a/test/indexed_view.cpp b/test/indexed_view.cpp
index 4040448..d3cf4a6 100644
--- a/test/indexed_view.cpp
+++ b/test/indexed_view.cpp
@@ -498,12 +498,39 @@
     // A(1, seq(0,2,1)).cwiseAbs().colwise().replicate(2).eval();
     STATIC_CHECK(((internal::evaluator<decltype(A(1, seq(0, 2, 1)))>::Flags & RowMajorBit) == RowMajorBit));
   }
+
+  // Direct access.
+  {
+    int rows = 3;
+    int row_start = internal::random<int>(0, rows - 1);
+    int row_inc = internal::random<int>(1, rows - row_start);
+    int row_size = internal::random<int>(1, (rows - row_start) / row_inc);
+    auto row_seq = seqN(row_start, row_size, row_inc);
+
+    int cols = 3;
+    int col_start = internal::random<int>(0, cols - 1);
+    int col_inc = internal::random<int>(1, cols - col_start);
+    int col_size = internal::random<int>(1, (cols - col_start) / col_inc);
+    auto col_seq = seqN(col_start, col_size, col_inc);
+
+    MatrixXd m1 = MatrixXd::Random(rows, cols);
+    MatrixXd m2 = MatrixXd::Random(cols, rows);
+    VERIFY_IS_APPROX(m1(row_seq, indexing::all) * m2, m1(row_seq, indexing::all).eval() * m2);
+    VERIFY_IS_APPROX(m1 * m2(indexing::all, col_seq), m1 * m2(indexing::all, col_seq).eval());
+    VERIFY_IS_APPROX(m1(row_seq, col_seq) * m2(col_seq, row_seq),
+                     m1(row_seq, col_seq).eval() * m2(col_seq, row_seq).eval());
+
+    VectorXd v1 = VectorXd::Random(cols);
+    VERIFY_IS_APPROX(m1(row_seq, col_seq) * v1(col_seq), m1(row_seq, col_seq).eval() * v1(col_seq).eval());
+    VERIFY_IS_APPROX(v1(col_seq).transpose() * m2(col_seq, row_seq),
+                     v1(col_seq).transpose().eval() * m2(col_seq, row_seq).eval());
+  }
 }
 
 EIGEN_DECLARE_TEST(indexed_view) {
-  //   for(int i = 0; i < g_repeat; i++) {
-  CALL_SUBTEST_1(check_indexed_view());
-  //   }
+  for (int i = 0; i < g_repeat; i++) {
+    CALL_SUBTEST_1(check_indexed_view());
+  }
 
   // static checks of some internals:
   STATIC_CHECK((internal::is_valid_index_type<int>::value));