xref: /llvm-project/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp (revision 8caeb2e0c2fb8a5f1689c11775b81ceee76de958)
1 //===- llvm/unittests/Transforms/Vectorize/VPlanTest.cpp - VPlan tests ----===//
2 //
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "../lib/Transforms/Vectorize/VPlan.h"
11 #include "../lib/Transforms/Vectorize/VPlanCFG.h"
12 #include "VPlanTestBase.h"
13 #include "llvm/ADT/DepthFirstIterator.h"
14 #include "llvm/ADT/PostOrderIterator.h"
15 #include "llvm/Analysis/VectorUtils.h"
16 #include "llvm/IR/Instruction.h"
17 #include "llvm/IR/Instructions.h"
18 #include "gtest/gtest.h"
19 #include <string>
20 
21 namespace llvm {
22 namespace {
23 
24 #define CHECK_ITERATOR(Range1, ...)                                            \
25   do {                                                                         \
26     std::vector<VPInstruction *> Tmp = {__VA_ARGS__};                          \
27     EXPECT_EQ((size_t)std::distance(Range1.begin(), Range1.end()),             \
28               Tmp.size());                                                     \
29     for (auto Pair : zip(Range1, make_range(Tmp.begin(), Tmp.end())))          \
30       EXPECT_EQ(&std::get<0>(Pair), std::get<1>(Pair));                        \
31   } while (0)
32 
33 TEST(VPInstructionTest, insertBefore) {
34   VPInstruction *I1 = new VPInstruction(0, {});
35   VPInstruction *I2 = new VPInstruction(1, {});
36   VPInstruction *I3 = new VPInstruction(2, {});
37 
38   VPBasicBlock VPBB1;
39   VPBB1.appendRecipe(I1);
40 
41   I2->insertBefore(I1);
42   CHECK_ITERATOR(VPBB1, I2, I1);
43 
44   I3->insertBefore(I2);
45   CHECK_ITERATOR(VPBB1, I3, I2, I1);
46 }
47 
48 TEST(VPInstructionTest, eraseFromParent) {
49   VPInstruction *I1 = new VPInstruction(0, {});
50   VPInstruction *I2 = new VPInstruction(1, {});
51   VPInstruction *I3 = new VPInstruction(2, {});
52 
53   VPBasicBlock VPBB1;
54   VPBB1.appendRecipe(I1);
55   VPBB1.appendRecipe(I2);
56   VPBB1.appendRecipe(I3);
57 
58   I2->eraseFromParent();
59   CHECK_ITERATOR(VPBB1, I1, I3);
60 
61   I1->eraseFromParent();
62   CHECK_ITERATOR(VPBB1, I3);
63 
64   I3->eraseFromParent();
65   EXPECT_TRUE(VPBB1.empty());
66 }
67 
68 TEST(VPInstructionTest, moveAfter) {
69   VPInstruction *I1 = new VPInstruction(0, {});
70   VPInstruction *I2 = new VPInstruction(1, {});
71   VPInstruction *I3 = new VPInstruction(2, {});
72 
73   VPBasicBlock VPBB1;
74   VPBB1.appendRecipe(I1);
75   VPBB1.appendRecipe(I2);
76   VPBB1.appendRecipe(I3);
77 
78   I1->moveAfter(I2);
79 
80   CHECK_ITERATOR(VPBB1, I2, I1, I3);
81 
82   VPInstruction *I4 = new VPInstruction(4, {});
83   VPInstruction *I5 = new VPInstruction(5, {});
84   VPBasicBlock VPBB2;
85   VPBB2.appendRecipe(I4);
86   VPBB2.appendRecipe(I5);
87 
88   I3->moveAfter(I4);
89 
90   CHECK_ITERATOR(VPBB1, I2, I1);
91   CHECK_ITERATOR(VPBB2, I4, I3, I5);
92   EXPECT_EQ(I3->getParent(), I4->getParent());
93 }
94 
95 TEST(VPInstructionTest, moveBefore) {
96   VPInstruction *I1 = new VPInstruction(0, {});
97   VPInstruction *I2 = new VPInstruction(1, {});
98   VPInstruction *I3 = new VPInstruction(2, {});
99 
100   VPBasicBlock VPBB1;
101   VPBB1.appendRecipe(I1);
102   VPBB1.appendRecipe(I2);
103   VPBB1.appendRecipe(I3);
104 
105   I1->moveBefore(VPBB1, I3->getIterator());
106 
107   CHECK_ITERATOR(VPBB1, I2, I1, I3);
108 
109   VPInstruction *I4 = new VPInstruction(4, {});
110   VPInstruction *I5 = new VPInstruction(5, {});
111   VPBasicBlock VPBB2;
112   VPBB2.appendRecipe(I4);
113   VPBB2.appendRecipe(I5);
114 
115   I3->moveBefore(VPBB2, I4->getIterator());
116 
117   CHECK_ITERATOR(VPBB1, I2, I1);
118   CHECK_ITERATOR(VPBB2, I3, I4, I5);
119   EXPECT_EQ(I3->getParent(), I4->getParent());
120 
121   VPBasicBlock VPBB3;
122 
123   I4->moveBefore(VPBB3, VPBB3.end());
124 
125   CHECK_ITERATOR(VPBB1, I2, I1);
126   CHECK_ITERATOR(VPBB2, I3, I5);
127   CHECK_ITERATOR(VPBB3, I4);
128   EXPECT_EQ(&VPBB3, I4->getParent());
129 }
130 
131 TEST(VPInstructionTest, setOperand) {
132   VPValue *VPV1 = new VPValue();
133   VPValue *VPV2 = new VPValue();
134   VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2});
135   EXPECT_EQ(1u, VPV1->getNumUsers());
136   EXPECT_EQ(I1, *VPV1->user_begin());
137   EXPECT_EQ(1u, VPV2->getNumUsers());
138   EXPECT_EQ(I1, *VPV2->user_begin());
139 
140   // Replace operand 0 (VPV1) with VPV3.
141   VPValue *VPV3 = new VPValue();
142   I1->setOperand(0, VPV3);
143   EXPECT_EQ(0u, VPV1->getNumUsers());
144   EXPECT_EQ(1u, VPV2->getNumUsers());
145   EXPECT_EQ(I1, *VPV2->user_begin());
146   EXPECT_EQ(1u, VPV3->getNumUsers());
147   EXPECT_EQ(I1, *VPV3->user_begin());
148 
149   // Replace operand 1 (VPV2) with VPV3.
150   I1->setOperand(1, VPV3);
151   EXPECT_EQ(0u, VPV1->getNumUsers());
152   EXPECT_EQ(0u, VPV2->getNumUsers());
153   EXPECT_EQ(2u, VPV3->getNumUsers());
154   EXPECT_EQ(I1, *VPV3->user_begin());
155   EXPECT_EQ(I1, *std::next(VPV3->user_begin()));
156 
157   // Replace operand 0 (VPV3) with VPV4.
158   VPValue *VPV4 = new VPValue();
159   I1->setOperand(0, VPV4);
160   EXPECT_EQ(1u, VPV3->getNumUsers());
161   EXPECT_EQ(I1, *VPV3->user_begin());
162   EXPECT_EQ(I1, *VPV4->user_begin());
163 
164   // Replace operand 1 (VPV3) with VPV4.
165   I1->setOperand(1, VPV4);
166   EXPECT_EQ(0u, VPV3->getNumUsers());
167   EXPECT_EQ(I1, *VPV4->user_begin());
168   EXPECT_EQ(I1, *std::next(VPV4->user_begin()));
169 
170   delete I1;
171   delete VPV1;
172   delete VPV2;
173   delete VPV3;
174   delete VPV4;
175 }
176 
177 TEST(VPInstructionTest, replaceAllUsesWith) {
178   VPValue *VPV1 = new VPValue();
179   VPValue *VPV2 = new VPValue();
180   VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2});
181 
182   // Replace all uses of VPV1 with VPV3.
183   VPValue *VPV3 = new VPValue();
184   VPV1->replaceAllUsesWith(VPV3);
185   EXPECT_EQ(VPV3, I1->getOperand(0));
186   EXPECT_EQ(VPV2, I1->getOperand(1));
187   EXPECT_EQ(0u, VPV1->getNumUsers());
188   EXPECT_EQ(1u, VPV2->getNumUsers());
189   EXPECT_EQ(I1, *VPV2->user_begin());
190   EXPECT_EQ(1u, VPV3->getNumUsers());
191   EXPECT_EQ(I1, *VPV3->user_begin());
192 
193   // Replace all uses of VPV2 with VPV3.
194   VPV2->replaceAllUsesWith(VPV3);
195   EXPECT_EQ(VPV3, I1->getOperand(0));
196   EXPECT_EQ(VPV3, I1->getOperand(1));
197   EXPECT_EQ(0u, VPV1->getNumUsers());
198   EXPECT_EQ(0u, VPV2->getNumUsers());
199   EXPECT_EQ(2u, VPV3->getNumUsers());
200   EXPECT_EQ(I1, *VPV3->user_begin());
201 
202   // Replace all uses of VPV3 with VPV1.
203   VPV3->replaceAllUsesWith(VPV1);
204   EXPECT_EQ(VPV1, I1->getOperand(0));
205   EXPECT_EQ(VPV1, I1->getOperand(1));
206   EXPECT_EQ(2u, VPV1->getNumUsers());
207   EXPECT_EQ(I1, *VPV1->user_begin());
208   EXPECT_EQ(0u, VPV2->getNumUsers());
209   EXPECT_EQ(0u, VPV3->getNumUsers());
210 
211   VPInstruction *I2 = new VPInstruction(0, {VPV1, VPV2});
212   EXPECT_EQ(3u, VPV1->getNumUsers());
213   VPV1->replaceAllUsesWith(VPV3);
214   EXPECT_EQ(3u, VPV3->getNumUsers());
215 
216   delete I1;
217   delete I2;
218   delete VPV1;
219   delete VPV2;
220   delete VPV3;
221 }
222 
223 TEST(VPInstructionTest, releaseOperandsAtDeletion) {
224   VPValue *VPV1 = new VPValue();
225   VPValue *VPV2 = new VPValue();
226   VPInstruction *I1 = new VPInstruction(0, {VPV1, VPV2});
227 
228   EXPECT_EQ(1u, VPV1->getNumUsers());
229   EXPECT_EQ(I1, *VPV1->user_begin());
230   EXPECT_EQ(1u, VPV2->getNumUsers());
231   EXPECT_EQ(I1, *VPV2->user_begin());
232 
233   delete I1;
234 
235   EXPECT_EQ(0u, VPV1->getNumUsers());
236   EXPECT_EQ(0u, VPV2->getNumUsers());
237 
238   delete VPV1;
239   delete VPV2;
240 }
241 
242 using VPBasicBlockTest = VPlanTestBase;
243 
244 TEST_F(VPBasicBlockTest, getPlan) {
245   {
246     VPlan &Plan = getPlan();
247     VPBasicBlock *VPBB1 = Plan.getEntry();
248     VPBasicBlock *VPBB2 = new VPBasicBlock();
249     VPBasicBlock *VPBB3 = new VPBasicBlock();
250     VPBasicBlock *VPBB4 = new VPBasicBlock();
251 
252     //     VPBB1
253     //     /   \
254     // VPBB2  VPBB3
255     //    \    /
256     //    VPBB4
257     VPBlockUtils::connectBlocks(VPBB1, VPBB2);
258     VPBlockUtils::connectBlocks(VPBB1, VPBB3);
259     VPBlockUtils::connectBlocks(VPBB2, VPBB4);
260     VPBlockUtils::connectBlocks(VPBB3, VPBB4);
261     VPBlockUtils::connectBlocks(VPBB4, Plan.getScalarHeader());
262 
263     EXPECT_EQ(&Plan, VPBB1->getPlan());
264     EXPECT_EQ(&Plan, VPBB2->getPlan());
265     EXPECT_EQ(&Plan, VPBB3->getPlan());
266     EXPECT_EQ(&Plan, VPBB4->getPlan());
267   }
268 
269   {
270     VPlan &Plan = getPlan();
271     VPBasicBlock *VPBB1 = Plan.getEntry();
272     // VPBasicBlock is the entry into the VPlan, followed by a region.
273     VPBasicBlock *R1BB1 = new VPBasicBlock();
274     VPBasicBlock *R1BB2 = new VPBasicBlock();
275     VPRegionBlock *R1 = new VPRegionBlock(R1BB1, R1BB2, "R1");
276     VPBlockUtils::connectBlocks(R1BB1, R1BB2);
277 
278     VPBlockUtils::connectBlocks(VPBB1, R1);
279 
280     VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
281 
282     EXPECT_EQ(&Plan, VPBB1->getPlan());
283     EXPECT_EQ(&Plan, R1->getPlan());
284     EXPECT_EQ(&Plan, R1BB1->getPlan());
285     EXPECT_EQ(&Plan, R1BB2->getPlan());
286   }
287 
288   {
289     VPlan &Plan = getPlan();
290     VPBasicBlock *R1BB1 = new VPBasicBlock();
291     VPBasicBlock *R1BB2 = new VPBasicBlock();
292     VPRegionBlock *R1 = new VPRegionBlock(R1BB1, R1BB2, "R1");
293     VPBlockUtils::connectBlocks(R1BB1, R1BB2);
294 
295     VPBasicBlock *R2BB1 = new VPBasicBlock();
296     VPBasicBlock *R2BB2 = new VPBasicBlock();
297     VPRegionBlock *R2 = new VPRegionBlock(R2BB1, R2BB2, "R2");
298     VPBlockUtils::connectBlocks(R2BB1, R2BB2);
299 
300     VPBasicBlock *VPBB1 = Plan.getEntry();
301     VPBlockUtils::connectBlocks(VPBB1, R1);
302     VPBlockUtils::connectBlocks(VPBB1, R2);
303 
304     VPBasicBlock *VPBB2 = new VPBasicBlock();
305     VPBlockUtils::connectBlocks(R1, VPBB2);
306     VPBlockUtils::connectBlocks(R2, VPBB2);
307 
308     VPBlockUtils::connectBlocks(R2, Plan.getScalarHeader());
309 
310     EXPECT_EQ(&Plan, VPBB1->getPlan());
311     EXPECT_EQ(&Plan, R1->getPlan());
312     EXPECT_EQ(&Plan, R1BB1->getPlan());
313     EXPECT_EQ(&Plan, R1BB2->getPlan());
314     EXPECT_EQ(&Plan, R2->getPlan());
315     EXPECT_EQ(&Plan, R2BB1->getPlan());
316     EXPECT_EQ(&Plan, R2BB2->getPlan());
317     EXPECT_EQ(&Plan, VPBB2->getPlan());
318   }
319 }
320 
321 TEST_F(VPBasicBlockTest, TraversingIteratorTest) {
322   {
323     // VPBasicBlocks only
324     //     VPBB1
325     //     /   \
326     // VPBB2  VPBB3
327     //    \    /
328     //    VPBB4
329     //
330     VPlan &Plan = getPlan();
331     VPBasicBlock *VPBB1 = Plan.getEntry();
332     VPBasicBlock *VPBB2 = new VPBasicBlock();
333     VPBasicBlock *VPBB3 = new VPBasicBlock();
334     VPBasicBlock *VPBB4 = new VPBasicBlock();
335 
336     VPBlockUtils::connectBlocks(VPBB1, VPBB2);
337     VPBlockUtils::connectBlocks(VPBB1, VPBB3);
338     VPBlockUtils::connectBlocks(VPBB2, VPBB4);
339     VPBlockUtils::connectBlocks(VPBB3, VPBB4);
340 
341     VPBlockDeepTraversalWrapper<const VPBlockBase *> Start(VPBB1);
342     SmallVector<const VPBlockBase *> FromIterator(depth_first(Start));
343     EXPECT_EQ(4u, FromIterator.size());
344     EXPECT_EQ(VPBB1, FromIterator[0]);
345     EXPECT_EQ(VPBB2, FromIterator[1]);
346 
347     VPBlockUtils::connectBlocks(VPBB4, Plan.getScalarHeader());
348   }
349 
350   {
351     // 2 consecutive regions.
352     // VPBB0
353     //  |
354     // R1 {
355     //     \
356     //     R1BB1
357     //    /     \   |--|
358     //  R1BB2   R1BB3 -|
359     //    \      /
360     //     R1BB4
361     //  }
362     //   |
363     // R2 {
364     //   \
365     //    R2BB1
366     //      |
367     //    R2BB2
368     //
369     VPlan &Plan = getPlan();
370     VPBasicBlock *VPBB0 = Plan.getEntry();
371     VPBasicBlock *R1BB1 = new VPBasicBlock();
372     VPBasicBlock *R1BB2 = new VPBasicBlock();
373     VPBasicBlock *R1BB3 = new VPBasicBlock();
374     VPBasicBlock *R1BB4 = new VPBasicBlock();
375     VPRegionBlock *R1 = new VPRegionBlock(R1BB1, R1BB4, "R1");
376     R1BB2->setParent(R1);
377     R1BB3->setParent(R1);
378     VPBlockUtils::connectBlocks(VPBB0, R1);
379     VPBlockUtils::connectBlocks(R1BB1, R1BB2);
380     VPBlockUtils::connectBlocks(R1BB1, R1BB3);
381     VPBlockUtils::connectBlocks(R1BB2, R1BB4);
382     VPBlockUtils::connectBlocks(R1BB3, R1BB4);
383     // Cycle.
384     VPBlockUtils::connectBlocks(R1BB3, R1BB3);
385 
386     VPBasicBlock *R2BB1 = new VPBasicBlock();
387     VPBasicBlock *R2BB2 = new VPBasicBlock();
388     VPRegionBlock *R2 = new VPRegionBlock(R2BB1, R2BB2, "R2");
389     VPBlockUtils::connectBlocks(R2BB1, R2BB2);
390     VPBlockUtils::connectBlocks(R1, R2);
391 
392     // Successors of R1.
393     SmallVector<const VPBlockBase *> FromIterator(
394         VPAllSuccessorsIterator<VPBlockBase *>(R1),
395         VPAllSuccessorsIterator<VPBlockBase *>::end(R1));
396     EXPECT_EQ(1u, FromIterator.size());
397     EXPECT_EQ(R1BB1, FromIterator[0]);
398 
399     // Depth-first.
400     VPBlockDeepTraversalWrapper<VPBlockBase *> Start(R1);
401     FromIterator.clear();
402     copy(df_begin(Start), df_end(Start), std::back_inserter(FromIterator));
403     EXPECT_EQ(8u, FromIterator.size());
404     EXPECT_EQ(R1, FromIterator[0]);
405     EXPECT_EQ(R1BB1, FromIterator[1]);
406     EXPECT_EQ(R1BB2, FromIterator[2]);
407     EXPECT_EQ(R1BB4, FromIterator[3]);
408     EXPECT_EQ(R2, FromIterator[4]);
409     EXPECT_EQ(R2BB1, FromIterator[5]);
410     EXPECT_EQ(R2BB2, FromIterator[6]);
411     EXPECT_EQ(R1BB3, FromIterator[7]);
412 
413     // const VPBasicBlocks only.
414     FromIterator.clear();
415     copy(VPBlockUtils::blocksOnly<const VPBasicBlock>(depth_first(Start)),
416          std::back_inserter(FromIterator));
417     EXPECT_EQ(6u, FromIterator.size());
418     EXPECT_EQ(R1BB1, FromIterator[0]);
419     EXPECT_EQ(R1BB2, FromIterator[1]);
420     EXPECT_EQ(R1BB4, FromIterator[2]);
421     EXPECT_EQ(R2BB1, FromIterator[3]);
422     EXPECT_EQ(R2BB2, FromIterator[4]);
423     EXPECT_EQ(R1BB3, FromIterator[5]);
424 
425     // VPRegionBlocks only.
426     SmallVector<VPRegionBlock *> FromIteratorVPRegion(
427         VPBlockUtils::blocksOnly<VPRegionBlock>(depth_first(Start)));
428     EXPECT_EQ(2u, FromIteratorVPRegion.size());
429     EXPECT_EQ(R1, FromIteratorVPRegion[0]);
430     EXPECT_EQ(R2, FromIteratorVPRegion[1]);
431 
432     // Post-order.
433     FromIterator.clear();
434     copy(post_order(Start), std::back_inserter(FromIterator));
435     EXPECT_EQ(8u, FromIterator.size());
436     EXPECT_EQ(R2BB2, FromIterator[0]);
437     EXPECT_EQ(R2BB1, FromIterator[1]);
438     EXPECT_EQ(R2, FromIterator[2]);
439     EXPECT_EQ(R1BB4, FromIterator[3]);
440     EXPECT_EQ(R1BB2, FromIterator[4]);
441     EXPECT_EQ(R1BB3, FromIterator[5]);
442     EXPECT_EQ(R1BB1, FromIterator[6]);
443     EXPECT_EQ(R1, FromIterator[7]);
444 
445     VPBlockUtils::connectBlocks(R2, Plan.getScalarHeader());
446   }
447 
448   {
449     // 2 nested regions.
450     //  VPBB1
451     //    |
452     //  R1 {
453     //         R1BB1
454     //       /        \
455     //   R2 {          |
456     //     \           |
457     //     R2BB1       |
458     //       |   \    R1BB2
459     //     R2BB2-|     |
460     //        \        |
461     //         R2BB3   |
462     //   }            /
463     //      \        /
464     //        R1BB3
465     //  }
466     //   |
467     //  VPBB2
468     //
469     VPlan &Plan = getPlan();
470     VPBasicBlock *R1BB1 = new VPBasicBlock("R1BB1");
471     VPBasicBlock *R1BB2 = new VPBasicBlock("R1BB2");
472     VPBasicBlock *R1BB3 = new VPBasicBlock("R1BB3");
473     VPRegionBlock *R1 = new VPRegionBlock(R1BB1, R1BB3, "R1");
474 
475     VPBasicBlock *R2BB1 = new VPBasicBlock("R2BB1");
476     VPBasicBlock *R2BB2 = new VPBasicBlock("R2BB2");
477     VPBasicBlock *R2BB3 = new VPBasicBlock("R2BB3");
478     VPRegionBlock *R2 = new VPRegionBlock(R2BB1, R2BB3, "R2");
479     R2BB2->setParent(R2);
480     VPBlockUtils::connectBlocks(R2BB1, R2BB2);
481     VPBlockUtils::connectBlocks(R2BB2, R2BB1);
482     VPBlockUtils::connectBlocks(R2BB2, R2BB3);
483 
484     R2->setParent(R1);
485     VPBlockUtils::connectBlocks(R1BB1, R2);
486     R1BB2->setParent(R1);
487     VPBlockUtils::connectBlocks(R1BB1, R1BB2);
488     VPBlockUtils::connectBlocks(R1BB2, R1BB3);
489     VPBlockUtils::connectBlocks(R2, R1BB3);
490 
491     VPBasicBlock *VPBB1 = Plan.getEntry();
492     VPBlockUtils::connectBlocks(VPBB1, R1);
493     VPBasicBlock *VPBB2 = new VPBasicBlock("VPBB2");
494     VPBlockUtils::connectBlocks(R1, VPBB2);
495 
496     // Depth-first.
497     VPBlockDeepTraversalWrapper<VPBlockBase *> Start(VPBB1);
498     SmallVector<VPBlockBase *> FromIterator(depth_first(Start));
499     EXPECT_EQ(10u, FromIterator.size());
500     EXPECT_EQ(VPBB1, FromIterator[0]);
501     EXPECT_EQ(R1, FromIterator[1]);
502     EXPECT_EQ(R1BB1, FromIterator[2]);
503     EXPECT_EQ(R2, FromIterator[3]);
504     EXPECT_EQ(R2BB1, FromIterator[4]);
505     EXPECT_EQ(R2BB2, FromIterator[5]);
506     EXPECT_EQ(R2BB3, FromIterator[6]);
507     EXPECT_EQ(R1BB3, FromIterator[7]);
508     EXPECT_EQ(VPBB2, FromIterator[8]);
509     EXPECT_EQ(R1BB2, FromIterator[9]);
510 
511     // Post-order.
512     FromIterator.clear();
513     FromIterator.append(po_begin(Start), po_end(Start));
514     EXPECT_EQ(10u, FromIterator.size());
515     EXPECT_EQ(VPBB2, FromIterator[0]);
516     EXPECT_EQ(R1BB3, FromIterator[1]);
517     EXPECT_EQ(R2BB3, FromIterator[2]);
518     EXPECT_EQ(R2BB2, FromIterator[3]);
519     EXPECT_EQ(R2BB1, FromIterator[4]);
520     EXPECT_EQ(R2, FromIterator[5]);
521     EXPECT_EQ(R1BB2, FromIterator[6]);
522     EXPECT_EQ(R1BB1, FromIterator[7]);
523     EXPECT_EQ(R1, FromIterator[8]);
524     EXPECT_EQ(VPBB1, FromIterator[9]);
525 
526     VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
527   }
528 
529   {
530     //  VPBB1
531     //    |
532     //  R1 {
533     //    \
534     //     R2 {
535     //      R2BB1
536     //        |
537     //      R2BB2
538     //   }
539     //
540     VPlan &Plan = getPlan();
541     VPBasicBlock *R2BB1 = new VPBasicBlock("R2BB1");
542     VPBasicBlock *R2BB2 = new VPBasicBlock("R2BB2");
543     VPRegionBlock *R2 = new VPRegionBlock(R2BB1, R2BB2, "R2");
544     VPBlockUtils::connectBlocks(R2BB1, R2BB2);
545 
546     VPRegionBlock *R1 = new VPRegionBlock(R2, R2, "R1");
547     R2->setParent(R1);
548 
549     VPBasicBlock *VPBB1 = Plan.getEntry();
550     VPBlockUtils::connectBlocks(VPBB1, R1);
551 
552     // Depth-first.
553     VPBlockDeepTraversalWrapper<VPBlockBase *> Start(VPBB1);
554     SmallVector<VPBlockBase *> FromIterator(depth_first(Start));
555     EXPECT_EQ(5u, FromIterator.size());
556     EXPECT_EQ(VPBB1, FromIterator[0]);
557     EXPECT_EQ(R1, FromIterator[1]);
558     EXPECT_EQ(R2, FromIterator[2]);
559     EXPECT_EQ(R2BB1, FromIterator[3]);
560     EXPECT_EQ(R2BB2, FromIterator[4]);
561 
562     // Post-order.
563     FromIterator.clear();
564     FromIterator.append(po_begin(Start), po_end(Start));
565     EXPECT_EQ(5u, FromIterator.size());
566     EXPECT_EQ(R2BB2, FromIterator[0]);
567     EXPECT_EQ(R2BB1, FromIterator[1]);
568     EXPECT_EQ(R2, FromIterator[2]);
569     EXPECT_EQ(R1, FromIterator[3]);
570     EXPECT_EQ(VPBB1, FromIterator[4]);
571 
572     VPBlockUtils::connectBlocks(R1, Plan.getScalarHeader());
573   }
574 
575   {
576     //  Nested regions with both R3 and R2 being exit nodes without successors.
577     //  The successors of R1 should be used.
578     //
579     //  VPBB1
580     //    |
581     //  R1 {
582     //    \
583     //     R2 {
584     //      \
585     //      R2BB1
586     //        |
587     //       R3 {
588     //          R3BB1
589     //      }
590     //   }
591     //   |
592     //  VPBB2
593     //
594     VPlan &Plan = getPlan();
595     VPBasicBlock *R3BB1 = new VPBasicBlock("R3BB1");
596     VPRegionBlock *R3 = new VPRegionBlock(R3BB1, R3BB1, "R3");
597 
598     VPBasicBlock *R2BB1 = new VPBasicBlock("R2BB1");
599     VPRegionBlock *R2 = new VPRegionBlock(R2BB1, R3, "R2");
600     R3->setParent(R2);
601     VPBlockUtils::connectBlocks(R2BB1, R3);
602 
603     VPRegionBlock *R1 = new VPRegionBlock(R2, R2, "R1");
604     R2->setParent(R1);
605 
606     VPBasicBlock *VPBB1 = Plan.getEntry();
607     VPBasicBlock *VPBB2 = new VPBasicBlock("VPBB2");
608     VPBlockUtils::connectBlocks(VPBB1, R1);
609     VPBlockUtils::connectBlocks(R1, VPBB2);
610 
611     // Depth-first.
612     VPBlockDeepTraversalWrapper<VPBlockBase *> Start(VPBB1);
613     SmallVector<VPBlockBase *> FromIterator(depth_first(Start));
614     EXPECT_EQ(7u, FromIterator.size());
615     EXPECT_EQ(VPBB1, FromIterator[0]);
616     EXPECT_EQ(R1, FromIterator[1]);
617     EXPECT_EQ(R2, FromIterator[2]);
618     EXPECT_EQ(R2BB1, FromIterator[3]);
619     EXPECT_EQ(R3, FromIterator[4]);
620     EXPECT_EQ(R3BB1, FromIterator[5]);
621     EXPECT_EQ(VPBB2, FromIterator[6]);
622 
623     SmallVector<VPBlockBase *> FromIteratorVPBB;
624     copy(VPBlockUtils::blocksOnly<VPBasicBlock>(depth_first(Start)),
625          std::back_inserter(FromIteratorVPBB));
626     EXPECT_EQ(VPBB1, FromIteratorVPBB[0]);
627     EXPECT_EQ(R2BB1, FromIteratorVPBB[1]);
628     EXPECT_EQ(R3BB1, FromIteratorVPBB[2]);
629     EXPECT_EQ(VPBB2, FromIteratorVPBB[3]);
630 
631     // Post-order.
632     FromIterator.clear();
633     copy(post_order(Start), std::back_inserter(FromIterator));
634     EXPECT_EQ(7u, FromIterator.size());
635     EXPECT_EQ(VPBB2, FromIterator[0]);
636     EXPECT_EQ(R3BB1, FromIterator[1]);
637     EXPECT_EQ(R3, FromIterator[2]);
638     EXPECT_EQ(R2BB1, FromIterator[3]);
639     EXPECT_EQ(R2, FromIterator[4]);
640     EXPECT_EQ(R1, FromIterator[5]);
641     EXPECT_EQ(VPBB1, FromIterator[6]);
642 
643     // Post-order, const VPRegionBlocks only.
644     VPBlockDeepTraversalWrapper<const VPBlockBase *> StartConst(VPBB1);
645     SmallVector<const VPRegionBlock *> FromIteratorVPRegion(
646         VPBlockUtils::blocksOnly<const VPRegionBlock>(post_order(StartConst)));
647     EXPECT_EQ(3u, FromIteratorVPRegion.size());
648     EXPECT_EQ(R3, FromIteratorVPRegion[0]);
649     EXPECT_EQ(R2, FromIteratorVPRegion[1]);
650     EXPECT_EQ(R1, FromIteratorVPRegion[2]);
651 
652     // Post-order, VPBasicBlocks only.
653     FromIterator.clear();
654     copy(VPBlockUtils::blocksOnly<VPBasicBlock>(post_order(Start)),
655          std::back_inserter(FromIterator));
656     EXPECT_EQ(FromIterator.size(), 4u);
657     EXPECT_EQ(VPBB2, FromIterator[0]);
658     EXPECT_EQ(R3BB1, FromIterator[1]);
659     EXPECT_EQ(R2BB1, FromIterator[2]);
660     EXPECT_EQ(VPBB1, FromIterator[3]);
661 
662     VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
663   }
664 }
665 
666 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
667 TEST_F(VPBasicBlockTest, print) {
668   VPInstruction *TC = new VPInstruction(Instruction::Add, {});
669   VPlan &Plan = getPlan(TC);
670   VPBasicBlock *VPBB0 = Plan.getEntry();
671   VPBB0->appendRecipe(TC);
672 
673   VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
674   VPInstruction *I2 = new VPInstruction(Instruction::Sub, {I1});
675   VPInstruction *I3 = new VPInstruction(Instruction::Br, {I1, I2});
676 
677   VPBasicBlock *VPBB1 = new VPBasicBlock();
678   VPBB1->appendRecipe(I1);
679   VPBB1->appendRecipe(I2);
680   VPBB1->appendRecipe(I3);
681   VPBB1->setName("bb1");
682 
683   VPInstruction *I4 = new VPInstruction(Instruction::Mul, {I2, I1});
684   VPInstruction *I5 = new VPInstruction(Instruction::Ret, {I4});
685   VPBasicBlock *VPBB2 = new VPBasicBlock();
686   VPBB2->appendRecipe(I4);
687   VPBB2->appendRecipe(I5);
688   VPBB2->setName("bb2");
689 
690   VPBlockUtils::connectBlocks(VPBB1, VPBB2);
691 
692   // Check printing an instruction without associated VPlan.
693   {
694     std::string I3Dump;
695     raw_string_ostream OS(I3Dump);
696     VPSlotTracker SlotTracker;
697     I3->print(OS, "", SlotTracker);
698     EXPECT_EQ("EMIT br <badref>, <badref>", I3Dump);
699   }
700 
701   VPBlockUtils::connectBlocks(VPBB2, Plan.getScalarHeader());
702   VPBlockUtils::connectBlocks(VPBB0, VPBB1);
703   std::string FullDump;
704   raw_string_ostream OS(FullDump);
705   Plan.printDOT(OS);
706 
707   const char *ExpectedStr = R"(digraph VPlan {
708 graph [labelloc=t, fontsize=30; label="Vectorization Plan\n for UF\>=1\nvp\<%1\> = original trip-count\n"]
709 node [shape=rect, fontname=Courier, fontsize=30]
710 edge [fontname=Courier, fontsize=30]
711 compound=true
712   N0 [label =
713     "preheader:\l" +
714     "  EMIT vp\<%1\> = add\l" +
715     "Successor(s): bb1\l"
716   ]
717   N0 -> N1 [ label=""]
718   N1 [label =
719     "bb1:\l" +
720     "  EMIT vp\<%2\> = add\l" +
721     "  EMIT vp\<%3\> = sub vp\<%2\>\l" +
722     "  EMIT br vp\<%2\>, vp\<%3\>\l" +
723     "Successor(s): bb2\l"
724   ]
725   N1 -> N2 [ label=""]
726   N2 [label =
727     "bb2:\l" +
728     "  EMIT vp\<%5\> = mul vp\<%3\>, vp\<%2\>\l" +
729     "  EMIT ret vp\<%5\>\l" +
730     "Successor(s): ir-bb\<scalar.header\>\l"
731   ]
732   N2 -> N3 [ label=""]
733   N3 [label =
734     "ir-bb\<scalar.header\>:\l" +
735     "No successors\l"
736   ]
737 }
738 )";
739   EXPECT_EQ(ExpectedStr, FullDump);
740 
741   const char *ExpectedBlock1Str = R"(bb1:
742   EMIT vp<%2> = add
743   EMIT vp<%3> = sub vp<%2>
744   EMIT br vp<%2>, vp<%3>
745 Successor(s): bb2
746 )";
747   std::string Block1Dump;
748   raw_string_ostream OS1(Block1Dump);
749   VPBB1->print(OS1);
750   EXPECT_EQ(ExpectedBlock1Str, Block1Dump);
751 
752   // Ensure that numbering is good when dumping the second block in isolation.
753   const char *ExpectedBlock2Str = R"(bb2:
754   EMIT vp<%5> = mul vp<%3>, vp<%2>
755   EMIT ret vp<%5>
756 Successor(s): ir-bb<scalar.header>
757 )";
758   std::string Block2Dump;
759   raw_string_ostream OS2(Block2Dump);
760   VPBB2->print(OS2);
761   EXPECT_EQ(ExpectedBlock2Str, Block2Dump);
762 
763   {
764     std::string I3Dump;
765     raw_string_ostream OS(I3Dump);
766     VPSlotTracker SlotTracker(&Plan);
767     I3->print(OS, "", SlotTracker);
768     EXPECT_EQ("EMIT br vp<%2>, vp<%3>", I3Dump);
769   }
770 
771   {
772     std::string I4Dump;
773     raw_string_ostream OS(I4Dump);
774     OS << *I4;
775     EXPECT_EQ("EMIT vp<%5> = mul vp<%3>, vp<%2>", I4Dump);
776   }
777 }
778 
779 TEST_F(VPBasicBlockTest, printPlanWithVFsAndUFs) {
780   VPInstruction *TC = new VPInstruction(Instruction::Sub, {});
781   VPlan &Plan = getPlan(TC);
782   VPBasicBlock *VPBB0 = Plan.getEntry();
783   VPBB0->appendRecipe(TC);
784 
785   VPInstruction *I1 = new VPInstruction(Instruction::Add, {});
786   VPBasicBlock *VPBB1 = new VPBasicBlock();
787   VPBB1->appendRecipe(I1);
788   VPBB1->setName("bb1");
789 
790   VPBlockUtils::connectBlocks(VPBB1, Plan.getScalarHeader());
791   VPBlockUtils::connectBlocks(VPBB0, VPBB1);
792   Plan.setName("TestPlan");
793   Plan.addVF(ElementCount::getFixed(4));
794 
795   {
796     std::string FullDump;
797     raw_string_ostream OS(FullDump);
798     Plan.print(OS);
799 
800     const char *ExpectedStr = R"(VPlan 'TestPlan for VF={4},UF>=1' {
801 vp<%1> = original trip-count
802 
803 preheader:
804   EMIT vp<%1> = sub
805 Successor(s): bb1
806 
807 bb1:
808   EMIT vp<%2> = add
809 Successor(s): ir-bb<scalar.header>
810 
811 ir-bb<scalar.header>:
812 No successors
813 }
814 )";
815     EXPECT_EQ(ExpectedStr, FullDump);
816   }
817 
818   {
819     Plan.addVF(ElementCount::getScalable(8));
820     std::string FullDump;
821     raw_string_ostream OS(FullDump);
822     Plan.print(OS);
823 
824     const char *ExpectedStr = R"(VPlan 'TestPlan for VF={4,vscale x 8},UF>=1' {
825 vp<%1> = original trip-count
826 
827 preheader:
828   EMIT vp<%1> = sub
829 Successor(s): bb1
830 
831 bb1:
832   EMIT vp<%2> = add
833 Successor(s): ir-bb<scalar.header>
834 
835 ir-bb<scalar.header>:
836 No successors
837 }
838 )";
839     EXPECT_EQ(ExpectedStr, FullDump);
840   }
841 
842   {
843     Plan.setUF(4);
844     std::string FullDump;
845     raw_string_ostream OS(FullDump);
846     Plan.print(OS);
847 
848     const char *ExpectedStr = R"(VPlan 'TestPlan for VF={4,vscale x 8},UF={4}' {
849 vp<%1> = original trip-count
850 
851 preheader:
852   EMIT vp<%1> = sub
853 Successor(s): bb1
854 
855 bb1:
856   EMIT vp<%2> = add
857 Successor(s): ir-bb<scalar.header>
858 
859 ir-bb<scalar.header>:
860 No successors
861 }
862 )";
863     EXPECT_EQ(ExpectedStr, FullDump);
864   }
865 }
866 #endif
867 
868 using VPRecipeTest = VPlanTestBase;
869 TEST_F(VPRecipeTest, CastVPInstructionToVPUser) {
870   VPValue Op1;
871   VPValue Op2;
872   VPInstruction Recipe(Instruction::Add, {&Op1, &Op2});
873   EXPECT_TRUE(isa<VPUser>(&Recipe));
874   VPRecipeBase *BaseR = &Recipe;
875   EXPECT_TRUE(isa<VPUser>(BaseR));
876   EXPECT_EQ(&Recipe, BaseR);
877 }
878 
879 TEST_F(VPRecipeTest, CastVPWidenRecipeToVPUser) {
880   IntegerType *Int32 = IntegerType::get(C, 32);
881   auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
882                                        PoisonValue::get(Int32));
883   VPValue Op1;
884   VPValue Op2;
885   SmallVector<VPValue *, 2> Args;
886   Args.push_back(&Op1);
887   Args.push_back(&Op1);
888   VPWidenRecipe WidenR(*AI, make_range(Args.begin(), Args.end()));
889   EXPECT_TRUE(isa<VPUser>(&WidenR));
890   VPRecipeBase *WidenRBase = &WidenR;
891   EXPECT_TRUE(isa<VPUser>(WidenRBase));
892   EXPECT_EQ(&WidenR, WidenRBase);
893   delete AI;
894 }
895 
896 TEST_F(VPRecipeTest, CastVPWidenCallRecipeToVPUserAndVPDef) {
897   IntegerType *Int32 = IntegerType::get(C, 32);
898   FunctionType *FTy = FunctionType::get(Int32, false);
899   Function *Fn = Function::Create(FTy, GlobalValue::ExternalLinkage, 0);
900   auto *Call = CallInst::Create(FTy, Fn);
901   VPValue Op1;
902   VPValue Op2;
903   VPValue CalledFn(Call->getCalledFunction());
904   SmallVector<VPValue *, 2> Args;
905   Args.push_back(&Op1);
906   Args.push_back(&Op2);
907   Args.push_back(&CalledFn);
908   VPWidenCallRecipe Recipe(Call, Fn, Args);
909   EXPECT_TRUE(isa<VPUser>(&Recipe));
910   VPRecipeBase *BaseR = &Recipe;
911   EXPECT_TRUE(isa<VPUser>(BaseR));
912   EXPECT_EQ(&Recipe, BaseR);
913 
914   VPValue *VPV = &Recipe;
915   EXPECT_TRUE(VPV->getDefiningRecipe());
916   EXPECT_EQ(&Recipe, VPV->getDefiningRecipe());
917 
918   delete Call;
919   delete Fn;
920 }
921 
922 TEST_F(VPRecipeTest, CastVPWidenSelectRecipeToVPUserAndVPDef) {
923   IntegerType *Int1 = IntegerType::get(C, 1);
924   IntegerType *Int32 = IntegerType::get(C, 32);
925   auto *SelectI = SelectInst::Create(
926       PoisonValue::get(Int1), PoisonValue::get(Int32), PoisonValue::get(Int32));
927   VPValue Op1;
928   VPValue Op2;
929   VPValue Op3;
930   SmallVector<VPValue *, 4> Args;
931   Args.push_back(&Op1);
932   Args.push_back(&Op2);
933   Args.push_back(&Op3);
934   VPWidenSelectRecipe WidenSelectR(*SelectI,
935                                    make_range(Args.begin(), Args.end()));
936   EXPECT_TRUE(isa<VPUser>(&WidenSelectR));
937   VPRecipeBase *BaseR = &WidenSelectR;
938   EXPECT_TRUE(isa<VPUser>(BaseR));
939   EXPECT_EQ(&WidenSelectR, BaseR);
940 
941   VPValue *VPV = &WidenSelectR;
942   EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
943   EXPECT_EQ(&WidenSelectR, VPV->getDefiningRecipe());
944 
945   delete SelectI;
946 }
947 
948 TEST_F(VPRecipeTest, CastVPWidenGEPRecipeToVPUserAndVPDef) {
949   IntegerType *Int32 = IntegerType::get(C, 32);
950   PointerType *Int32Ptr = PointerType::get(Int32, 0);
951   auto *GEP = GetElementPtrInst::Create(Int32, PoisonValue::get(Int32Ptr),
952                                         PoisonValue::get(Int32));
953   VPValue Op1;
954   VPValue Op2;
955   SmallVector<VPValue *, 4> Args;
956   Args.push_back(&Op1);
957   Args.push_back(&Op2);
958   VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end()));
959   EXPECT_TRUE(isa<VPUser>(&Recipe));
960   VPRecipeBase *BaseR = &Recipe;
961   EXPECT_TRUE(isa<VPUser>(BaseR));
962   EXPECT_EQ(&Recipe, BaseR);
963 
964   VPValue *VPV = &Recipe;
965   EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
966   EXPECT_EQ(&Recipe, VPV->getDefiningRecipe());
967 
968   delete GEP;
969 }
970 
971 TEST_F(VPRecipeTest, CastVPBlendRecipeToVPUser) {
972   IntegerType *Int32 = IntegerType::get(C, 32);
973   auto *Phi = PHINode::Create(Int32, 1);
974   VPValue I1;
975   VPValue I2;
976   VPValue M2;
977   SmallVector<VPValue *, 4> Args;
978   Args.push_back(&I1);
979   Args.push_back(&I2);
980   Args.push_back(&M2);
981   VPBlendRecipe Recipe(Phi, Args);
982   EXPECT_TRUE(isa<VPUser>(&Recipe));
983   VPRecipeBase *BaseR = &Recipe;
984   EXPECT_TRUE(isa<VPUser>(BaseR));
985   delete Phi;
986 }
987 
988 TEST_F(VPRecipeTest, CastVPInterleaveRecipeToVPUser) {
989   VPValue Addr;
990   VPValue Mask;
991   InterleaveGroup<Instruction> IG(4, false, Align(4));
992   VPInterleaveRecipe Recipe(&IG, &Addr, {}, &Mask, false);
993   EXPECT_TRUE(isa<VPUser>(&Recipe));
994   VPRecipeBase *BaseR = &Recipe;
995   EXPECT_TRUE(isa<VPUser>(BaseR));
996   EXPECT_EQ(&Recipe, BaseR);
997 }
998 
999 TEST_F(VPRecipeTest, CastVPReplicateRecipeToVPUser) {
1000   VPValue Op1;
1001   VPValue Op2;
1002   SmallVector<VPValue *, 4> Args;
1003   Args.push_back(&Op1);
1004   Args.push_back(&Op2);
1005 
1006   IntegerType *Int32 = IntegerType::get(C, 32);
1007   FunctionType *FTy = FunctionType::get(Int32, false);
1008   auto *Call = CallInst::Create(FTy, PoisonValue::get(FTy));
1009   VPReplicateRecipe Recipe(Call, make_range(Args.begin(), Args.end()), true);
1010   EXPECT_TRUE(isa<VPUser>(&Recipe));
1011   VPRecipeBase *BaseR = &Recipe;
1012   EXPECT_TRUE(isa<VPUser>(BaseR));
1013   delete Call;
1014 }
1015 
1016 TEST_F(VPRecipeTest, CastVPBranchOnMaskRecipeToVPUser) {
1017   VPValue Mask;
1018   VPBranchOnMaskRecipe Recipe(&Mask);
1019   EXPECT_TRUE(isa<VPUser>(&Recipe));
1020   VPRecipeBase *BaseR = &Recipe;
1021   EXPECT_TRUE(isa<VPUser>(BaseR));
1022   EXPECT_EQ(&Recipe, BaseR);
1023 }
1024 
1025 TEST_F(VPRecipeTest, CastVPWidenMemoryRecipeToVPUserAndVPDef) {
1026   IntegerType *Int32 = IntegerType::get(C, 32);
1027   PointerType *Int32Ptr = PointerType::get(Int32, 0);
1028   auto *Load =
1029       new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1));
1030   VPValue Addr;
1031   VPValue Mask;
1032   VPWidenLoadRecipe Recipe(*Load, &Addr, &Mask, true, false, {});
1033   EXPECT_TRUE(isa<VPUser>(&Recipe));
1034   VPRecipeBase *BaseR = &Recipe;
1035   EXPECT_TRUE(isa<VPUser>(BaseR));
1036   EXPECT_EQ(&Recipe, BaseR);
1037 
1038   VPValue *VPV = Recipe.getVPSingleValue();
1039   EXPECT_TRUE(isa<VPRecipeBase>(VPV->getDefiningRecipe()));
1040   EXPECT_EQ(&Recipe, VPV->getDefiningRecipe());
1041 
1042   delete Load;
1043 }
1044 
1045 TEST_F(VPRecipeTest, MayHaveSideEffectsAndMayReadWriteMemory) {
1046   IntegerType *Int1 = IntegerType::get(C, 1);
1047   IntegerType *Int32 = IntegerType::get(C, 32);
1048   PointerType *Int32Ptr = PointerType::get(Int32, 0);
1049 
1050   {
1051     auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
1052                                          PoisonValue::get(Int32));
1053     VPValue Op1;
1054     VPValue Op2;
1055     SmallVector<VPValue *, 2> Args;
1056     Args.push_back(&Op1);
1057     Args.push_back(&Op1);
1058     VPWidenRecipe Recipe(*AI, make_range(Args.begin(), Args.end()));
1059     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1060     EXPECT_FALSE(Recipe.mayReadFromMemory());
1061     EXPECT_FALSE(Recipe.mayWriteToMemory());
1062     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1063     delete AI;
1064   }
1065 
1066   {
1067     auto *SelectI =
1068         SelectInst::Create(PoisonValue::get(Int1), PoisonValue::get(Int32),
1069                            PoisonValue::get(Int32));
1070     VPValue Op1;
1071     VPValue Op2;
1072     VPValue Op3;
1073     SmallVector<VPValue *, 4> Args;
1074     Args.push_back(&Op1);
1075     Args.push_back(&Op2);
1076     Args.push_back(&Op3);
1077     VPWidenSelectRecipe Recipe(*SelectI, make_range(Args.begin(), Args.end()));
1078     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1079     EXPECT_FALSE(Recipe.mayReadFromMemory());
1080     EXPECT_FALSE(Recipe.mayWriteToMemory());
1081     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1082     delete SelectI;
1083   }
1084 
1085   {
1086     auto *GEP = GetElementPtrInst::Create(Int32, PoisonValue::get(Int32Ptr),
1087                                           PoisonValue::get(Int32));
1088     VPValue Op1;
1089     VPValue Op2;
1090     SmallVector<VPValue *, 4> Args;
1091     Args.push_back(&Op1);
1092     Args.push_back(&Op2);
1093     VPWidenGEPRecipe Recipe(GEP, make_range(Args.begin(), Args.end()));
1094     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1095     EXPECT_FALSE(Recipe.mayReadFromMemory());
1096     EXPECT_FALSE(Recipe.mayWriteToMemory());
1097     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1098     delete GEP;
1099   }
1100 
1101   {
1102     VPValue Mask;
1103     VPBranchOnMaskRecipe Recipe(&Mask);
1104     EXPECT_TRUE(Recipe.mayHaveSideEffects());
1105     EXPECT_FALSE(Recipe.mayReadFromMemory());
1106     EXPECT_FALSE(Recipe.mayWriteToMemory());
1107     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1108   }
1109 
1110   {
1111     VPValue ChainOp;
1112     VPValue VecOp;
1113     VPValue CondOp;
1114     VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, &ChainOp, &CondOp,
1115                              &VecOp, false);
1116     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1117     EXPECT_FALSE(Recipe.mayReadFromMemory());
1118     EXPECT_FALSE(Recipe.mayWriteToMemory());
1119     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1120   }
1121 
1122   {
1123     VPValue ChainOp;
1124     VPValue VecOp;
1125     VPValue CondOp;
1126     VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, &ChainOp, &CondOp,
1127                              &VecOp, false);
1128     VPValue EVL;
1129     VPReductionEVLRecipe EVLRecipe(Recipe, EVL, &CondOp);
1130     EXPECT_FALSE(EVLRecipe.mayHaveSideEffects());
1131     EXPECT_FALSE(EVLRecipe.mayReadFromMemory());
1132     EXPECT_FALSE(EVLRecipe.mayWriteToMemory());
1133     EXPECT_FALSE(EVLRecipe.mayReadOrWriteMemory());
1134   }
1135 
1136   {
1137     auto *Load =
1138         new LoadInst(Int32, PoisonValue::get(Int32Ptr), "", false, Align(1));
1139     VPValue Addr;
1140     VPValue Mask;
1141     VPWidenLoadRecipe Recipe(*Load, &Addr, &Mask, true, false, {});
1142     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1143     EXPECT_TRUE(Recipe.mayReadFromMemory());
1144     EXPECT_FALSE(Recipe.mayWriteToMemory());
1145     EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
1146     delete Load;
1147   }
1148 
1149   {
1150     auto *Store = new StoreInst(PoisonValue::get(Int32),
1151                                 PoisonValue::get(Int32Ptr), false, Align(1));
1152     VPValue Addr;
1153     VPValue Mask;
1154     VPValue StoredV;
1155     VPWidenStoreRecipe Recipe(*Store, &Addr, &StoredV, &Mask, false, false, {});
1156     EXPECT_TRUE(Recipe.mayHaveSideEffects());
1157     EXPECT_FALSE(Recipe.mayReadFromMemory());
1158     EXPECT_TRUE(Recipe.mayWriteToMemory());
1159     EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
1160     delete Store;
1161   }
1162 
1163   {
1164     FunctionType *FTy = FunctionType::get(Int32, false);
1165     Function *Fn = Function::Create(FTy, GlobalValue::ExternalLinkage, 0);
1166     auto *Call = CallInst::Create(FTy, Fn);
1167     VPValue Op1;
1168     VPValue Op2;
1169     VPValue CalledFn(Call->getCalledFunction());
1170     SmallVector<VPValue *, 3> Args;
1171     Args.push_back(&Op1);
1172     Args.push_back(&Op2);
1173     Args.push_back(&CalledFn);
1174     VPWidenCallRecipe Recipe(Call, Fn, Args);
1175     EXPECT_TRUE(Recipe.mayHaveSideEffects());
1176     EXPECT_TRUE(Recipe.mayReadFromMemory());
1177     EXPECT_TRUE(Recipe.mayWriteToMemory());
1178     EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
1179     delete Call;
1180     delete Fn;
1181   }
1182 
1183   {
1184     // Test for a call to a function without side-effects.
1185     Module M("", C);
1186     Function *TheFn =
1187         Intrinsic::getOrInsertDeclaration(&M, Intrinsic::thread_pointer);
1188 
1189     auto *Call = CallInst::Create(TheFn->getFunctionType(), TheFn);
1190     VPValue Op1;
1191     VPValue Op2;
1192     VPValue CalledFn(TheFn);
1193     SmallVector<VPValue *, 3> Args;
1194     Args.push_back(&Op1);
1195     Args.push_back(&Op2);
1196     Args.push_back(&CalledFn);
1197     VPWidenCallRecipe Recipe(Call, TheFn, Args);
1198     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1199     EXPECT_FALSE(Recipe.mayReadFromMemory());
1200     EXPECT_FALSE(Recipe.mayWriteToMemory());
1201     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1202     delete Call;
1203   }
1204 
1205   {
1206     VPValue Op1;
1207     VPValue Op2;
1208     InductionDescriptor IndDesc;
1209     VPScalarIVStepsRecipe Recipe(IndDesc, &Op1, &Op2);
1210     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1211     EXPECT_FALSE(Recipe.mayReadFromMemory());
1212     EXPECT_FALSE(Recipe.mayWriteToMemory());
1213     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1214   }
1215 
1216   // The initial implementation is conservative with respect to VPInstructions.
1217   {
1218     VPValue Op1;
1219     VPValue Op2;
1220     VPInstruction VPInst(Instruction::Add, {&Op1, &Op2});
1221     VPRecipeBase &Recipe = VPInst;
1222     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1223     EXPECT_TRUE(Recipe.mayReadFromMemory());
1224     EXPECT_FALSE(Recipe.mayWriteToMemory());
1225     EXPECT_TRUE(Recipe.mayReadOrWriteMemory());
1226   }
1227   {
1228     VPValue Op1;
1229     VPPredInstPHIRecipe Recipe(&Op1, {});
1230     EXPECT_FALSE(Recipe.mayHaveSideEffects());
1231     EXPECT_FALSE(Recipe.mayReadFromMemory());
1232     EXPECT_FALSE(Recipe.mayWriteToMemory());
1233     EXPECT_FALSE(Recipe.mayReadOrWriteMemory());
1234   }
1235 }
1236 
1237 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1238 TEST_F(VPRecipeTest, dumpRecipeInPlan) {
1239   VPlan &Plan = getPlan();
1240   VPBasicBlock *VPBB0 = Plan.getEntry();
1241   VPBasicBlock *VPBB1 = new VPBasicBlock();
1242   VPBlockUtils::connectBlocks(VPBB1, Plan.getScalarHeader());
1243   VPBlockUtils::connectBlocks(VPBB0, VPBB1);
1244 
1245   IntegerType *Int32 = IntegerType::get(C, 32);
1246   auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
1247                                        PoisonValue::get(Int32));
1248   AI->setName("a");
1249   SmallVector<VPValue *, 2> Args;
1250   VPValue *ExtVPV1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1251   VPValue *ExtVPV2 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 2));
1252   Args.push_back(ExtVPV1);
1253   Args.push_back(ExtVPV2);
1254   VPWidenRecipe *WidenR =
1255       new VPWidenRecipe(*AI, make_range(Args.begin(), Args.end()));
1256   VPBB1->appendRecipe(WidenR);
1257 
1258   {
1259     // Use EXPECT_EXIT to capture stderr and compare against expected output.
1260     //
1261     // Test VPValue::dump().
1262     VPValue *VPV = WidenR;
1263     EXPECT_EXIT(
1264         {
1265           VPV->dump();
1266           exit(0);
1267         },
1268         testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>");
1269 
1270     VPDef *Def = WidenR;
1271     EXPECT_EXIT(
1272         {
1273           Def->dump();
1274           exit(0);
1275         },
1276         testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>");
1277 
1278     EXPECT_EXIT(
1279         {
1280           WidenR->dump();
1281           exit(0);
1282         },
1283         testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>");
1284 
1285     // Test VPRecipeBase::dump().
1286     VPRecipeBase *R = WidenR;
1287     EXPECT_EXIT(
1288         {
1289           R->dump();
1290           exit(0);
1291         },
1292         testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>");
1293 
1294     // Test VPDef::dump().
1295     VPDef *D = WidenR;
1296     EXPECT_EXIT(
1297         {
1298           D->dump();
1299           exit(0);
1300         },
1301         testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>");
1302   }
1303 
1304   delete AI;
1305 }
1306 
1307 TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesInPlan) {
1308   VPlan &Plan = getPlan();
1309   VPBasicBlock *VPBB0 = Plan.getEntry();
1310   VPBasicBlock *VPBB1 = new VPBasicBlock();
1311   VPBlockUtils::connectBlocks(VPBB1, Plan.getScalarHeader());
1312   VPBlockUtils::connectBlocks(VPBB0, VPBB1);
1313 
1314   IntegerType *Int32 = IntegerType::get(C, 32);
1315   auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
1316                                        PoisonValue::get(Int32));
1317   AI->setName("a");
1318   SmallVector<VPValue *, 2> Args;
1319   VPValue *ExtVPV1 = Plan.getOrAddLiveIn(ConstantInt::get(Int32, 1));
1320   VPValue *ExtVPV2 = Plan.getOrAddLiveIn(AI);
1321   Args.push_back(ExtVPV1);
1322   Args.push_back(ExtVPV2);
1323   VPInstruction *I1 = new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2});
1324   VPInstruction *I2 = new VPInstruction(Instruction::Mul, {I1, I1});
1325   VPBB1->appendRecipe(I1);
1326   VPBB1->appendRecipe(I2);
1327 
1328   // Check printing I1.
1329   {
1330     // Use EXPECT_EXIT to capture stderr and compare against expected output.
1331     //
1332     // Test VPValue::dump().
1333     VPValue *VPV = I1;
1334     EXPECT_EXIT(
1335         {
1336           VPV->dump();
1337           exit(0);
1338         },
1339         testing::ExitedWithCode(0), "EMIT vp<%1> = add ir<1>, ir<%a>");
1340 
1341     // Test VPRecipeBase::dump().
1342     VPRecipeBase *R = I1;
1343     EXPECT_EXIT(
1344         {
1345           R->dump();
1346           exit(0);
1347         },
1348         testing::ExitedWithCode(0), "EMIT vp<%1> = add ir<1>, ir<%a>");
1349 
1350     // Test VPDef::dump().
1351     VPDef *D = I1;
1352     EXPECT_EXIT(
1353         {
1354           D->dump();
1355           exit(0);
1356         },
1357         testing::ExitedWithCode(0), "EMIT vp<%1> = add ir<1>, ir<%a>");
1358   }
1359   // Check printing I2.
1360   {
1361     // Use EXPECT_EXIT to capture stderr and compare against expected output.
1362     //
1363     // Test VPValue::dump().
1364     VPValue *VPV = I2;
1365     EXPECT_EXIT(
1366         {
1367           VPV->dump();
1368           exit(0);
1369         },
1370         testing::ExitedWithCode(0), "EMIT vp<%2> = mul vp<%1>, vp<%1>");
1371 
1372     // Test VPRecipeBase::dump().
1373     VPRecipeBase *R = I2;
1374     EXPECT_EXIT(
1375         {
1376           R->dump();
1377           exit(0);
1378         },
1379         testing::ExitedWithCode(0), "EMIT vp<%2> = mul vp<%1>, vp<%1>");
1380 
1381     // Test VPDef::dump().
1382     VPDef *D = I2;
1383     EXPECT_EXIT(
1384         {
1385           D->dump();
1386           exit(0);
1387         },
1388         testing::ExitedWithCode(0), "EMIT vp<%2> = mul vp<%1>, vp<%1>");
1389   }
1390   delete AI;
1391 }
1392 
1393 TEST_F(VPRecipeTest, dumpRecipeUnnamedVPValuesNotInPlanOrBlock) {
1394   IntegerType *Int32 = IntegerType::get(C, 32);
1395   auto *AI = BinaryOperator::CreateAdd(PoisonValue::get(Int32),
1396                                        PoisonValue::get(Int32));
1397   AI->setName("a");
1398   VPValue *ExtVPV1 = new VPValue(ConstantInt::get(Int32, 1));
1399   VPValue *ExtVPV2 = new VPValue(AI);
1400 
1401   VPInstruction *I1 = new VPInstruction(Instruction::Add, {ExtVPV1, ExtVPV2});
1402   VPInstruction *I2 = new VPInstruction(Instruction::Mul, {I1, I1});
1403 
1404   // Check printing I1.
1405   {
1406     // Use EXPECT_EXIT to capture stderr and compare against expected output.
1407     //
1408     // Test VPValue::dump().
1409     VPValue *VPV = I1;
1410     EXPECT_EXIT(
1411         {
1412           VPV->dump();
1413           exit(0);
1414         },
1415         testing::ExitedWithCode(0), "EMIT <badref> = add ir<1>, ir<%a>");
1416 
1417     // Test VPRecipeBase::dump().
1418     VPRecipeBase *R = I1;
1419     EXPECT_EXIT(
1420         {
1421           R->dump();
1422           exit(0);
1423         },
1424         testing::ExitedWithCode(0), "EMIT <badref> = add ir<1>, ir<%a>");
1425 
1426     // Test VPDef::dump().
1427     VPDef *D = I1;
1428     EXPECT_EXIT(
1429         {
1430           D->dump();
1431           exit(0);
1432         },
1433         testing::ExitedWithCode(0), "EMIT <badref> = add ir<1>, ir<%a>");
1434   }
1435   // Check printing I2.
1436   {
1437     // Use EXPECT_EXIT to capture stderr and compare against expected output.
1438     //
1439     // Test VPValue::dump().
1440     VPValue *VPV = I2;
1441     EXPECT_EXIT(
1442         {
1443           VPV->dump();
1444           exit(0);
1445         },
1446         testing::ExitedWithCode(0), "EMIT <badref> = mul <badref>, <badref>");
1447 
1448     // Test VPRecipeBase::dump().
1449     VPRecipeBase *R = I2;
1450     EXPECT_EXIT(
1451         {
1452           R->dump();
1453           exit(0);
1454         },
1455         testing::ExitedWithCode(0), "EMIT <badref> = mul <badref>, <badref>");
1456 
1457     // Test VPDef::dump().
1458     VPDef *D = I2;
1459     EXPECT_EXIT(
1460         {
1461           D->dump();
1462           exit(0);
1463         },
1464         testing::ExitedWithCode(0), "EMIT <badref> = mul <badref>, <badref>");
1465   }
1466 
1467   delete I2;
1468   delete I1;
1469   delete ExtVPV2;
1470   delete ExtVPV1;
1471   delete AI;
1472 }
1473 
1474 #endif
1475 
1476 TEST_F(VPRecipeTest, CastVPReductionRecipeToVPUser) {
1477   VPValue ChainOp;
1478   VPValue VecOp;
1479   VPValue CondOp;
1480   VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, &ChainOp, &CondOp,
1481                            &VecOp, false);
1482   EXPECT_TRUE(isa<VPUser>(&Recipe));
1483   VPRecipeBase *BaseR = &Recipe;
1484   EXPECT_TRUE(isa<VPUser>(BaseR));
1485 }
1486 
1487 TEST_F(VPRecipeTest, CastVPReductionEVLRecipeToVPUser) {
1488   VPValue ChainOp;
1489   VPValue VecOp;
1490   VPValue CondOp;
1491   VPReductionRecipe Recipe(RecurrenceDescriptor(), nullptr, &ChainOp, &CondOp,
1492                            &VecOp, false);
1493   VPValue EVL;
1494   VPReductionEVLRecipe EVLRecipe(Recipe, EVL, &CondOp);
1495   EXPECT_TRUE(isa<VPUser>(&EVLRecipe));
1496   VPRecipeBase *BaseR = &EVLRecipe;
1497   EXPECT_TRUE(isa<VPUser>(BaseR));
1498 }
1499 
1500 struct VPDoubleValueDef : public VPRecipeBase {
1501   VPDoubleValueDef(ArrayRef<VPValue *> Operands) : VPRecipeBase(99, Operands) {
1502     new VPValue(nullptr, this);
1503     new VPValue(nullptr, this);
1504   }
1505 
1506   VPRecipeBase *clone() override { return nullptr; }
1507 
1508   void execute(struct VPTransformState &State) override {}
1509 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1510   void print(raw_ostream &O, const Twine &Indent,
1511              VPSlotTracker &SlotTracker) const override {}
1512 #endif
1513 };
1514 
1515 TEST(VPDoubleValueDefTest, traverseUseLists) {
1516   // Check that the def-use chains of a multi-def can be traversed in both
1517   // directions.
1518 
1519   // Create a new VPDef which defines 2 values and has 2 operands.
1520   VPInstruction Op0(20, {});
1521   VPInstruction Op1(30, {});
1522   VPDoubleValueDef DoubleValueDef({&Op0, &Op1});
1523 
1524   // Create a new users of the defined values.
1525   VPInstruction I1(
1526       1, {DoubleValueDef.getVPValue(0), DoubleValueDef.getVPValue(1)});
1527   VPInstruction I2(2, {DoubleValueDef.getVPValue(0)});
1528   VPInstruction I3(3, {DoubleValueDef.getVPValue(1)});
1529 
1530   // Check operands of the VPDef (traversing upwards).
1531   SmallVector<VPValue *, 4> DoubleOperands(DoubleValueDef.op_begin(),
1532                                            DoubleValueDef.op_end());
1533   EXPECT_EQ(2u, DoubleOperands.size());
1534   EXPECT_EQ(&Op0, DoubleOperands[0]);
1535   EXPECT_EQ(&Op1, DoubleOperands[1]);
1536 
1537   // Check users of the defined values (traversing downwards).
1538   SmallVector<VPUser *, 4> DoubleValueDefV0Users(
1539       DoubleValueDef.getVPValue(0)->user_begin(),
1540       DoubleValueDef.getVPValue(0)->user_end());
1541   EXPECT_EQ(2u, DoubleValueDefV0Users.size());
1542   EXPECT_EQ(&I1, DoubleValueDefV0Users[0]);
1543   EXPECT_EQ(&I2, DoubleValueDefV0Users[1]);
1544 
1545   SmallVector<VPUser *, 4> DoubleValueDefV1Users(
1546       DoubleValueDef.getVPValue(1)->user_begin(),
1547       DoubleValueDef.getVPValue(1)->user_end());
1548   EXPECT_EQ(2u, DoubleValueDefV1Users.size());
1549   EXPECT_EQ(&I1, DoubleValueDefV1Users[0]);
1550   EXPECT_EQ(&I3, DoubleValueDefV1Users[1]);
1551 
1552   // Now check that we can get the right VPDef for each defined value.
1553   EXPECT_EQ(&DoubleValueDef, I1.getOperand(0)->getDefiningRecipe());
1554   EXPECT_EQ(&DoubleValueDef, I1.getOperand(1)->getDefiningRecipe());
1555   EXPECT_EQ(&DoubleValueDef, I2.getOperand(0)->getDefiningRecipe());
1556   EXPECT_EQ(&DoubleValueDef, I3.getOperand(0)->getDefiningRecipe());
1557 }
1558 
1559 TEST_F(VPRecipeTest, CastToVPSingleDefRecipe) {
1560   VPValue Start;
1561   VPEVLBasedIVPHIRecipe R(&Start, {});
1562   VPRecipeBase *B = &R;
1563   EXPECT_TRUE(isa<VPSingleDefRecipe>(B));
1564   // TODO: check other VPSingleDefRecipes.
1565 }
1566 
1567 } // namespace
1568 } // namespace llvm
1569