1 //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/IR/LLVMContext.h"
11 #include "llvm/IR/Metadata.h"
12 #include "llvm/Transforms/Utils/ValueMapper.h"
13 #include "gtest/gtest.h"
14 
15 using namespace llvm;
16 
17 namespace {
18 
19 TEST(ValueMapperTest, MapMetadata) {
20   LLVMContext Context;
21   auto *U = MDTuple::get(Context, None);
22 
23   // The node should be unchanged.
24   ValueToValueMapTy VM;
25   EXPECT_EQ(U, MapMetadata(U, VM, RF_None));
26 }
27 
28 TEST(ValueMapperTest, MapMetadataCycle) {
29   LLVMContext Context;
30   MDNode *U0;
31   MDNode *U1;
32   {
33     Metadata *Ops[] = {nullptr};
34     auto T = MDTuple::getTemporary(Context, Ops);
35     Ops[0] = T.get();
36     U0 = MDTuple::get(Context, Ops);
37     T->replaceOperandWith(0, U0);
38     U1 = MDNode::replaceWithUniqued(std::move(T));
39     U0->resolveCycles();
40   }
41 
42   EXPECT_TRUE(U0->isResolved());
43   EXPECT_TRUE(U0->isUniqued());
44   EXPECT_TRUE(U1->isResolved());
45   EXPECT_TRUE(U1->isUniqued());
46   EXPECT_EQ(U1, U0->getOperand(0));
47   EXPECT_EQ(U0, U1->getOperand(0));
48 
49   // Cycles shouldn't be duplicated.
50   {
51     ValueToValueMapTy VM;
52     EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
53     EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
54   }
55 
56   // Check the other order.
57   {
58     ValueToValueMapTy VM;
59     EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
60     EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
61   }
62 }
63 
64 TEST(ValueMapperTest, MapMetadataUnresolved) {
65   LLVMContext Context;
66   TempMDTuple T = MDTuple::getTemporary(Context, None);
67 
68   ValueToValueMapTy VM;
69   EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
70 }
71 
72 TEST(ValueMapperTest, MapMetadataDistinct) {
73   LLVMContext Context;
74   auto *D = MDTuple::getDistinct(Context, None);
75 
76   {
77     // The node should be cloned.
78     ValueToValueMapTy VM;
79     EXPECT_NE(D, MapMetadata(D, VM, RF_None));
80   }
81   {
82     // The node should be moved.
83     ValueToValueMapTy VM;
84     EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
85   }
86 }
87 
88 TEST(ValueMapperTest, MapMetadataDistinctOperands) {
89   LLVMContext Context;
90   Metadata *Old = MDTuple::getDistinct(Context, None);
91   auto *D = MDTuple::getDistinct(Context, Old);
92   ASSERT_EQ(Old, D->getOperand(0));
93 
94   Metadata *New = MDTuple::getDistinct(Context, None);
95   ValueToValueMapTy VM;
96   VM.MD()[Old].reset(New);
97 
98   // Make sure operands are updated.
99   EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
100   EXPECT_EQ(New, D->getOperand(0));
101 }
102 
103 TEST(ValueMapperTest, MapMetadataSeeded) {
104   LLVMContext Context;
105   auto *D = MDTuple::getDistinct(Context, None);
106 
107   // The node should be moved.
108   ValueToValueMapTy VM;
109   EXPECT_EQ(None, VM.getMappedMD(D));
110 
111   VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
112   EXPECT_EQ(D, *VM.getMappedMD(D));
113   EXPECT_EQ(D, MapMetadata(D, VM, RF_None));
114 }
115 
116 TEST(ValueMapperTest, MapMetadataSeededWithNull) {
117   LLVMContext Context;
118   auto *D = MDTuple::getDistinct(Context, None);
119 
120   // The node should be moved.
121   ValueToValueMapTy VM;
122   EXPECT_EQ(None, VM.getMappedMD(D));
123 
124   VM.MD().insert(std::make_pair(D, TrackingMDRef()));
125   EXPECT_EQ(nullptr, *VM.getMappedMD(D));
126   EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None));
127 }
128 
129 } // end namespace
130