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