1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "unit_test.h"
17 #include "optimizer/optimizations/move_constants.h"
18
19 namespace panda::compiler {
20
21 class MoveConstantsTest : public GraphTest {
22 };
23
TEST_F(MoveConstantsTest,MoveNullPtrToCommonImmediateDominator)24 TEST_F(MoveConstantsTest, MoveNullPtrToCommonImmediateDominator)
25 {
26 GRAPH(GetGraph())
27 {
28 PARAMETER(0, 1).u64();
29 CONSTANT(1, nullptr);
30
31 BASIC_BLOCK(2, 4, 3)
32 {
33 INST(2, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
34 }
35
36 BASIC_BLOCK(3, -1)
37 {
38 INST(3, Opcode::ReturnI).u64().Imm(0);
39 }
40
41 BASIC_BLOCK(4, 6, 5)
42 {
43 INST(4, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
44 }
45
46 BASIC_BLOCK(5, -1)
47 {
48 INST(6, Opcode::Return).ref().Inputs(1);
49 }
50
51 BASIC_BLOCK(6, -1)
52 {
53 INST(8, Opcode::Return).ref().Inputs(1);
54 }
55 }
56 Graph *graph_et = CreateEmptyGraph();
57 GRAPH(graph_et)
58 {
59 PARAMETER(0, 1).u64();
60
61 BASIC_BLOCK(2, 4, 3)
62 {
63 INST(2, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
64 }
65
66 BASIC_BLOCK(3, -1)
67 {
68 INST(3, Opcode::ReturnI).u64().Imm(0);
69 }
70
71 BASIC_BLOCK(4, 6, 5)
72 {
73 CONSTANT(1, nullptr);
74 INST(4, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
75 }
76
77 BASIC_BLOCK(5, -1)
78 {
79 INST(6, Opcode::Return).ref().Inputs(1);
80 }
81
82 BASIC_BLOCK(6, -1)
83 {
84 INST(8, Opcode::Return).ref().Inputs(1);
85 }
86 }
87
88 bool result = GetGraph()->RunPass<MoveConstants>();
89 ASSERT_TRUE(result);
90
91 GraphChecker(GetGraph()).Check();
92 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
93 }
94
TEST_F(MoveConstantsTest,MoveToCommonImmediateDominator)95 TEST_F(MoveConstantsTest, MoveToCommonImmediateDominator)
96 {
97 GRAPH(GetGraph())
98 {
99 PARAMETER(0, 1).u64();
100 CONSTANT(1, 12345);
101
102 BASIC_BLOCK(2, 4, 3)
103 {
104 INST(2, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
105 }
106
107 BASIC_BLOCK(3, -1)
108 {
109 INST(3, Opcode::ReturnI).u64().Imm(0);
110 }
111
112 BASIC_BLOCK(4, 6, 5)
113 {
114 INST(4, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
115 }
116
117 BASIC_BLOCK(5, -1)
118 {
119 INST(5, Opcode::Sub).u64().Inputs(1, 0);
120 INST(6, Opcode::Return).u64().Inputs(5);
121 }
122
123 BASIC_BLOCK(6, -1)
124 {
125 INST(7, Opcode::Add).u64().Inputs(0, 1);
126 INST(8, Opcode::Return).u64().Inputs(7);
127 }
128 }
129 Graph *graph_et = CreateEmptyGraph();
130 GRAPH(graph_et)
131 {
132 PARAMETER(0, 1).u64();
133
134 BASIC_BLOCK(2, 4, 3)
135 {
136 INST(2, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
137 }
138
139 BASIC_BLOCK(3, -1)
140 {
141 INST(3, Opcode::ReturnI).u64().Imm(0);
142 }
143
144 BASIC_BLOCK(4, 6, 5)
145 {
146 CONSTANT(1, 12345);
147 INST(4, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
148 }
149
150 BASIC_BLOCK(5, -1)
151 {
152 INST(5, Opcode::Sub).u64().Inputs(1, 0);
153 INST(6, Opcode::Return).u64().Inputs(5);
154 }
155
156 BASIC_BLOCK(6, -1)
157 {
158 INST(7, Opcode::Add).u64().Inputs(0, 1);
159 INST(8, Opcode::Return).u64().Inputs(7);
160 }
161 }
162
163 bool result = GetGraph()->RunPass<MoveConstants>();
164 ASSERT_TRUE(result);
165
166 GraphChecker(GetGraph()).Check();
167 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
168 }
169
TEST_F(MoveConstantsTest,MoveToClosestCommonDominator)170 TEST_F(MoveConstantsTest, MoveToClosestCommonDominator)
171 {
172 GRAPH(GetGraph())
173 {
174 PARAMETER(0, 1).u64();
175 CONSTANT(1, 12345);
176
177 BASIC_BLOCK(2, 4, 3)
178 {
179 INST(4, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
180 }
181
182 BASIC_BLOCK(3, -1)
183 {
184 INST(30, Opcode::ReturnI).u64().Imm(0);
185 }
186
187 BASIC_BLOCK(4, 8, 5)
188 {
189 INST(9, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
190 }
191
192 BASIC_BLOCK(5, 7, 6)
193 {
194 INST(12, Opcode::IfImm).CC(CC_LE).Imm(15).Inputs(0);
195 }
196
197 BASIC_BLOCK(6, -1)
198 {
199 INST(17, Opcode::Add).u64().Inputs(0, 1);
200 INST(18, Opcode::Return).u64().Inputs(17);
201 }
202
203 BASIC_BLOCK(7, -1)
204 {
205 INST(23, Opcode::Sub).u64().Inputs(1, 0);
206 INST(24, Opcode::Return).u64().Inputs(23);
207 }
208
209 BASIC_BLOCK(8, -1)
210 {
211 INST(27, Opcode::Div).u64().Inputs(1, 0);
212 INST(28, Opcode::Return).u64().Inputs(27);
213 }
214 }
215 Graph *graph_et = CreateEmptyGraph();
216 GRAPH(graph_et)
217 {
218 PARAMETER(0, 1).u64();
219
220 BASIC_BLOCK(2, 4, 3)
221 {
222 INST(4, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
223 }
224
225 BASIC_BLOCK(3, -1)
226 {
227 INST(30, Opcode::ReturnI).u64().Imm(0);
228 }
229
230 BASIC_BLOCK(4, 8, 5)
231 {
232 CONSTANT(1, 12345);
233 INST(9, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
234 }
235
236 BASIC_BLOCK(5, 7, 6)
237 {
238 INST(12, Opcode::IfImm).CC(CC_LE).Imm(15).Inputs(0);
239 }
240
241 BASIC_BLOCK(6, -1)
242 {
243 INST(17, Opcode::Add).u64().Inputs(0, 1);
244 INST(18, Opcode::Return).u64().Inputs(17);
245 }
246
247 BASIC_BLOCK(7, -1)
248 {
249 INST(23, Opcode::Sub).u64().Inputs(1, 0);
250 INST(24, Opcode::Return).u64().Inputs(23);
251 }
252
253 BASIC_BLOCK(8, -1)
254 {
255 INST(27, Opcode::Div).u64().Inputs(1, 0);
256 INST(28, Opcode::Return).u64().Inputs(27);
257 }
258 }
259
260 bool result = GetGraph()->RunPass<MoveConstants>();
261 ASSERT_TRUE(result);
262
263 GraphChecker(GetGraph()).Check();
264 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
265 }
266
TEST_F(MoveConstantsTest,MoveJustBeforeUser)267 TEST_F(MoveConstantsTest, MoveJustBeforeUser)
268 {
269 GRAPH(GetGraph())
270 {
271 PARAMETER(0, 1).u64();
272 CONSTANT(1, 12345);
273
274 BASIC_BLOCK(2, 4, 3)
275 {
276 INST(4, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
277 }
278
279 BASIC_BLOCK(3, -1)
280 {
281 INST(13, Opcode::ReturnI).u64().Imm(0);
282 }
283
284 BASIC_BLOCK(4, 6, 5)
285 {
286 INST(9, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
287 }
288
289 BASIC_BLOCK(5, -1)
290 {
291 INST(10, Opcode::Add).u64().Inputs(0, 1);
292 INST(11, Opcode::Return).u64().Inputs(10);
293 }
294
295 BASIC_BLOCK(6, -1)
296 {
297 INST(12, Opcode::Return).u64().Inputs(0);
298 }
299 }
300 Graph *graph_et = CreateEmptyGraph();
301 GRAPH(graph_et)
302 {
303 PARAMETER(0, 1).u64();
304
305 BASIC_BLOCK(2, 4, 3)
306 {
307 INST(4, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
308 }
309
310 BASIC_BLOCK(3, -1)
311 {
312 INST(13, Opcode::ReturnI).u64().Imm(0);
313 }
314
315 BASIC_BLOCK(4, 6, 5)
316 {
317 INST(9, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
318 }
319
320 BASIC_BLOCK(5, -1)
321 {
322 CONSTANT(1, 12345);
323 INST(10, Opcode::Add).u64().Inputs(0, 1);
324 INST(11, Opcode::Return).u64().Inputs(10);
325 }
326
327 BASIC_BLOCK(6, -1)
328 {
329 INST(12, Opcode::Return).u64().Inputs(0);
330 }
331 }
332
333 bool result = GetGraph()->RunPass<MoveConstants>();
334 ASSERT_TRUE(result);
335
336 GraphChecker(GetGraph()).Check();
337 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
338 }
339
TEST_F(MoveConstantsTest,MoveJustBeforeUserSingleBlock)340 TEST_F(MoveConstantsTest, MoveJustBeforeUserSingleBlock)
341 {
342 GRAPH(GetGraph())
343 {
344 PARAMETER(0, 1).u64();
345 CONSTANT(1, 12345);
346
347 BASIC_BLOCK(2, 4, 3)
348 {
349 INST(5, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
350 }
351
352 BASIC_BLOCK(3, -1)
353 {
354 INST(17, Opcode::ReturnI).Imm(0);
355 }
356
357 BASIC_BLOCK(4, 6, 5)
358 {
359 INST(9, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
360 }
361
362 BASIC_BLOCK(5, -1)
363 {
364 INST(12, Opcode::Div).u64().Inputs(1, 0);
365 INST(13, Opcode::Add).u64().Inputs(12, 1);
366 INST(14, Opcode::Return).u64().Inputs(13);
367 }
368
369 BASIC_BLOCK(6, -1)
370 {
371 INST(15, Opcode::Return).u64().Inputs(0);
372 }
373 }
374 Graph *graph_et = CreateEmptyGraph();
375 GRAPH(graph_et)
376 {
377 PARAMETER(0, 1).u64();
378
379 BASIC_BLOCK(2, 4, 3)
380 {
381 INST(5, Opcode::IfImm).CC(CC_GE).Imm(5).Inputs(0);
382 }
383
384 BASIC_BLOCK(3, -1)
385 {
386 INST(17, Opcode::ReturnI).Imm(0);
387 }
388
389 BASIC_BLOCK(4, 6, 5)
390 {
391 INST(9, Opcode::IfImm).CC(CC_LE).Imm(10).Inputs(0);
392 }
393
394 BASIC_BLOCK(5, -1)
395 {
396 CONSTANT(1, 12345);
397 INST(12, Opcode::Div).u64().Inputs(1, 0);
398 INST(13, Opcode::Add).u64().Inputs(12, 1);
399 INST(14, Opcode::Return).u64().Inputs(13);
400 }
401
402 BASIC_BLOCK(6, -1)
403 {
404 INST(15, Opcode::Return).u64().Inputs(0);
405 }
406 }
407
408 bool result = GetGraph()->RunPass<MoveConstants>();
409 ASSERT_TRUE(result);
410
411 GraphChecker(GetGraph()).Check();
412 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
413 }
414
TEST_F(MoveConstantsTest,MovePhiInput)415 TEST_F(MoveConstantsTest, MovePhiInput)
416 {
417 GRAPH(GetGraph())
418 {
419 PARAMETER(0, 1).u64();
420 CONSTANT(2, 12345);
421
422 BASIC_BLOCK(2, 4, 3)
423 {
424 INST(15, Opcode::IfImm).CC(CC_LE).Imm(5).Inputs(0);
425 }
426
427 BASIC_BLOCK(3, 4, 3)
428 {
429 INST(4, Opcode::Phi).u64().Inputs({{2, 0}, {3, 22}});
430 INST(5, Opcode::Phi).u64().Inputs({{2, 2}, {3, 23}});
431 INST(22, Opcode::AddI).u64().Imm(1).Inputs(4);
432 INST(23, Opcode::AddI).u64().Imm(1).Inputs(5);
433 INST(24, Opcode::If).CC(CC_GE).Inputs(23, 0);
434 }
435
436 BASIC_BLOCK(4, -1)
437 {
438 INST(19, Opcode::Phi).u64().Inputs({{3, 22}, {2, 0}});
439 INST(13, Opcode::Return).u64().Inputs(19);
440 }
441 }
442 Graph *graph_et = CreateEmptyGraph();
443 GRAPH(graph_et)
444 {
445 PARAMETER(0, 1).u64();
446
447 BASIC_BLOCK(2, 4, 3)
448 {
449 CONSTANT(2, 12345);
450 INST(15, Opcode::IfImm).CC(CC_LE).Imm(5).Inputs(0);
451 }
452
453 BASIC_BLOCK(3, 4, 3)
454 {
455 INST(4, Opcode::Phi).u64().Inputs({{2, 0}, {3, 22}});
456 INST(5, Opcode::Phi).u64().Inputs({{2, 2}, {3, 23}});
457 INST(22, Opcode::AddI).u64().Imm(1).Inputs(4);
458 INST(23, Opcode::AddI).u64().Imm(1).Inputs(5);
459 INST(24, Opcode::If).CC(CC_GE).Inputs(23, 0);
460 }
461
462 BASIC_BLOCK(4, -1)
463 {
464 INST(19, Opcode::Phi).u64().Inputs({{3, 22}, {2, 0}});
465 INST(13, Opcode::Return).u64().Inputs(19);
466 }
467 }
468
469 bool result = GetGraph()->RunPass<MoveConstants>();
470 ASSERT_TRUE(result);
471
472 GraphChecker(GetGraph()).Check();
473 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
474 }
475
TEST_F(MoveConstantsTest,AvoidMoveToLoop)476 TEST_F(MoveConstantsTest, AvoidMoveToLoop)
477 {
478 GRAPH(GetGraph())
479 {
480 PARAMETER(0, 1).u64();
481 CONSTANT(2, 5);
482 CONSTANT(11, 0);
483 CONSTANT(22, 3);
484
485 BASIC_BLOCK(2, 3)
486 {
487 INST(1, Opcode::NOP);
488 }
489
490 BASIC_BLOCK(3, 7, 4)
491 {
492 INST(3, Opcode::Phi).u64().Inputs({{2, 2}, {6, 35}});
493 INST(4, Opcode::Phi).u64().Inputs({{2, 0}, {6, 34}});
494 INST(5, Opcode::Phi).u64().Inputs({{2, 2}, {6, 42}});
495 INST(39, Opcode::If).CC(CC_GE).Inputs(5, 0);
496 }
497
498 BASIC_BLOCK(4, 6, 5)
499 {
500 INST(29, Opcode::IfImm).CC(CC_LE).Imm(0).Inputs(0);
501 }
502
503 BASIC_BLOCK(5, 6, 5)
504 {
505 INST(14, Opcode::Phi).u64().Inputs({{4, 4}, {5, 23}});
506 INST(16, Opcode::Phi).u64().Inputs({{4, 11}, {5, 40}});
507 INST(23, Opcode::Mul).u64().Inputs(14, 22);
508 INST(40, Opcode::AddI).u64().Imm(1).Inputs(16);
509 INST(41, Opcode::If).CC(CC_GE).Inputs(40, 0);
510 }
511
512 BASIC_BLOCK(6, 3)
513 {
514 INST(34, Opcode::Phi).u64().Inputs({{5, 23}, {4, 4}});
515 INST(35, Opcode::Phi).u64().Inputs({{5, 40}, {4, 11}});
516 INST(42, Opcode::AddI).u64().Imm(1).Inputs(5);
517 }
518
519 BASIC_BLOCK(7, -1)
520 {
521 INST(27, Opcode::Return).u64().Inputs(4);
522 }
523 }
524 Graph *graph_et = CreateEmptyGraph();
525 GRAPH(graph_et)
526 {
527 PARAMETER(0, 1).u64();
528
529 BASIC_BLOCK(2, 3)
530 {
531 CONSTANT(22, 3);
532 CONSTANT(11, 0);
533 CONSTANT(2, 5);
534 INST(1, Opcode::NOP);
535 }
536
537 BASIC_BLOCK(3, 7, 4)
538 {
539 INST(3, Opcode::Phi).u64().Inputs({{2, 2}, {6, 35}});
540 INST(4, Opcode::Phi).u64().Inputs({{2, 0}, {6, 34}});
541 INST(5, Opcode::Phi).u64().Inputs({{2, 2}, {6, 42}});
542 INST(39, Opcode::If).CC(CC_GE).Inputs(5, 0);
543 }
544
545 BASIC_BLOCK(4, 6, 5)
546 {
547 INST(29, Opcode::IfImm).CC(CC_LE).Imm(0).Inputs(0);
548 }
549
550 BASIC_BLOCK(5, 6, 5)
551 {
552 INST(14, Opcode::Phi).u64().Inputs({{4, 4}, {5, 23}});
553 INST(16, Opcode::Phi).u64().Inputs({{4, 11}, {5, 40}});
554 INST(23, Opcode::Mul).u64().Inputs(14, 22);
555 INST(40, Opcode::AddI).u64().Imm(1).Inputs(16);
556 INST(41, Opcode::If).CC(CC_GE).Inputs(40, 0);
557 }
558
559 BASIC_BLOCK(6, 3)
560 {
561 INST(34, Opcode::Phi).u64().Inputs({{5, 23}, {4, 4}});
562 INST(35, Opcode::Phi).u64().Inputs({{5, 40}, {4, 11}});
563 INST(42, Opcode::AddI).u64().Imm(1).Inputs(5);
564 }
565
566 BASIC_BLOCK(7, -1)
567 {
568 INST(27, Opcode::Return).u64().Inputs(4);
569 }
570 }
571
572 bool result = GetGraph()->RunPass<MoveConstants>();
573 ASSERT_TRUE(result);
574
575 GraphChecker(GetGraph()).Check();
576 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
577 }
578
TEST_F(MoveConstantsTest,MoveToClosestCommonDominator2)579 TEST_F(MoveConstantsTest, MoveToClosestCommonDominator2)
580 {
581 GRAPH(GetGraph())
582 {
583 PARAMETER(0, 1).u64();
584 PARAMETER(1, 2).u64();
585 CONSTANT(4, 12345);
586
587 BASIC_BLOCK(2, 3, 4)
588 {
589 INST(2, Opcode::If).CC(CC_LE).Inputs(0, 4);
590 }
591
592 BASIC_BLOCK(3, -1)
593 {
594 INST(3, Opcode::Mul).u64().Inputs(0, 4);
595 INST(5, Opcode::Return).u64().Inputs(3);
596 }
597
598 BASIC_BLOCK(4, -1)
599 {
600 INST(6, Opcode::Mul).u64().Inputs(1, 4);
601 INST(7, Opcode::Return).u64().Inputs(6);
602 }
603 }
604 Graph *graph_et = CreateEmptyGraph();
605 GRAPH(graph_et)
606 {
607 PARAMETER(0, 1).u64();
608 PARAMETER(1, 2).u64();
609
610 BASIC_BLOCK(2, 3, 4)
611 {
612 CONSTANT(4, 12345);
613 INST(2, Opcode::If).CC(CC_LE).Inputs(0, 4);
614 }
615
616 BASIC_BLOCK(3, -1)
617 {
618 INST(3, Opcode::Mul).u64().Inputs(0, 4);
619 INST(5, Opcode::Return).u64().Inputs(3);
620 }
621
622 BASIC_BLOCK(4, -1)
623 {
624 INST(6, Opcode::Mul).u64().Inputs(1, 4);
625 INST(7, Opcode::Return).u64().Inputs(6);
626 }
627 }
628
629 bool result = GetGraph()->RunPass<MoveConstants>();
630 ASSERT_TRUE(result);
631
632 GraphChecker(GetGraph()).Check();
633 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
634 }
635
TEST_F(MoveConstantsTest,MoveToClosestCommonDominatorPhi)636 TEST_F(MoveConstantsTest, MoveToClosestCommonDominatorPhi)
637 {
638 GRAPH(GetGraph())
639 {
640 PARAMETER(0, 1).u64();
641 PARAMETER(1, 2).u64();
642 CONSTANT(5, 12345);
643
644 BASIC_BLOCK(2, 3, 4)
645 {
646 INST(2, Opcode::If).CC(CC_LE).Inputs(0, 1);
647 }
648
649 BASIC_BLOCK(3, 5)
650 {
651 INST(3, Opcode::Mul).u64().Inputs(0, 1);
652 }
653
654 BASIC_BLOCK(4, 5)
655 {
656 INST(4, Opcode::Div).u64().Inputs(0, 1);
657 }
658
659 BASIC_BLOCK(5, -1)
660 {
661 INST(6, Opcode::Phi).u64().Inputs({{3, 3}, {4, 5}});
662 INST(7, Opcode::Return).u64().Inputs(6);
663 }
664 }
665 Graph *graph_et = CreateEmptyGraph();
666 GRAPH(graph_et)
667 {
668 PARAMETER(0, 1).u64();
669 PARAMETER(1, 2).u64();
670
671 BASIC_BLOCK(2, 3, 4)
672 {
673 CONSTANT(5, 12345);
674 INST(2, Opcode::If).CC(CC_LE).Inputs(0, 1);
675 }
676
677 BASIC_BLOCK(3, 5)
678 {
679 INST(3, Opcode::Mul).u64().Inputs(0, 1);
680 }
681
682 BASIC_BLOCK(4, 5)
683 {
684 INST(4, Opcode::Div).u64().Inputs(0, 1);
685 }
686
687 BASIC_BLOCK(5, -1)
688 {
689 INST(6, Opcode::Phi).u64().Inputs({{3, 3}, {4, 5}});
690 INST(7, Opcode::Return).u64().Inputs(6);
691 }
692 }
693
694 bool result = GetGraph()->RunPass<MoveConstants>();
695 ASSERT_TRUE(result);
696
697 GraphChecker(GetGraph()).Check();
698 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
699 }
700
TEST_F(MoveConstantsTest,WasNotApplied)701 TEST_F(MoveConstantsTest, WasNotApplied)
702 {
703 GRAPH(GetGraph())
704 {
705 PARAMETER(0, 1).u64();
706
707 BASIC_BLOCK(2, -1)
708 {
709 INST(3, Opcode::Return).u64().Inputs(0);
710 }
711 }
712 Graph *graph_et = CreateEmptyGraph();
713 GRAPH(graph_et)
714 {
715 PARAMETER(0, 1).u64();
716
717 BASIC_BLOCK(2, -1)
718 {
719 INST(3, Opcode::Return).u64().Inputs(0);
720 }
721 }
722
723 bool result = GetGraph()->RunPass<MoveConstants>();
724 ASSERT_FALSE(result);
725
726 GraphChecker(GetGraph()).Check();
727 ASSERT_TRUE(GraphComparator().Compare(GetGraph(), graph_et));
728 }
729
TEST_F(MoveConstantsTest,CatchPhiUser)730 TEST_F(MoveConstantsTest, CatchPhiUser)
731 {
732 GRAPH(GetGraph())
733 {
734 CONSTANT(0, nullptr);
735
736 BASIC_BLOCK(2, 3, 5)
737 {
738 INST(1, Opcode::Try).CatchTypeIds({0x0});
739 }
740 BASIC_BLOCK(3, 4)
741 {
742 INST(2, Opcode::SaveState).Inputs().SrcVregs({});
743 INST(3, Opcode::CallStatic).ref().InputsAutoType(2);
744 INST(4, Opcode::SaveState).Inputs().SrcVregs({});
745 INST(5, Opcode::CallStatic).v0id().InputsAutoType(4);
746 }
747 BASIC_BLOCK(4, 5) {}
748 BASIC_BLOCK(5, 6)
749 {
750 // If INST(3, Opcode::CallStatic) throw exception -> use nullptr
751 // If INST(5, Opcode::CallStatic) throw exception -> use INST(3, Opcode::CallStatic)
752 INST(9, Opcode::CatchPhi).ref().ThrowableInsts({3, 5}).Inputs(0, 3);
753 }
754 BASIC_BLOCK(6, -1)
755 {
756 INST(10, Opcode::Return).ref().Inputs(9);
757 }
758 }
759
760 GetGraph()->RunPass<MoveConstants>();
761 // CONSTANT(0, nullptr) should dominate throwable INST(3, Opcode::CallStatic)
762 ASSERT_TRUE(INS(0).IsDominate(&INS(3)));
763 }
764
765 } // namespace panda::compiler
766