Recommit "rL366894: [yaml2obj] - Allow custom fields for the SHT_UNDEF sections."
[llvm-complete.git] / unittests / Transforms / Utils / ValueMapperTest.cpp
blob690f4340068422a60ee337ea5f83cd7124f8d6d3
1 //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Transforms/Utils/ValueMapper.h"
10 #include "llvm/IR/Constants.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/GlobalVariable.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Metadata.h"
15 #include "gtest/gtest.h"
17 using namespace llvm;
19 namespace {
21 TEST(ValueMapperTest, mapMDNode) {
22 LLVMContext Context;
23 auto *U = MDTuple::get(Context, None);
25 // The node should be unchanged.
26 ValueToValueMapTy VM;
27 EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U));
30 TEST(ValueMapperTest, mapMDNodeCycle) {
31 LLVMContext Context;
32 MDNode *U0;
33 MDNode *U1;
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();
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));
51 // Cycles shouldn't be duplicated.
53 ValueToValueMapTy VM;
54 EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
55 EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
58 // Check the other order.
60 ValueToValueMapTy VM;
61 EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
62 EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
66 TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) {
67 LLVMContext Context;
68 auto *PtrTy = Type::getInt8Ty(Context)->getPointerTo();
69 std::unique_ptr<GlobalVariable> G0 = llvm::make_unique<GlobalVariable>(
70 PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G0");
71 std::unique_ptr<GlobalVariable> G1 = llvm::make_unique<GlobalVariable>(
72 PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G1");
74 // Create a cycle that references G0.
75 MDNode *N0; // !0 = !{!1}
76 MDNode *N1; // !1 = !{!0, i8* @G0}
78 auto T0 = MDTuple::getTemporary(Context, nullptr);
79 Metadata *Ops1[] = {T0.get(), ConstantAsMetadata::get(G0.get())};
80 N1 = MDTuple::get(Context, Ops1);
81 T0->replaceOperandWith(0, N1);
82 N0 = MDNode::replaceWithUniqued(std::move(T0));
85 // Resolve N0 and N1.
86 ASSERT_FALSE(N0->isResolved());
87 ASSERT_FALSE(N1->isResolved());
88 N0->resolveCycles();
89 ASSERT_TRUE(N0->isResolved());
90 ASSERT_TRUE(N1->isResolved());
92 // Seed the value map to map G0 to G1 and map the nodes. The output should
93 // have new nodes that reference G1 (instead of G0).
94 ValueToValueMapTy VM;
95 VM[G0.get()] = G1.get();
96 MDNode *MappedN0 = ValueMapper(VM).mapMDNode(*N0);
97 MDNode *MappedN1 = ValueMapper(VM).mapMDNode(*N1);
98 EXPECT_NE(N0, MappedN0);
99 EXPECT_NE(N1, MappedN1);
100 EXPECT_EQ(ConstantAsMetadata::get(G1.get()), MappedN1->getOperand(1));
102 // Check that the output nodes are resolved.
103 EXPECT_TRUE(MappedN0->isResolved());
104 EXPECT_TRUE(MappedN1->isResolved());
107 TEST(ValueMapperTest, mapMDNodeUnresolved) {
108 LLVMContext Context;
109 TempMDTuple T = MDTuple::getTemporary(Context, None);
111 ValueToValueMapTy VM;
112 EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T));
115 TEST(ValueMapperTest, mapMDNodeDistinct) {
116 LLVMContext Context;
117 auto *D = MDTuple::getDistinct(Context, None);
120 // The node should be cloned.
121 ValueToValueMapTy VM;
122 EXPECT_NE(D, ValueMapper(VM).mapMDNode(*D));
125 // The node should be moved.
126 ValueToValueMapTy VM;
127 EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
131 TEST(ValueMapperTest, mapMDNodeDistinctOperands) {
132 LLVMContext Context;
133 Metadata *Old = MDTuple::getDistinct(Context, None);
134 auto *D = MDTuple::getDistinct(Context, Old);
135 ASSERT_EQ(Old, D->getOperand(0));
137 Metadata *New = MDTuple::getDistinct(Context, None);
138 ValueToValueMapTy VM;
139 VM.MD()[Old].reset(New);
141 // Make sure operands are updated.
142 EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
143 EXPECT_EQ(New, D->getOperand(0));
146 TEST(ValueMapperTest, mapMDNodeSeeded) {
147 LLVMContext Context;
148 auto *D = MDTuple::getDistinct(Context, None);
150 // The node should be moved.
151 ValueToValueMapTy VM;
152 EXPECT_EQ(None, VM.getMappedMD(D));
154 VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
155 EXPECT_EQ(D, *VM.getMappedMD(D));
156 EXPECT_EQ(D, ValueMapper(VM).mapMDNode(*D));
159 TEST(ValueMapperTest, mapMDNodeSeededWithNull) {
160 LLVMContext Context;
161 auto *D = MDTuple::getDistinct(Context, None);
163 // The node should be moved.
164 ValueToValueMapTy VM;
165 EXPECT_EQ(None, VM.getMappedMD(D));
167 VM.MD().insert(std::make_pair(D, TrackingMDRef()));
168 EXPECT_EQ(nullptr, *VM.getMappedMD(D));
169 EXPECT_EQ(nullptr, ValueMapper(VM).mapMDNode(*D));
172 TEST(ValueMapperTest, mapMetadataNullMapGlobalWithIgnoreMissingLocals) {
173 LLVMContext C;
174 FunctionType *FTy =
175 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
176 std::unique_ptr<Function> F(
177 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
179 ValueToValueMapTy VM;
180 RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
181 EXPECT_EQ(nullptr, ValueMapper(VM, Flags).mapValue(*F));
184 TEST(ValueMapperTest, mapMetadataMDString) {
185 LLVMContext C;
186 auto *S1 = MDString::get(C, "S1");
187 ValueToValueMapTy VM;
189 // Make sure S1 maps to itself, but isn't memoized.
190 EXPECT_EQ(S1, ValueMapper(VM).mapMetadata(*S1));
191 EXPECT_EQ(None, VM.getMappedMD(S1));
193 // We still expect VM.MD() to be respected.
194 auto *S2 = MDString::get(C, "S2");
195 VM.MD()[S1].reset(S2);
196 EXPECT_EQ(S2, ValueMapper(VM).mapMetadata(*S1));
199 TEST(ValueMapperTest, mapMetadataGetMappedMD) {
200 LLVMContext C;
201 auto *N0 = MDTuple::get(C, None);
202 auto *N1 = MDTuple::get(C, N0);
204 // Make sure hasMD and getMappedMD work correctly.
205 ValueToValueMapTy VM;
206 EXPECT_FALSE(VM.hasMD());
207 EXPECT_EQ(N0, ValueMapper(VM).mapMetadata(*N0));
208 EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1));
209 EXPECT_TRUE(VM.hasMD());
210 ASSERT_NE(None, VM.getMappedMD(N0));
211 ASSERT_NE(None, VM.getMappedMD(N1));
212 EXPECT_EQ(N0, *VM.getMappedMD(N0));
213 EXPECT_EQ(N1, *VM.getMappedMD(N1));
216 TEST(ValueMapperTest, mapMetadataNoModuleLevelChanges) {
217 LLVMContext C;
218 auto *N0 = MDTuple::get(C, None);
219 auto *N1 = MDTuple::get(C, N0);
221 // Nothing should be memoized when RF_NoModuleLevelChanges.
222 ValueToValueMapTy VM;
223 EXPECT_FALSE(VM.hasMD());
224 EXPECT_EQ(N0, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0));
225 EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1));
226 EXPECT_FALSE(VM.hasMD());
227 EXPECT_EQ(None, VM.getMappedMD(N0));
228 EXPECT_EQ(None, VM.getMappedMD(N1));
231 TEST(ValueMapperTest, mapMetadataConstantAsMetadata) {
232 LLVMContext C;
233 FunctionType *FTy =
234 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
235 std::unique_ptr<Function> F(
236 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
238 auto *CAM = ConstantAsMetadata::get(F.get());
240 // ConstantAsMetadata shouldn't be memoized.
241 ValueToValueMapTy VM;
242 EXPECT_EQ(CAM, ValueMapper(VM).mapMetadata(*CAM));
243 EXPECT_FALSE(VM.MD().count(CAM));
244 EXPECT_EQ(CAM, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
245 EXPECT_FALSE(VM.MD().count(CAM));
247 // But it should respect a mapping that gets seeded.
248 auto *N = MDTuple::get(C, None);
249 VM.MD()[CAM].reset(N);
250 EXPECT_EQ(N, ValueMapper(VM).mapMetadata(*CAM));
251 EXPECT_EQ(N, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
254 std::unique_ptr<Function> F2(
255 Function::Create(FTy, GlobalValue::ExternalLinkage, "F2"));
256 ValueToValueMapTy VM;
257 VM[F.get()] = F2.get();
258 auto *F2MD = ValueMapper(VM).mapMetadata(*CAM);
259 EXPECT_FALSE(VM.MD().count(CAM));
260 EXPECT_TRUE(F2MD);
261 EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue());
264 #ifdef GTEST_HAS_DEATH_TEST
265 #ifndef NDEBUG
266 TEST(ValueMapperTest, mapMetadataLocalAsMetadata) {
267 LLVMContext C;
268 FunctionType *FTy =
269 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
270 std::unique_ptr<Function> F(
271 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
272 Argument &A = *F->arg_begin();
274 // mapMetadata doesn't support LocalAsMetadata. The only valid container for
275 // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
276 auto *LAM = LocalAsMetadata::get(&A);
277 ValueToValueMapTy VM;
278 EXPECT_DEATH(ValueMapper(VM).mapMetadata(*LAM), "Unexpected local metadata");
279 EXPECT_DEATH(ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*LAM),
280 "Unexpected local metadata");
282 #endif
283 #endif
285 TEST(ValueMapperTest, mapValueLocalAsMetadata) {
286 LLVMContext C;
287 FunctionType *FTy =
288 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
289 std::unique_ptr<Function> F(
290 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
291 Argument &A = *F->arg_begin();
293 auto *LAM = LocalAsMetadata::get(&A);
294 auto *MAV = MetadataAsValue::get(C, LAM);
296 // The principled answer to a LocalAsMetadata of an unmapped SSA value would
297 // be to return nullptr (regardless of RF_IgnoreMissingLocals).
299 // However, algorithms that use RemapInstruction assume that each instruction
300 // only references SSA values from previous instructions. Arguments of
301 // such as "metadata i32 %x" don't currently successfully maintain that
302 // property. To keep RemapInstruction from crashing we need a non-null
303 // return here, but we also shouldn't reference the unmapped local. Use
304 // "metadata !{}".
305 auto *N0 = MDTuple::get(C, None);
306 auto *N0AV = MetadataAsValue::get(C, N0);
307 ValueToValueMapTy VM;
308 EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV));
309 EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
310 EXPECT_FALSE(VM.count(MAV));
311 EXPECT_FALSE(VM.count(&A));
312 EXPECT_EQ(None, VM.getMappedMD(LAM));
314 VM[MAV] = MAV;
315 EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV));
316 EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
317 EXPECT_TRUE(VM.count(MAV));
318 EXPECT_FALSE(VM.count(&A));
320 VM[MAV] = &A;
321 EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV));
322 EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
323 EXPECT_TRUE(VM.count(MAV));
324 EXPECT_FALSE(VM.count(&A));
327 TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) {
328 LLVMContext Context;
329 auto *Int8 = Type::getInt8Ty(Context);
330 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false);
331 std::unique_ptr<Function> F(
332 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
334 // Map a local value to a constant.
335 Argument &A = *F->arg_begin();
336 Constant &C = *ConstantInt::get(Int8, 42);
337 ValueToValueMapTy VM;
338 VM[&A] = &C;
340 // Look up the metadata-as-value wrapper. Don't crash.
341 auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A));
342 auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C));
343 EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata()));
344 EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata()));
345 EXPECT_EQ(&C, ValueMapper(VM).mapValue(A));
346 EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA));
349 } // end namespace