diff mbox

[ARM,PR69194] Fix ICE in in extract_insn

Message ID 568FA675.9050405@linaro.org
State New
Headers show

Commit Message

Kugan Vivekanandarajah Jan. 8, 2016, 12:07 p.m. UTC
neon_vld1<mode> pattern does not accept eliminable registers and due to
this, testcase in PR ICE. The problem is in arm_expand_neon_args, in the
NEON_ARG_MEMORY case, where it call force_reg.  Since an eliminable reg
is already a reg, it just returns that value, and we get the wrong
result.  It needs to call copy_to_mode_reg instead, like
arm_expand_binop_builtin does. Attached patch does this. Regression
tested on arm-none-linux-gnu with no new regression. Is this OK for trunk?

Thanks,
Kugan

gcc/ChangeLog:

2016-01-08  Kugan Vivekanandarajah  <kuganv@linaro.org>
	    Jim Wilson  <jim.wilson@linaro.org>

	PR target/69194
	* config/arm/arm-builtins.c (arm_expand_neon_args): Call
	 copy_to_mode_reg instead of force_reg.

gcc/testsuite/ChangeLog:

2016-01-08  Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR target/69194
	* gcc.target/arm/pr69194.C: New test.

Comments

Jim Wilson Jan. 8, 2016, 7:43 p.m. UTC | #1
Here is a smaller simpler testcase.  Only the first four args get
passed in regs, so the fifth one has address equal to the virtual
incoming args reg which triggers the failure.

typedef __simd128_float32_t float32x4_t;
float32x4_t
sub (float32x4_t a, float32x4_t b, float32x4_t c, float32x4_t d, float32x4_t e)
{
  return __builtin_neon_vld1v4sf((const float *)&e);
}

The original testcase failed with linaro gcc 4.9.  I verified that
this testcase fails with FSF gcc-5.3.0.

Jim
diff mbox

Patch

diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 11cd17d..40dd620 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -2146,7 +2146,7 @@  constant_arg:
 	      if (!(*insn_data[icode].operand[opno].predicate)
                    (op[argc], mode[argc]))
 		op[argc] = (replace_equiv_address
-			    (op[argc], force_reg (Pmode, XEXP (op[argc], 0))));
+			    (op[argc], copy_to_mode_reg (Pmode, XEXP (op[argc], 0))));
               break;
 
 	    case NEON_ARG_STOP:
diff --git a/gcc/testsuite/gcc.target/arm/pr69194.C b/gcc/testsuite/gcc.target/arm/pr69194.C
index e69de29..b78fb5b 100644
--- a/gcc/testsuite/gcc.target/arm/pr69194.C
+++ b/gcc/testsuite/gcc.target/arm/pr69194.C
@@ -0,0 +1,504 @@ 
+
+/* { dg-do-compile } */
+/* { dg-require-effective-target arm_neon } */
+/* { dg-options "-O2 -mfpu=neon -S  -Wno-deprecated-declarations" } */
+
+namespace std {
+    typedef int size_t;
+    typedef int ptrdiff_t;
+    template <typename _Tp> _Tp *__addressof(_Tp &__r) { return &__r; }
+    template <typename _Tp, size_t _Nm> struct __array_traits {
+	typedef _Tp _Type[_Nm];
+	static _Tp &_S_ref(_Type __t, size_t __n) { return __t[__n]; }
+    };
+    template <typename _Tp, size_t _Nm> struct array {
+	typedef _Tp *pointer;
+	typedef __array_traits<_Tp, _Nm> _AT_Type;
+	typename _AT_Type::_Type _M_elems;
+	pointer data() { return __addressof(_AT_Type::_S_ref(_M_elems, 0)); }
+    };
+    template <typename> class complex;
+    template <> struct complex<float> {
+	typedef float _ComplexT;
+	complex(_ComplexT);
+	_ComplexT _M_value;
+    };
+}
+
+typedef __simd128_float32_t float32x4_t;
+namespace Eigen {
+    const int Dynamic = -1;
+    void vld1q_f32(const float *__a) { __builtin_neon_vld1v4sf(__a); }
+    const int EvalBeforeNestingBit = 2;
+    const int NestByRefBit = 6;
+    enum { Unaligned };
+    enum {
+	DefaultTraversal,
+	SliceVectorizedTraversal,
+	InvalidTraversal,
+	NoUnrolling,
+	ColMajor
+    };
+    enum { ReadOnlyAccessors, WriteAccessors };
+    struct Dense;
+    namespace internal {
+	template <typename> struct traits;
+	template <typename T> struct traits<const T> : traits<T> {};
+	template <typename> struct accessors_level {
+	    enum { has_write_access, value };
+	};
+    }
+    template <typename> struct EigenBase;
+    template <typename> class DenseBase;
+    template <typename Derived, int = internal::accessors_level<Derived>::value>
+      class DenseCoeffsBase;
+    template <typename, int _Rows, int _Cols, int = ColMajor, int = _Rows,
+	     int = _Cols>
+	       class Matrix;
+    template <typename> class MatrixBase;
+    template <typename, typename> class CwiseUnaryOp;
+    template <typename, typename, int> class CoeffBasedProduct;
+    template <typename, int = ReadOnlyAccessors> class MapBase;
+    template <int, int> class Stride;
+    template <typename, int = Unaligned, typename = Stride<0, 0>> class Map;
+    template <typename> class ArrayWrapper;
+    namespace internal {
+	template <typename, typename> struct product_type;
+    }
+    template <typename Lhs, typename Rhs,
+	     int = internal::product_type<Lhs, Rhs>::value>
+	       struct ProductReturnType;
+    namespace internal {
+	template <bool, typename Then, typename> struct conditional {
+	    typedef Then type;
+	};
+	template <typename Then, typename Else> struct conditional<false, Then, Else> {
+	    typedef Else type;
+	};
+	template <typename, typename> struct is_same {
+	    enum { value = 1 };
+	};
+	template <typename T> struct remove_all { typedef T type; };
+	template <typename T> struct remove_all<T &> {
+	    typedef typename remove_all<T>::type type;
+	};
+	template <typename T> struct add_const_on_value_type { typedef T type; };
+	template <typename T, typename> struct scalar_product_traits {
+	    typedef T ReturnType;
+	};
+    }
+    typedef std::ptrdiff_t DenseIndex;
+    namespace internal {
+	class no_assignment_operator {};
+	template <typename I1, typename I2> struct promote_index_type {
+	    typedef typename conditional<sizeof(I2), I2, I1>::type type;
+	};
+	template <typename T, int> class variable_if_dynamic {
+	public:
+	  variable_if_dynamic(T) {}
+	};
+	template <typename> struct packet_traits;
+	template <typename> struct unpacket_traits;
+	template <typename, int, int, int, int, int> class compute_matrix_flags {
+	public:
+	  enum { ret };
+	};
+	template <typename T> struct plain_matrix_type {
+	    typedef Matrix<typename traits<T>::Scalar, traits<T>::MaxRowsAtCompileTime,
+		    traits<T>::MaxColsAtCompileTime> type;
+	};
+	template <typename T> struct eval {
+	    typedef typename plain_matrix_type<T>::type type;
+	};
+	template <typename T> struct ref_selector {
+	    typedef typename conditional<NestByRefBit, T const &, T>::type type;
+	};
+	template <typename T, int = 1, typename PlainObject = typename eval<T>::type>
+	  struct nested {
+	      typedef typename conditional<traits<T>::Flags, PlainObject,
+		      typename ref_selector<T>::type>::type type;
+	  };
+	template <typename Derived> struct dense_xpr_base {
+	    typedef MatrixBase<Derived> type;
+	};
+	template <typename, typename, typename, typename BaseType>
+	  struct special_scalar_op_base : BaseType {};
+	template <typename> struct is_lvalue {
+	    enum { value };
+	};
+    }
+    template <typename T> struct GenericNumTraits {
+	enum { ReadCost, AddCost };
+	typedef T Real;
+    };
+    template <typename T> struct NumTraits : GenericNumTraits<T> {};
+    namespace internal {
+	template <typename Packet>
+	  Packet ploadu(const typename unpacket_traits<Packet>::type *);
+	template <typename Packet, int>
+	  Packet ploadt(typename unpacket_traits<Packet>::type *from) {
+	      ploadu<Packet>(from);
+	  }
+	typedef float32x4_t Packet4f;
+	template <> struct packet_traits<float> { typedef Packet4f type; };
+	template <> struct unpacket_traits<Packet4f> { typedef float type; };
+	template <> Packet4f ploadu(const float *from) { vld1q_f32(from); }
+	struct Packet2cf {};
+	template <> struct packet_traits<std::complex<float>> {
+	    typedef Packet2cf type;
+	    enum { AlignedOnScalar, size };
+	};
+	template <> struct unpacket_traits<Packet2cf> {
+	    typedef std::complex<float> type;
+	};
+	template <> Packet2cf ploadu(const std::complex<float> *from) {
+	    ploadu<Packet4f>((float *)from);
+	}
+	template <typename> struct scalar_pow_op;
+    }
+    template <typename Derived>
+      class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
+      };
+    template <typename Derived>
+      class DenseCoeffsBase<Derived, WriteAccessors>
+      : public DenseCoeffsBase<Derived, ReadOnlyAccessors> {
+      public:
+	typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
+	typedef typename internal::traits<Derived>::Index Index;
+	Base::derived;
+	template <typename OtherDerived, int StoreMode, int LoadMode>
+	  void copyPacket(Index row, Index col, const DenseBase<OtherDerived> &other) {
+	      derived().template writePacket<StoreMode>(
+							row, col, other.derived().template packet<LoadMode>(row, col));
+	  }
+	template <typename OtherDerived, int StoreMode, int LoadMode>
+	  void copyPacketByOuterInner(Index, Index inner,
+				      const DenseBase<OtherDerived> &other) {
+	      Index row;
+	      Index col;
+	      copyPacket<OtherDerived, StoreMode, LoadMode>(row, col, other);
+	  }
+      };
+    template <typename Derived>
+      class DenseBase
+      : public internal::special_scalar_op_base<
+	Derived, typename internal::traits<Derived>::Scalar,
+	typename NumTraits<typename internal::traits<Derived>::Scalar>::Real,
+	DenseCoeffsBase<Derived>> {
+	public:
+	  typedef typename internal::traits<Derived>::Index Index;
+	  typedef typename internal::traits<Derived>::Scalar Scalar;
+	  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
+	  typedef typename NumTraits<Scalar>::Real RealScalar;
+	  typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar,
+		  DenseCoeffsBase<Derived>> Base;
+	  Base::derived;
+	  template <typename OtherDerived>
+	    Derived &lazyAssign(const DenseBase<OtherDerived> &);
+	};
+    template <typename Derived> class MatrixBase : public DenseBase<Derived> {
+    public:
+      typename internal::traits<Derived>;
+      typedef DenseBase<Derived> Base;
+      Base::derived;
+      template <typename OtherDerived>
+	const typename ProductReturnType<Derived, OtherDerived>::Type
+	operator*(const MatrixBase<OtherDerived> &) const;
+      ArrayWrapper<Derived> array() const { return derived(); }
+    };
+    template <typename Derived> struct EigenBase {
+	Derived derived();
+	const Derived &derived() const { return *static_cast<const Derived *>(this); }
+    };
+    namespace internal {
+	template <typename, typename> struct assign_traits {
+	    enum { DstIsAligned, SrcIsAligned };
+	    enum { MayInnerVectorize = SrcIsAligned, MaySliceVectorize };
+	    enum {
+		Traversal = MayInnerVectorize ?: MaySliceVectorize ?: DefaultTraversal,
+		Unrolling = DefaultTraversal ?: NoUnrolling
+	    };
+	};
+	template <typename Derived1, typename Derived2, int,
+		 int = assign_traits<Derived1, Derived2>::Unrolling>
+		   struct assign_impl;
+	template <typename Derived1, typename Derived2, int Version>
+	  struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, Version> {
+	      typedef typename Derived1::Index Index;
+	      static void run(Derived1 dst, Derived2 src) {
+		  typedef typename Derived1::Scalar Scalar;
+		  typedef packet_traits<Scalar> PacketTraits;
+		  enum {
+		      packetSize = PacketTraits::size,
+		      alignable = PacketTraits::AlignedOnScalar,
+		      dstAlignment
+		  };
+		  for (Index outer;;)
+		    for (Index inner;;)
+		      dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(
+											     outer, inner, src);
+	      }
+	  };
+    }
+    template <typename Derived>
+      template <typename OtherDerived>
+      Derived &DenseBase<Derived>::lazyAssign(const DenseBase<OtherDerived> &other) {
+	  enum { SameType = internal::is_same<Scalar, Scalar>::value };
+	  internal::assign_impl < Derived, OtherDerived,
+	    SameType ? internal::assign_traits<Derived, OtherDerived>::Traversal
+	      : InvalidTraversal > ::run(derived(), other.derived());
+      }
+    namespace internal {
+	template <typename, typename, bool = 0> struct assign_selector;
+	template <typename Derived, typename OtherDerived>
+	  struct assign_selector<Derived, OtherDerived> {
+	      static Derived run(Derived dst, OtherDerived other) { dst.lazyAssign(other); }
+	  };
+    }
+    template <typename Derived>
+      class PlainObjectBase : public internal::dense_xpr_base<Derived>::type {
+      public:
+	typedef typename internal::traits<Derived>::Index Index;
+	typedef typename internal::traits<Derived>::Scalar Scalar;
+	typedef typename internal::packet_traits<Scalar>::type PacketScalar;
+	Scalar coeff(Index, Index) const;
+	template <int> void writePacket(Index, Index, PacketScalar);
+	template <typename OtherDerived>
+	  Derived _set_noalias(const DenseBase<OtherDerived> &other) {
+	      internal::assign_selector<Derived, OtherDerived>::run(this->derived(),
+								    other.derived());
+	  }
+      };
+    namespace internal {
+	template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
+		 int _MaxCols>
+		   struct traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>> {
+		       typedef _Scalar Scalar;
+		       typedef Dense StorageKind;
+		       typedef DenseIndex Index;
+		       enum {
+			   RowsAtCompileTime,
+			   ColsAtCompileTime,
+			   MaxRowsAtCompileTime = _MaxRows,
+			   MaxColsAtCompileTime,
+			   Flags = compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows,
+			   _MaxCols>::ret,
+			   CoeffReadCost = NumTraits<Scalar>::ReadCost
+		       };
+		   };
+    }
+    template <typename _Scalar, int _Rows, int, int, int, int _MaxCols>
+      class Matrix : public PlainObjectBase<Matrix<_Scalar, _Rows, _MaxCols>> {
+      public:
+	typedef PlainObjectBase<Matrix> Base;
+	enum {
+	    RowsAtCompileTime = Eigen::internal::traits<Matrix>::RowsAtCompileTime,
+	    ColsAtCompileTime = Eigen::internal::traits<Matrix>::ColsAtCompileTime,
+	    MaxRowsAtCompileTime =
+	      Eigen::internal::traits<Matrix>::MaxRowsAtCompileTime,
+	    MaxColsAtCompileTime =
+	      Eigen::internal::traits<Matrix>::MaxColsAtCompileTime,
+	    Flags = Eigen::internal::traits<Matrix>::Flags,
+	    CoeffReadCost = Eigen::internal::traits<Matrix>::CoeffReadCost
+	};
+	template <typename OtherDerived> Matrix(MatrixBase<OtherDerived> &other) {
+	    Base::_set_noalias(other);
+	}
+	template <typename OtherDerived> Matrix(const EigenBase<OtherDerived>);
+      };
+    namespace internal {
+	template <typename UnaryOp, typename XprType>
+	  struct traits<CwiseUnaryOp<UnaryOp, XprType>> : traits<XprType> {};
+    }
+    template <typename, typename, typename> class CwiseUnaryOpImpl;
+    template <typename UnaryOp, typename XprType>
+      class CwiseUnaryOp
+      : internal::no_assignment_operator,
+      public CwiseUnaryOpImpl<UnaryOp, XprType,
+      typename internal::traits<XprType>::StorageKind> {
+      };
+    template <typename UnaryOp, typename XprType>
+      class CwiseUnaryOpImpl<UnaryOp, XprType, Dense>
+      : public internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType>>::type {};
+    template <typename Derived>
+      class MapBase<Derived> : public internal::dense_xpr_base<Derived>::type {
+      public:
+	typename internal::dense_xpr_base<Derived>;
+	enum {
+	    RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
+	    ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime
+	};
+	typedef typename internal::traits<Derived>::Index Index;
+	typedef typename internal::traits<Derived>::Scalar Scalar;
+	typedef typename internal::packet_traits<Scalar>::type PacketScalar;
+	typedef typename internal::conditional<internal::is_lvalue<Derived>::value,
+		Scalar, Scalar *>::type PointerType;
+	template <int LoadMode> PacketScalar packet(Index, Index) const {
+	    internal::ploadt<PacketScalar, LoadMode>(m_data);
+	}
+	MapBase(PointerType dataPtr)
+	  : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {}
+	PointerType m_data;
+	internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
+	internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
+      };
+    namespace internal {
+	template <typename PlainObjectType, int MapOptions, typename StrideType>
+	  struct traits<Map<PlainObjectType, MapOptions, StrideType>>
+	  : traits<PlainObjectType> {};
+    }
+    template <typename PlainObjectType, int, typename>
+      class Map : public MapBase<Map<PlainObjectType>> {
+      public:
+	typedef MapBase<Map> Base;
+	enum {
+	    RowsAtCompileTime = Eigen::internal::traits<Map>::RowsAtCompileTime,
+	    ColsAtCompileTime = Eigen::internal::traits<Map>::ColsAtCompileTime,
+	    MaxRowsAtCompileTime = Eigen::internal::traits<Map>::MaxRowsAtCompileTime,
+	    MaxColsAtCompileTime = Eigen::internal::traits<Map>::MaxColsAtCompileTime,
+	    Flags = Eigen::internal::traits<Map>::Flags,
+	    CoeffReadCost = Eigen::internal::traits<Map>::CoeffReadCost
+	};
+	typedef typename Base::PointerType PointerArgType;
+	Map(PointerArgType dataPtr) : Base(dataPtr) {}
+      };
+    enum { Large, Small };
+    namespace internal {
+	template <int, int, int> struct product_type_selector;
+	template <int, int MaxSize> struct product_size_category {
+	    enum { is_large = MaxSize == Dynamic, value = is_large ? Large : 1 ?: Small };
+	};
+	template <typename Lhs, typename Rhs> struct product_type {
+	    typedef typename remove_all<Lhs>::type _Lhs;
+	    typedef typename remove_all<Rhs>::type _Rhs;
+	    enum {
+		MaxRows = _Lhs::MaxRowsAtCompileTime,
+		Rows = _Lhs::RowsAtCompileTime,
+		MaxCols = _Rhs::MaxColsAtCompileTime,
+		Cols = _Rhs::ColsAtCompileTime,
+		MaxDepth = _Lhs::MaxColsAtCompileTime <= _Rhs::MaxRowsAtCompileTime
+		  ?: _Rhs::MaxRowsAtCompileTime,
+		Depth = _Lhs::ColsAtCompileTime <= _Rhs::RowsAtCompileTime
+		  ?: _Rhs::RowsAtCompileTime
+	    };
+	    enum {
+		rows_select = product_size_category<Rows, MaxRows>::value,
+		cols_select = product_size_category<Cols, MaxCols>::value,
+		depth_select = product_size_category<Depth, MaxDepth>::value
+	    };
+	    typedef product_type_selector<rows_select, cols_select, depth_select>
+	      selector;
+	    enum { value = selector::ret };
+	};
+	template <> struct product_type_selector<Large, 1, Small> {
+	    enum { ret };
+	};
+    }
+    template <typename Lhs, typename Rhs, int> struct ProductReturnType {
+	typedef typename internal::nested<Lhs, Rhs::ColsAtCompileTime>::type
+	  LhsNested;
+	typedef typename internal::nested<Rhs, Lhs::RowsAtCompileTime>::type
+	  RhsNested;
+	typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeNestingBit> Type;
+    };
+    template <typename Derived>
+      template <typename OtherDerived>
+      const typename ProductReturnType<Derived, OtherDerived>::Type
+      MatrixBase<Derived>::
+      operator*(const MatrixBase<OtherDerived> &other) const {
+	  return typename ProductReturnType<Derived, OtherDerived>::Type(
+									 derived(), other.derived());
+      }
+    namespace internal {
+	template <int, int, typename, typename, typename, int>
+	  struct product_packet_impl;
+	template <typename LhsNested, typename RhsNested, int NestingFlags>
+	  struct traits<CoeffBasedProduct<LhsNested, RhsNested, NestingFlags>> {
+	      typedef typename remove_all<LhsNested>::type _LhsNested;
+	      typedef typename remove_all<RhsNested>::type _RhsNested;
+	      typedef typename scalar_product_traits<
+		typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType
+		Scalar;
+	      typedef typename promote_index_type<typename traits<_LhsNested>::Index,
+		      typename traits<_RhsNested>::Index>::type
+			Index;
+	      enum {
+		  LhsFlags = _LhsNested::Flags,
+		  RhsFlags = _RhsNested::Flags,
+		  RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
+		  ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
+		  InnerSize = _LhsNested::RowsAtCompileTime,
+		  MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
+		  MaxColsAtCompileTime = is_same<Scalar, Scalar>::value,
+		  CanVectorizeLhs = packet_traits<Scalar>::size,
+		  Flags,
+		  CoeffReadCost = NumTraits<Scalar>::AddCost
+	      };
+	  };
+    }
+    template <typename LhsNested, typename RhsNested, int NestingFlags>
+      class CoeffBasedProduct
+      : internal::no_assignment_operator,
+      public MatrixBase<CoeffBasedProduct<LhsNested, RhsNested, NestingFlags>> {
+      public:
+	typedef MatrixBase<CoeffBasedProduct> Base;
+	typedef typename Base::PacketScalar PacketScalar;
+	typedef typename Eigen::internal::nested<CoeffBasedProduct>::type Nested;
+	typedef typename Eigen::internal::traits<CoeffBasedProduct>::Index Index;
+	typedef typename internal::traits<CoeffBasedProduct>::_LhsNested _LhsNested;
+	typedef typename internal::traits<CoeffBasedProduct>::_RhsNested _RhsNested;
+	template <typename Lhs, typename Rhs>
+	  CoeffBasedProduct(Lhs lhs, Rhs &rhs)
+	  : m_lhs(lhs), m_rhs(rhs) {}
+	template <int LoadMode> PacketScalar packet(Index row, Index col) const {
+	    PacketScalar res;
+	    internal::product_packet_impl<ColMajor, Dynamic, _LhsNested, _RhsNested,
+	      PacketScalar, LoadMode>::run(row, col, m_lhs,
+					   m_rhs, res);
+	}
+	typename internal::add_const_on_value_type<LhsNested>::type m_lhs;
+	typename internal::add_const_on_value_type<RhsNested>::type m_rhs;
+      };
+    namespace internal {
+	template <int UnrollingIndex, typename Lhs, typename Rhs, typename Packet,
+		 int LoadMode>
+		   struct product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet,
+		 LoadMode> {
+		     typedef typename Lhs::Index Index;
+		     static void run(Index row, Index col, Lhs lhs, Rhs rhs, Packet) {
+			 lhs.coeff(row, 0), rhs.template packet<LoadMode>(0, col);
+		     }
+		 };
+    }
+    template <typename Derived> class ArrayBase : public DenseBase<Derived> {
+    public:
+      typedef typename internal::traits<Derived>::Scalar Scalar;
+      CwiseUnaryOp<internal::scalar_pow_op<Scalar>, Derived> pow(Scalar);
+    };
+    namespace internal {
+	template <typename ExpressionType>
+	  struct traits<ArrayWrapper<ExpressionType>>
+	  : traits<typename remove_all<typename ExpressionType::Nested>::type> {};
+    }
+    template <typename ExpressionType>
+      class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType>> {
+      public:
+	typedef typename internal::nested<ExpressionType>::type NestedExpressionType;
+	ArrayWrapper(ExpressionType matrix) : m_expression(matrix) {}
+	NestedExpressionType m_expression;
+      };
+}
+
+struct crashes {
+    int x;
+    int y;
+};
+using Scalar = std::complex<float>;
+using Points = std::array<Scalar, 4>;
+using Table = Eigen::Matrix<Scalar, Eigen::Dynamic, 4>;
+using Vec = Eigen::Matrix<float, Eigen::Dynamic, 1>;
+crashes do_crash(Table cal, Points p) {
+    using map_t = Eigen::Map<Eigen::Matrix<Scalar, 4, 1>>;
+    map_t points_mat(p.data());
+    Vec top = (cal * points_mat).array().pow(2);
+}