xref: /llvm-project/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp (revision 69341e6abca92f7f118ee7bd99be0cdfc649386f)
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/Constants.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Metadata.h"
14 #include "llvm/Transforms/Utils/ValueMapper.h"
15 #include "gtest/gtest.h"
16 
17 using namespace llvm;
18 
19 namespace {
20 
21 TEST(ValueMapperTest, MapMetadata) {
22   LLVMContext Context;
23   auto *U = MDTuple::get(Context, None);
24 
25   // The node should be unchanged.
26   ValueToValueMapTy VM;
27   EXPECT_EQ(U, MapMetadata(U, VM, RF_None));
28 }
29 
30 TEST(ValueMapperTest, MapMetadataCycle) {
31   LLVMContext Context;
32   MDNode *U0;
33   MDNode *U1;
34   {
35     Metadata *Ops[] = {nullptr};
36     auto T = MDTuple::getTemporary(Context, Ops);
37     Ops[0] = T.get();
38     U0 = MDTuple::get(Context, Ops);
39     T->replaceOperandWith(0, U0);
40     U1 = MDNode::replaceWithUniqued(std::move(T));
41     U0->resolveCycles();
42   }
43 
44   EXPECT_TRUE(U0->isResolved());
45   EXPECT_TRUE(U0->isUniqued());
46   EXPECT_TRUE(U1->isResolved());
47   EXPECT_TRUE(U1->isUniqued());
48   EXPECT_EQ(U1, U0->getOperand(0));
49   EXPECT_EQ(U0, U1->getOperand(0));
50 
51   // Cycles shouldn't be duplicated.
52   {
53     ValueToValueMapTy VM;
54     EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
55     EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
56   }
57 
58   // Check the other order.
59   {
60     ValueToValueMapTy VM;
61     EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
62     EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
63   }
64 }
65 
66 TEST(ValueMapperTest, MapMetadataUnresolved) {
67   LLVMContext Context;
68   TempMDTuple T = MDTuple::getTemporary(Context, None);
69 
70   ValueToValueMapTy VM;
71   EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
72 }
73 
74 TEST(ValueMapperTest, MapMetadataDistinct) {
75   LLVMContext Context;
76   auto *D = MDTuple::getDistinct(Context, None);
77 
78   {
79     // The node should be cloned.
80     ValueToValueMapTy VM;
81     EXPECT_NE(D, MapMetadata(D, VM, RF_None));
82   }
83   {
84     // The node should be moved.
85     ValueToValueMapTy VM;
86     EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
87   }
88 }
89 
90 TEST(ValueMapperTest, MapMetadataDistinctOperands) {
91   LLVMContext Context;
92   Metadata *Old = MDTuple::getDistinct(Context, None);
93   auto *D = MDTuple::getDistinct(Context, Old);
94   ASSERT_EQ(Old, D->getOperand(0));
95 
96   Metadata *New = MDTuple::getDistinct(Context, None);
97   ValueToValueMapTy VM;
98   VM.MD()[Old].reset(New);
99 
100   // Make sure operands are updated.
101   EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
102   EXPECT_EQ(New, D->getOperand(0));
103 }
104 
105 TEST(ValueMapperTest, MapMetadataSeeded) {
106   LLVMContext Context;
107   auto *D = MDTuple::getDistinct(Context, None);
108 
109   // The node should be moved.
110   ValueToValueMapTy VM;
111   EXPECT_EQ(None, VM.getMappedMD(D));
112 
113   VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
114   EXPECT_EQ(D, *VM.getMappedMD(D));
115   EXPECT_EQ(D, MapMetadata(D, VM, RF_None));
116 }
117 
118 TEST(ValueMapperTest, MapMetadataSeededWithNull) {
119   LLVMContext Context;
120   auto *D = MDTuple::getDistinct(Context, None);
121 
122   // The node should be moved.
123   ValueToValueMapTy VM;
124   EXPECT_EQ(None, VM.getMappedMD(D));
125 
126   VM.MD().insert(std::make_pair(D, TrackingMDRef()));
127   EXPECT_EQ(nullptr, *VM.getMappedMD(D));
128   EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None));
129 }
130 
131 TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) {
132   LLVMContext C;
133   FunctionType *FTy =
134       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
135   std::unique_ptr<Function> F(
136       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
137 
138   ValueToValueMapTy VM;
139   RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
140   EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags));
141 }
142 
143 TEST(ValueMapperTest, MapMetadataMDString) {
144   LLVMContext C;
145   auto *S1 = MDString::get(C, "S1");
146   ValueToValueMapTy VM;
147 
148   // Make sure S1 maps to itself, but isn't memoized.
149   EXPECT_EQ(S1, MapMetadata(S1, VM));
150   EXPECT_EQ(None, VM.getMappedMD(S1));
151 
152   // We still expect VM.MD() to be respected.
153   auto *S2 = MDString::get(C, "S2");
154   VM.MD()[S1].reset(S2);
155   EXPECT_EQ(S2, MapMetadata(S1, VM));
156 }
157 
158 TEST(ValueMapperTest, MapMetadataGetMappedMD) {
159   LLVMContext C;
160   auto *N0 = MDTuple::get(C, None);
161   auto *N1 = MDTuple::get(C, N0);
162 
163   // Make sure hasMD and getMappedMD work correctly.
164   ValueToValueMapTy VM;
165   EXPECT_FALSE(VM.hasMD());
166   EXPECT_EQ(N0, MapMetadata(N0, VM));
167   EXPECT_EQ(N1, MapMetadata(N1, VM));
168   EXPECT_TRUE(VM.hasMD());
169   ASSERT_NE(None, VM.getMappedMD(N0));
170   ASSERT_NE(None, VM.getMappedMD(N1));
171   EXPECT_EQ(N0, *VM.getMappedMD(N0));
172   EXPECT_EQ(N1, *VM.getMappedMD(N1));
173 }
174 
175 TEST(ValueMapperTest, MapMetadataNoModuleLevelChanges) {
176   LLVMContext C;
177   auto *N0 = MDTuple::get(C, None);
178   auto *N1 = MDTuple::get(C, N0);
179 
180   // Nothing should be memoized when RF_NoModuleLevelChanges.
181   ValueToValueMapTy VM;
182   EXPECT_FALSE(VM.hasMD());
183   EXPECT_EQ(N0, MapMetadata(N0, VM, RF_NoModuleLevelChanges));
184   EXPECT_EQ(N1, MapMetadata(N1, VM, RF_NoModuleLevelChanges));
185   EXPECT_FALSE(VM.hasMD());
186   EXPECT_EQ(None, VM.getMappedMD(N0));
187   EXPECT_EQ(None, VM.getMappedMD(N1));
188 }
189 
190 TEST(ValueMapperTest, MapMetadataConstantAsMetadata) {
191   LLVMContext C;
192   FunctionType *FTy =
193       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
194   std::unique_ptr<Function> F(
195       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
196 
197   auto *CAM = ConstantAsMetadata::get(F.get());
198   {
199     ValueToValueMapTy VM;
200     EXPECT_EQ(CAM, MapMetadata(CAM, VM));
201     EXPECT_TRUE(VM.MD().count(CAM));
202     VM.MD().erase(CAM);
203     EXPECT_EQ(CAM, MapMetadata(CAM, VM, RF_IgnoreMissingLocals));
204     EXPECT_TRUE(VM.MD().count(CAM));
205 
206     auto *N = MDTuple::get(C, None);
207     VM.MD()[CAM].reset(N);
208     EXPECT_EQ(N, MapMetadata(CAM, VM));
209     EXPECT_EQ(N, MapMetadata(CAM, VM, RF_IgnoreMissingLocals));
210   }
211 
212   std::unique_ptr<Function> F2(
213       Function::Create(FTy, GlobalValue::ExternalLinkage, "F2"));
214   ValueToValueMapTy VM;
215   VM[F.get()] = F2.get();
216   auto *F2MD = MapMetadata(CAM, VM);
217   EXPECT_TRUE(VM.MD().count(CAM));
218   EXPECT_TRUE(F2MD);
219   EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue());
220 }
221 
222 #ifdef GTEST_HAS_DEATH_TEST
223 #ifndef NDEBUG
224 TEST(ValueMapperTest, MapMetadataLocalAsMetadata) {
225   LLVMContext C;
226   FunctionType *FTy =
227       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
228   std::unique_ptr<Function> F(
229       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
230   Argument &A = *F->arg_begin();
231 
232   // MapMetadata doesn't support LocalAsMetadata.  The only valid container for
233   // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
234   auto *LAM = LocalAsMetadata::get(&A);
235   ValueToValueMapTy VM;
236   EXPECT_DEATH(MapMetadata(LAM, VM), "Unexpected local metadata");
237   EXPECT_DEATH(MapMetadata(LAM, VM, RF_IgnoreMissingLocals),
238                "Unexpected local metadata");
239 }
240 #endif
241 #endif
242 
243 TEST(ValueMapperTest, MapValueLocalAsMetadata) {
244   LLVMContext C;
245   FunctionType *FTy =
246       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
247   std::unique_ptr<Function> F(
248       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
249   Argument &A = *F->arg_begin();
250 
251   auto *LAM = LocalAsMetadata::get(&A);
252   auto *MAV = MetadataAsValue::get(C, LAM);
253 
254   // The principled answer to a LocalAsMetadata of an unmapped SSA value would
255   // be to return nullptr (regardless of RF_IgnoreMissingLocals).
256   //
257   // However, algorithms that use RemapInstruction assume that each instruction
258   // only references SSA values from previous instructions.  Arguments of
259   // such as "metadata i32 %x" don't currently successfully maintain that
260   // property.  To keep RemapInstruction from crashing we need a non-null
261   // return here, but we also shouldn't reference the unmapped local.  Use
262   // "metadata !{}".
263   auto *N0 = MDTuple::get(C, None);
264   auto *N0AV = MetadataAsValue::get(C, N0);
265   ValueToValueMapTy VM;
266   EXPECT_EQ(N0AV, MapValue(MAV, VM));
267   EXPECT_EQ(nullptr, MapValue(MAV, VM, RF_IgnoreMissingLocals));
268   EXPECT_FALSE(VM.count(MAV));
269   EXPECT_FALSE(VM.count(&A));
270   EXPECT_EQ(None, VM.getMappedMD(LAM));
271 
272   VM[MAV] = MAV;
273   EXPECT_EQ(MAV, MapValue(MAV, VM));
274   EXPECT_EQ(MAV, MapValue(MAV, VM, RF_IgnoreMissingLocals));
275   EXPECT_TRUE(VM.count(MAV));
276   EXPECT_FALSE(VM.count(&A));
277 
278   VM[MAV] = &A;
279   EXPECT_EQ(&A, MapValue(MAV, VM));
280   EXPECT_EQ(&A, MapValue(MAV, VM, RF_IgnoreMissingLocals));
281   EXPECT_TRUE(VM.count(MAV));
282   EXPECT_FALSE(VM.count(&A));
283 }
284 
285 TEST(ValueMapperTest, MapValueLocalAsMetadataToConstant) {
286   LLVMContext Context;
287   auto *Int8 = Type::getInt8Ty(Context);
288   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false);
289   std::unique_ptr<Function> F(
290       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
291 
292   // Map a local value to a constant.
293   Argument &A = *F->arg_begin();
294   Constant &C = *ConstantInt::get(Int8, 42);
295   ValueToValueMapTy VM;
296   VM[&A] = &C;
297 
298   // Look up the metadata-as-value wrapper.  Don't crash.
299   auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A));
300   auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C));
301   EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata()));
302   EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata()));
303   EXPECT_EQ(&C, MapValue(&A, VM));
304   EXPECT_EQ(MDC, MapValue(MDA, VM));
305 }
306 
307 } // end namespace
308