xref: /llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp (revision 805873148afbbbd2a377340ec647a6c838570aa5)
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/Function.h"
11 #include "llvm/IR/LLVMContext.h"
12 #include "llvm/IR/Metadata.h"
13 #include "llvm/Transforms/Utils/ValueMapper.h"
14 #include "gtest/gtest.h"
15 
16 using namespace llvm;
17 
18 namespace {
19 
20 TEST(ValueMapperTest, MapMetadata) {
21   LLVMContext Context;
22   auto *U = MDTuple::get(Context, None);
23 
24   // The node should be unchanged.
25   ValueToValueMapTy VM;
26   EXPECT_EQ(U, MapMetadata(U, VM, RF_None));
27 }
28 
29 TEST(ValueMapperTest, MapMetadataCycle) {
30   LLVMContext Context;
31   MDNode *U0;
32   MDNode *U1;
33   {
34     Metadata *Ops[] = {nullptr};
35     auto T = MDTuple::getTemporary(Context, Ops);
36     Ops[0] = T.get();
37     U0 = MDTuple::get(Context, Ops);
38     T->replaceOperandWith(0, U0);
39     U1 = MDNode::replaceWithUniqued(std::move(T));
40     U0->resolveCycles();
41   }
42 
43   EXPECT_TRUE(U0->isResolved());
44   EXPECT_TRUE(U0->isUniqued());
45   EXPECT_TRUE(U1->isResolved());
46   EXPECT_TRUE(U1->isUniqued());
47   EXPECT_EQ(U1, U0->getOperand(0));
48   EXPECT_EQ(U0, U1->getOperand(0));
49 
50   // Cycles shouldn't be duplicated.
51   {
52     ValueToValueMapTy VM;
53     EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
54     EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
55   }
56 
57   // Check the other order.
58   {
59     ValueToValueMapTy VM;
60     EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
61     EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
62   }
63 }
64 
65 TEST(ValueMapperTest, MapMetadataUnresolved) {
66   LLVMContext Context;
67   TempMDTuple T = MDTuple::getTemporary(Context, None);
68 
69   ValueToValueMapTy VM;
70   EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
71 }
72 
73 TEST(ValueMapperTest, MapMetadataDistinct) {
74   LLVMContext Context;
75   auto *D = MDTuple::getDistinct(Context, None);
76 
77   {
78     // The node should be cloned.
79     ValueToValueMapTy VM;
80     EXPECT_NE(D, MapMetadata(D, VM, RF_None));
81   }
82   {
83     // The node should be moved.
84     ValueToValueMapTy VM;
85     EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
86   }
87 }
88 
89 TEST(ValueMapperTest, MapMetadataDistinctOperands) {
90   LLVMContext Context;
91   Metadata *Old = MDTuple::getDistinct(Context, None);
92   auto *D = MDTuple::getDistinct(Context, Old);
93   ASSERT_EQ(Old, D->getOperand(0));
94 
95   Metadata *New = MDTuple::getDistinct(Context, None);
96   ValueToValueMapTy VM;
97   VM.MD()[Old].reset(New);
98 
99   // Make sure operands are updated.
100   EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
101   EXPECT_EQ(New, D->getOperand(0));
102 }
103 
104 TEST(ValueMapperTest, MapMetadataSeeded) {
105   LLVMContext Context;
106   auto *D = MDTuple::getDistinct(Context, None);
107 
108   // The node should be moved.
109   ValueToValueMapTy VM;
110   EXPECT_EQ(None, VM.getMappedMD(D));
111 
112   VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
113   EXPECT_EQ(D, *VM.getMappedMD(D));
114   EXPECT_EQ(D, MapMetadata(D, VM, RF_None));
115 }
116 
117 TEST(ValueMapperTest, MapMetadataSeededWithNull) {
118   LLVMContext Context;
119   auto *D = MDTuple::getDistinct(Context, None);
120 
121   // The node should be moved.
122   ValueToValueMapTy VM;
123   EXPECT_EQ(None, VM.getMappedMD(D));
124 
125   VM.MD().insert(std::make_pair(D, TrackingMDRef()));
126   EXPECT_EQ(nullptr, *VM.getMappedMD(D));
127   EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None));
128 }
129 
130 TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) {
131   LLVMContext C;
132   FunctionType *FTy =
133       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
134   std::unique_ptr<Function> F(
135       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
136 
137   ValueToValueMapTy VM;
138   RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
139   EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags));
140 }
141 
142 } // end namespace
143