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