1// { dg-do compile }
2// { dg-additional-options "-Wno-psabi" }
3// Ignore warning on some powerpc-linux configurations.
4// { dg-prune-output "non-standard ABI extension" }
5
6typedef float __m128 __attribute__ ((__vector_size__ (16)));
7const int a = 0;
8enum
9{
10  ReadOnlyAccessors
11};
12template <typename> struct traits;
13struct A
14{
15  enum
16  {
17    value = 1
18  };
19};
20template <typename> struct EigenBase;
21template <typename> class J;
22template <typename, int = A::value> class DenseCoeffsBase;
23template <typename, int, int, int = 0, int = 0, int = 0> class K;
24template <typename> class N;
25template <typename, typename> class CwiseUnaryOp;
26template <typename> class L;
27template <typename> class P;
28template <typename> struct B;
29template <typename> struct C;
30template <typename Derived> struct dense_xpr_base
31{
32  typedef N<Derived> type;
33};
34template <typename Packet> void padd (Packet);
35template <> struct C<float>
36{
37  typedef __m128 type;
38};
39struct D
40{
41  void
42  packetOp (C<float>::type)
43  {
44    __m128 b = { m_other };
45    padd (b);
46  }
47  float m_other;
48};
49template <typename Derived>
50class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived>
51{
52public:
53  typedef typename C<typename traits<Derived>::Scalar>::type PacketScalar;
54};
55template <typename Derived>
56class DenseCoeffsBase<Derived>
57    : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
58{
59public:
60  template <typename OtherDerived, int, int LoadMode>
61  void
62  copyPacket (typename traits<Derived>::Index, J<OtherDerived> p2)
63  {
64    p2.derived ().template packet<LoadMode> (0);
65  }
66};
67template <typename Derived> class J : public DenseCoeffsBase<Derived>
68{
69public:
70  using DenseCoeffsBase<Derived>::derived;
71  template <typename OtherDerived>
72  Derived &lazyAssign (const J<OtherDerived> &);
73};
74template <typename Derived> class N : public J<Derived>
75{
76public:
77  template <typename OtherDerived>
78  typename B<OtherDerived>::Type operator*(N<OtherDerived>);
79  L<Derived> array ();
80};
81template <typename Derived> struct EigenBase
82{
83  Derived
84  derived () const
85  {
86    return *static_cast<const Derived *> (this);
87  }
88};
89template <typename Derived1, typename Derived2> struct F
90{
91  static void
92  run (Derived1 p1, Derived2 p2)
93  {
94    enum
95    {
96      srcAlignment
97    };
98    for (;;)
99      p1.template copyPacket<Derived2, 0, srcAlignment> (0, p2);
100  }
101};
102template <typename Derived>
103template <typename OtherDerived>
104Derived &
105J<Derived>::lazyAssign (const J<OtherDerived> &p1)
106{
107  F<Derived, OtherDerived>::run (derived (), p1.derived ());
108}
109template <typename Derived, typename OtherDerived> struct G
110{
111  static Derived
112  run (Derived p1, OtherDerived p2)
113  {
114    p1.lazyAssign (p2);
115  }
116};
117class H
118{
119public:
120  H (int, int, int);
121};
122template <typename Derived> class M : public dense_xpr_base<Derived>::type
123{
124public:
125  typedef typename traits<Derived>::Index Index;
126  H m_storage;
127  M (Index, Index, Index) : m_storage (0, 0, 0) {}
128  template <typename OtherDerived>
129  void
130  _set_noalias (J<OtherDerived> p1)
131  {
132    G<Derived, OtherDerived>::run (this->derived (), p1.derived ());
133  }
134};
135template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
136          int _MaxCols>
137struct traits<K<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
138{
139  typedef _Scalar Scalar;
140  typedef int StorageKind;
141  typedef int Index;
142};
143template <typename, int _Rows, int _Cols, int, int, int>
144class K : public M<K<float, _Rows, _Cols> >
145{
146public:
147  typedef M<K> Base;
148  typedef K Nested;
149  template <typename T0, typename T1> K (T0, T1);
150  template <typename OtherDerived> K (N<OtherDerived> p1) : Base (0, 0, 0)
151  {
152    Base::_set_noalias (p1);
153  }
154};
155template <typename UnaryOp, typename XprType>
156struct traits<CwiseUnaryOp<UnaryOp, XprType> > : traits<XprType>
157{
158};
159template <typename, typename, typename> class I;
160template <typename, typename XprType>
161class CwiseUnaryOp
162    : public I<D, XprType, typename traits<XprType>::StorageKind>
163{
164public:
165  D
166  functor ()
167  {
168    return m_functor;
169  }
170  typename XprType::Nested nestedExpression ();
171  D m_functor;
172};
173template <typename UnaryOp, typename XprType>
174class I<UnaryOp, XprType, int>
175    : public dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
176{
177public:
178  typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
179  typedef typename dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
180  typedef Derived Nested;
181  using Base::derived;
182  template <int LoadMode> void packet (typename traits<Derived>::Index)
183  {
184    derived ().functor ().packetOp (
185        derived ().nestedExpression ().template packet<LoadMode> (0));
186  }
187};
188template <typename> struct B
189{
190  typedef P<CwiseUnaryOp<D, L<K<float, 0, 1> > > > Type;
191};
192template <typename Derived> class O : public J<Derived>
193{
194public:
195  P<Derived> matrix ();
196};
197template <typename ExpressionType>
198struct traits<L<ExpressionType> > : traits<typename ExpressionType::Nested>
199{
200};
201template <typename ExpressionType> class L : public O<L<ExpressionType> >
202{
203public:
204  typedef L Nested;
205  template <int>
206  typename O<L>::PacketScalar packet (typename traits<L>::Index);
207};
208template <typename ExpressionType>
209struct traits<P<ExpressionType> > : traits<typename ExpressionType::Nested>
210{
211};
212template <typename ExpressionType> class P : public N<P<ExpressionType> >
213{
214public:
215  N<P> Base;
216  template <int LoadMode> void packet (typename traits<P>::Index)
217  {
218    m_expression.template packet<LoadMode> (0);
219  }
220  ExpressionType m_expression;
221};
222int
223main ()
224{
225  K<float, 0, a> m (0, 0);
226  K<float, 0, 1> c (0, 0);
227  c = m.array ().matrix () * m;
228}
229