]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/testsuite/g++.dg/pr112822.C
9949fbb08acff80dfc8da6bbe431c41c31c65af2
[thirdparty/gcc.git] / gcc / testsuite / g++.dg / pr112822.C
1 /* PR tree-optimization/112822 */
2 /* { dg-do compile { target c++17 } } */
3 /* { dg-options "-w -O2" } */
4 // { dg-do compile { target c++17 } }
5
6 /* Verify we do not ICE on the following noisy creduced test case. */
7
8 namespace b {
9 typedef int c;
10 template <bool, typename> struct d;
11 template <typename e> struct d<true, e> { using f = e; };
12 template <bool, typename, typename> struct aa;
13 template <typename g, typename h> struct aa<false, g, h> { using f = h; };
14 template <bool l, typename e> using ab = typename d<l, e>::f;
15 template <bool l, typename g, typename h> using n = typename aa<l, g, h>::f;
16 template <typename> class af {
17 public:
18 typedef __complex__ ah;
19 template <typename e> af operator+=(e) {
20 ah o;
21 x = o;
22 return *this;
23 }
24 ah x;
25 };
26 } // namespace b
27 namespace {
28 enum { p };
29 enum { ac, ad };
30 struct ae;
31 struct al;
32 struct ag;
33 typedef b::c an;
34 namespace ai {
35 template <typename aj> struct ak { typedef aj f; };
36 template <typename aj> using ar = typename ak<aj>::f;
37 template <typename> struct am {
38 enum { at };
39 };
40 template <typename, typename> struct ao {
41 enum { at };
42 };
43 template <typename> struct ap;
44 template <typename> struct aq {
45 enum { at };
46 };
47 } // namespace ai
48 template <typename> struct ay;
49 template <typename> class as;
50 template <typename, int> class ba;
51 template <typename, int au, int av, int = 0, int = au, int = av> class aw;
52 template <typename> class be;
53 template <typename, typename, int> class az;
54 namespace ai {
55 template <typename, typename> struct bg;
56 template <typename aj, int = bg<typename aj::bb, typename aj::bc>::bd>
57 struct bk;
58 template <typename, typename> struct bf;
59 template <typename> struct bm;
60 template <typename> struct bh;
61 template <int, typename bi, bool = ao<bi, typename bh<bi>::bj>::at> struct bp {
62 typedef bi f;
63 };
64 template <typename aj, int bl> struct br {
65 typedef typename bp<bl, typename bm<aj>::f>::f f;
66 };
67 template <typename, typename, int> struct bn;
68 template <typename aj, int bo> struct bn<aj, al, bo> {
69 typedef aw<typename aj ::bu, aj ::bv, aj ::bq> f;
70 };
71 template <typename aj> struct bx {
72 typedef typename bn<aj, typename ap<aj>::bs, aj ::bo>::f f;
73 };
74 template <typename aj> struct bt { typedef b::n<0, aj, aj> f; };
75 template <typename aj, int, typename ca = typename bx<aj>::f> struct cb {
76 enum { bw };
77 typedef b::n<bw, ca, typename bt<aj>::f> f;
78 };
79 template <typename cd, typename = typename ap<cd>::bs> struct by {
80 typedef be<cd> f;
81 };
82 template <typename cd, typename bs> struct bz {
83 typedef typename by<cd, bs>::f f;
84 };
85 template <typename, typename, int> struct ch;
86 template <typename ci, int cc> struct ch<ci, ci, cc> { typedef ci bd; };
87 } // namespace ai
88 template <typename ck, typename ce, typename = ai::bf<ck, ce>> struct cg;
89 template <typename aj, typename cm> struct cg<aj, cm> { typedef aj cn; };
90 namespace ai {
91 template <typename cj, int> cj cp;
92 template <typename bu, typename cj, int> void cl(bu *cr, cj cs) { ct(cr, cs); }
93 typedef __attribute__((altivec(vector__))) double co;
94 void ct(double *cr, co cs) { *(co *)cr = cs; }
95 struct cq {
96 co q;
97 };
98 template <> struct bm<b::af<double>> { typedef cq f; };
99 template <> struct bh<cq> { typedef cq bj; };
100 void ct(b::af<double> *cr, cq cs) { ct((double *)cr, cs.q); }
101 template <typename cw, typename> struct cx {
102 template <int cy, typename cj> void cu(cw *a, cj) {
103 cl<cw, cj, cy>(a, cp<cj, cy>);
104 }
105 };
106 } // namespace ai
107 template <typename cd> class ba<cd, ac> : public ay<cd> {
108 public:
109 typedef ai::ap<cd> bu;
110 typedef b::n<ai::ap<cd>::bo, bu, b::n<ai::am<bu>::at, bu, bu>> cv;
111 typedef ay<cd> db;
112 db::dc;
113 cv coeff(an dd, an col) const { return dc().coeff(dd, col); }
114 };
115 template <typename cd> class cz : public ba<cd, ai::aq<cd>::at> {
116 public:
117 ai::ap<cd> b;
118 enum { da, dg, dh, bv, bq, di = dg, bo };
119 };
120 template <typename cd> class be : public cz<cd> {
121 public:
122 typedef typename ai::ap<cd>::bu bu;
123 typedef cz<cd> db;
124 db::dc;
125 template <typename de> cd &operator+=(const be<de> &);
126 template <typename de> az<cd, de, ad> df(de);
127 };
128 template <typename cd> struct ay {
129 cd &dc() { return *static_cast<cd *>(this); }
130 cd dc() const;
131 };
132 template <typename, typename, int, typename> class dl;
133 namespace ai {
134 template <typename bb, typename bc, int dm> struct ap<az<bb, bc, dm>> {
135 typedef bb dj;
136 typedef bc r;
137 typedef ap<dj> s;
138 typedef ap<r> t;
139 typedef typename cg<typename dj ::bu, typename r ::bu>::cn bu;
140 typedef typename ch<typename s::cf, typename t::cf, bg<bb, bc>::bd>::bd cf;
141 enum { bo };
142 };
143 } // namespace ai
144 template <typename dk, typename Rhs_, int dm>
145 class az : public dl<dk, Rhs_, dm,
146 ai::ch<ai::ap<dk>, ai::ap<Rhs_>, ai::bg<dk, Rhs_>::bd>> {
147 public:
148 typedef dk bb;
149 typedef Rhs_ bc;
150 typedef typename ai::bt<bb>::f LhsNested;
151 typedef typename ai::bt<bc>::f dn;
152 typedef ai::ar<LhsNested> u;
153 typedef ai::ar<dn> RhsNestedCleaned;
154 u lhs();
155 RhsNestedCleaned rhs();
156 };
157 template <typename bb, typename bc, int dm, typename>
158 class dl : public ai::bz<az<bb, bc, dm>, al>::f {};
159 namespace ai {
160 template <typename> struct v { typedef ag w; };
161 template <typename aj> struct evaluator_traits_base {
162 typedef typename v<typename ap<aj>::cf>::w w;
163 };
164 template <typename aj> struct ax : evaluator_traits_base<aj> {};
165 template <typename> struct y { static const bool at = false; };
166 template <typename bu, int z> class plainobjectbase_evaluator_data {
167 public:
168 plainobjectbase_evaluator_data(bu *ptr, an) : data(ptr) {}
169 an outerStride() { return z; }
170 bu *data;
171 };
172 template <typename cd> struct evaluator {
173 typedef cd PlainObjectType;
174 typedef typename PlainObjectType::bu bu;
175 enum { IsVectorAtCompileTime };
176 enum { OuterStrideAtCompileTime };
177 evaluator(PlainObjectType &m) : m_d(m.data(), IsVectorAtCompileTime) {}
178 bu &coeffRef(an, an) { return m_d.data[m_d.outerStride()]; }
179 plainobjectbase_evaluator_data<bu, OuterStrideAtCompileTime> m_d;
180 };
181 template <typename bu, int Rows, int Cols, int Options, int MaxRows,
182 int MaxCols>
183 struct evaluator<aw<bu, Rows, Cols, Options, MaxRows, MaxCols>>
184 : evaluator<as<aw<bu, Rows, Cols>>> {
185 typedef aw<bu, Rows, Cols> XprType;
186 evaluator(XprType &m) : evaluator<as<XprType>>(m) {}
187 };
188 template <typename DstEvaluator, typename, typename>
189 struct copy_using_evaluator_traits {
190 typedef typename DstEvaluator::bu cw;
191 enum { RestrictedInnerSize };
192 typedef typename br<cw, RestrictedInnerSize>::f bi;
193 };
194 template <typename Kernel, an, int>
195 struct copy_using_evaluator_innervec_CompleteUnrolling {
196 typedef typename Kernel::bi bi;
197 enum { outer, inner, SrcAlignment, DstAlignment };
198 static void run(Kernel kernel) {
199 kernel.template assignPacketByOuterInner<DstAlignment, SrcAlignment, bi>(
200 outer, inner);
201 }
202 };
203 template <typename Kernel> struct dense_assignment_loop {
204 static void run(Kernel kernel) {
205 typedef typename Kernel::DstEvaluatorType::XprType DstXprType;
206 copy_using_evaluator_innervec_CompleteUnrolling<
207 Kernel, 0, DstXprType::dh>::run(kernel);
208 }
209 };
210 template <typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT,
211 typename Functor>
212 class generic_dense_assignment_kernel {
213 typedef typename DstEvaluatorTypeT::XprType DstXprType;
214
215 public:
216 typedef DstEvaluatorTypeT DstEvaluatorType;
217 typedef SrcEvaluatorTypeT SrcEvaluatorType;
218 typedef copy_using_evaluator_traits<DstEvaluatorTypeT, SrcEvaluatorTypeT,
219 Functor>
220 AssignmentTraits;
221 typedef typename AssignmentTraits::bi bi;
222 generic_dense_assignment_kernel(DstEvaluatorType dst, SrcEvaluatorType src,
223 Functor, DstXprType dstExpr)
224 : m_dst(dst), m_src(src), m_dstExpr(dstExpr) {}
225 template <int StoreMode, int LoadMode, typename cj> void cu(an dd, an col) {
226 m_functor.template cu<StoreMode>(
227 &m_dst.coeffRef(dd, col), m_src.template packet<LoadMode, cj>(dd, col));
228 }
229 template <int StoreMode, int LoadMode, typename cj>
230 void assignPacketByOuterInner(an, an) {
231 an dd;
232 an col;
233 cu<StoreMode, LoadMode, cj>(dd, col);
234 }
235 DstEvaluatorType m_dst;
236 SrcEvaluatorType &m_src;
237 Functor m_functor;
238 DstXprType m_dstExpr;
239 };
240 template <typename DstXprType, typename SrcXprType, typename Functor>
241 void call_dense_assignment_loop(DstXprType &dst, SrcXprType src, Functor func) {
242 typedef evaluator<DstXprType> DstEvaluatorType;
243 typedef evaluator<SrcXprType> SrcEvaluatorType;
244 SrcEvaluatorType srcEvaluator(src);
245 DstEvaluatorType dstEvaluator(dst);
246 typedef generic_dense_assignment_kernel<DstEvaluatorType, SrcEvaluatorType,
247 Functor>
248 Kernel;
249 Kernel kernel(dstEvaluator, srcEvaluator, func, dst);
250 dense_assignment_loop<Kernel>::run(kernel);
251 }
252 template <typename, typename> struct AssignmentKind;
253 struct Dense2Dense;
254 template <> struct AssignmentKind<ag, ag> { typedef Dense2Dense Kind; };
255 template <typename DstXprType, typename SrcXprType, typename,
256 typename = typename AssignmentKind<typename ax<DstXprType>::w,
257 typename ax<SrcXprType>::w>::Kind,
258 typename = void>
259 struct Assignment;
260 template <typename Dst, typename Src, typename Func>
261 void call_assignment(Dst &dst, Src src, Func func,
262 b::ab<!y<Src>::at, void *> = 0) {
263 enum { NeedToTranspose };
264 typedef b::n<NeedToTranspose, Dst, Dst> ActualDstTypeCleaned;
265 typedef b::n<NeedToTranspose, Dst, Dst &> ActualDstType;
266 ActualDstType actualDst(dst);
267 Assignment<ActualDstTypeCleaned, Src, Func>::run(actualDst, src, func);
268 }
269 template <typename DstXprType, typename SrcXprType, typename Functor,
270 typename Weak>
271 struct Assignment<DstXprType, SrcXprType, Functor, Weak> {
272 static void run(DstXprType &dst, SrcXprType src, Functor func) {
273 call_dense_assignment_loop(dst, src, func);
274 }
275 };
276 template <typename aj, int bl> struct plain_array { aj array[bl]; };
277 } // namespace ai
278 template <typename aj, int bl, int, int av, int> class DenseStorage {
279 ai::plain_array<aj, bl> m_data;
280
281 public:
282 an cols() { return av; }
283 aj *data() { return m_data.array; }
284 };
285 template <typename cd> class as : public ai::by<cd>::f {
286 public:
287 enum { Options };
288 typedef typename ai::by<cd>::f db;
289 typedef typename ai::ap<cd>::bu bu;
290 DenseStorage<bu, db::di, db::da, db::dg, Options> m_storage;
291 an cols() { return m_storage.cols(); }
292 bu &coeffRef(an, an colId) { return data()[colId]; }
293 bu *data() { return m_storage.data(); }
294 };
295 namespace ai {
296 template <typename Scalar_, int au, int av, int Options_, int MaxRows_,
297 int MaxCols_>
298 struct ap<aw<Scalar_, au, av, Options_, MaxRows_, MaxCols_>> {
299 typedef Scalar_ bu;
300 typedef ae cf;
301 typedef al bs;
302 enum { bo };
303 };
304 } // namespace ai
305 template <typename Scalar_, int au, int, int Options_, int, int>
306 class aw : public as<aw<Scalar_, au, Options_>> {
307 public:
308 template <typename T0, typename T1> aw(T0, T1) {}
309 };
310 template <typename cd>
311 template <typename de>
312 cd &be<cd>::operator+=(const be<de> &other) {
313 call_assignment(dc(), other.dc(), ai::cx<bu, bu>());
314 return dc();
315 }
316 namespace ai {
317 template <typename, typename> struct bg {
318 enum { bd };
319 };
320 template <typename bb, typename bc, int Options>
321 struct evaluator<az<bb, bc, Options>> : bk<az<bb, bc, Options>> {
322 typedef az<bb, bc, Options> XprType;
323 typedef bk<XprType> db;
324 evaluator(XprType xpr) : db(xpr) {}
325 };
326 template <typename bb, typename bc, int cc> struct bk<az<bb, bc, ad>, cc> {
327 typedef az<bb, bc, ad> XprType;
328 bk(XprType xpr)
329 : m_lhs(xpr.lhs()), m_rhs(xpr.rhs()), m_lhsImpl(m_lhs), m_rhsImpl(m_rhs) {
330 }
331 typedef typename cb<bb, bc::dg>::f LhsNested;
332 typedef typename cb<bc, bb::da>::f dn;
333 typedef LhsNested u;
334 typedef dn RhsNestedCleaned;
335 typedef u LhsEtorType;
336 typedef RhsNestedCleaned RhsEtorType;
337 template <int, typename bi> bi packet(an, an);
338 LhsNested m_lhs;
339 dn m_rhs;
340 LhsEtorType m_lhsImpl;
341 RhsEtorType m_rhsImpl;
342 };
343 } // namespace ai
344 } // namespace
345 namespace Eigen {
346 template <typename Type1, typename Type2> bool verifyIsApprox(Type1, Type2);
347 }
348 using namespace Eigen;
349 template <typename TC, typename TA, typename TB> TC ref_prod(TC C, TA, TB B) {
350 for (an i; i;)
351 for (an j = 0; j < C.cols(); ++j)
352 for (an k; k;)
353 C.coeffRef(i, j) += B.coeff(k, j);
354 return C;
355 }
356 template <typename aj, int Rows, int Cols, int Depth, int OC, int OA, int OB>
357 b::ab<!0, void> test_lazy_single(int rows, int cols, int depth) {
358 aw<aj, Depth, OA> ci(rows, depth);
359 aw<aj, Cols, OB> B(depth, cols);
360 aw<aj, Rows, OC> C(rows, cols);
361 aw D(C);
362 verifyIsApprox(C += ci.df(B), ref_prod(D, ci, B));
363 }
364 template <typename aj, int Rows, int Cols, int Depth>
365 void test_lazy_all_layout(int rows = Rows, int cols = Cols, int depth = Depth) {
366 test_lazy_single<aj, Rows, Cols, Depth, p, p, p>(rows, cols, depth);
367 }
368 template <typename aj> void test_lazy_l2() {
369 test_lazy_all_layout<aj, 1, 4, 2>();
370 }
371 void fn1() { test_lazy_l2<b::af<double>>(); }