1170c26d7SDuncan P. N. Exon Smith //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===//
2170c26d7SDuncan P. N. Exon Smith //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6170c26d7SDuncan P. N. Exon Smith //
7170c26d7SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
8170c26d7SDuncan P. N. Exon Smith 
99a67b073SChandler Carruth #include "llvm/Transforms/Utils/ValueMapper.h"
104ec55f8aSDuncan P. N. Exon Smith #include "llvm/IR/Constants.h"
11*32417b32SStephen Tozer #include "llvm/IR/DebugInfoMetadata.h"
12c1e40707SDuncan P. N. Exon Smith #include "llvm/IR/Function.h"
1311f60fd6SDuncan P. N. Exon Smith #include "llvm/IR/GlobalVariable.h"
14170c26d7SDuncan P. N. Exon Smith #include "llvm/IR/LLVMContext.h"
15170c26d7SDuncan P. N. Exon Smith #include "llvm/IR/Metadata.h"
16170c26d7SDuncan P. N. Exon Smith #include "gtest/gtest.h"
17170c26d7SDuncan P. N. Exon Smith 
18170c26d7SDuncan P. N. Exon Smith using namespace llvm;
19170c26d7SDuncan P. N. Exon Smith 
20170c26d7SDuncan P. N. Exon Smith namespace {
21170c26d7SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNode)2239423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNode) {
23ea7df770SDuncan P. N. Exon Smith   LLVMContext Context;
24ea7df770SDuncan P. N. Exon Smith   auto *U = MDTuple::get(Context, None);
25ea7df770SDuncan P. N. Exon Smith 
26ea7df770SDuncan P. N. Exon Smith   // The node should be unchanged.
27ea7df770SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
2839423b02SDuncan P. N. Exon Smith   EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U));
29ea7df770SDuncan P. N. Exon Smith }
30ea7df770SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeCycle)3139423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeCycle) {
32ea7df770SDuncan P. N. Exon Smith   LLVMContext Context;
33ea7df770SDuncan P. N. Exon Smith   MDNode *U0;
34ea7df770SDuncan P. N. Exon Smith   MDNode *U1;
35ea7df770SDuncan P. N. Exon Smith   {
36ea7df770SDuncan P. N. Exon Smith     Metadata *Ops[] = {nullptr};
37ea7df770SDuncan P. N. Exon Smith     auto T = MDTuple::getTemporary(Context, Ops);
38ea7df770SDuncan P. N. Exon Smith     Ops[0] = T.get();
39ea7df770SDuncan P. N. Exon Smith     U0 = MDTuple::get(Context, Ops);
40ea7df770SDuncan P. N. Exon Smith     T->replaceOperandWith(0, U0);
41ea7df770SDuncan P. N. Exon Smith     U1 = MDNode::replaceWithUniqued(std::move(T));
42ea7df770SDuncan P. N. Exon Smith     U0->resolveCycles();
43ea7df770SDuncan P. N. Exon Smith   }
44ea7df770SDuncan P. N. Exon Smith 
45ea7df770SDuncan P. N. Exon Smith   EXPECT_TRUE(U0->isResolved());
46ea7df770SDuncan P. N. Exon Smith   EXPECT_TRUE(U0->isUniqued());
47ea7df770SDuncan P. N. Exon Smith   EXPECT_TRUE(U1->isResolved());
48ea7df770SDuncan P. N. Exon Smith   EXPECT_TRUE(U1->isUniqued());
49ea7df770SDuncan P. N. Exon Smith   EXPECT_EQ(U1, U0->getOperand(0));
50ea7df770SDuncan P. N. Exon Smith   EXPECT_EQ(U0, U1->getOperand(0));
51ea7df770SDuncan P. N. Exon Smith 
52ea7df770SDuncan P. N. Exon Smith   // Cycles shouldn't be duplicated.
53ea7df770SDuncan P. N. Exon Smith   {
54ea7df770SDuncan P. N. Exon Smith     ValueToValueMapTy VM;
5539423b02SDuncan P. N. Exon Smith     EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
5639423b02SDuncan P. N. Exon Smith     EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
57ea7df770SDuncan P. N. Exon Smith   }
58ea7df770SDuncan P. N. Exon Smith 
59ea7df770SDuncan P. N. Exon Smith   // Check the other order.
60ea7df770SDuncan P. N. Exon Smith   {
61ea7df770SDuncan P. N. Exon Smith     ValueToValueMapTy VM;
6239423b02SDuncan P. N. Exon Smith     EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
6339423b02SDuncan P. N. Exon Smith     EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
64ea7df770SDuncan P. N. Exon Smith   }
65ea7df770SDuncan P. N. Exon Smith }
66ea7df770SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeDuplicatedCycle)6739423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) {
6811f60fd6SDuncan P. N. Exon Smith   LLVMContext Context;
6911f60fd6SDuncan P. N. Exon Smith   auto *PtrTy = Type::getInt8Ty(Context)->getPointerTo();
700eaee545SJonas Devlieghere   std::unique_ptr<GlobalVariable> G0 = std::make_unique<GlobalVariable>(
7111f60fd6SDuncan P. N. Exon Smith       PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G0");
720eaee545SJonas Devlieghere   std::unique_ptr<GlobalVariable> G1 = std::make_unique<GlobalVariable>(
7311f60fd6SDuncan P. N. Exon Smith       PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G1");
7411f60fd6SDuncan P. N. Exon Smith 
7511f60fd6SDuncan P. N. Exon Smith   // Create a cycle that references G0.
7611f60fd6SDuncan P. N. Exon Smith   MDNode *N0; // !0 = !{!1}
7711f60fd6SDuncan P. N. Exon Smith   MDNode *N1; // !1 = !{!0, i8* @G0}
7811f60fd6SDuncan P. N. Exon Smith   {
7911f60fd6SDuncan P. N. Exon Smith     auto T0 = MDTuple::getTemporary(Context, nullptr);
8011f60fd6SDuncan P. N. Exon Smith     Metadata *Ops1[] = {T0.get(), ConstantAsMetadata::get(G0.get())};
8111f60fd6SDuncan P. N. Exon Smith     N1 = MDTuple::get(Context, Ops1);
8211f60fd6SDuncan P. N. Exon Smith     T0->replaceOperandWith(0, N1);
8311f60fd6SDuncan P. N. Exon Smith     N0 = MDNode::replaceWithUniqued(std::move(T0));
8411f60fd6SDuncan P. N. Exon Smith   }
8511f60fd6SDuncan P. N. Exon Smith 
8611f60fd6SDuncan P. N. Exon Smith   // Resolve N0 and N1.
8711f60fd6SDuncan P. N. Exon Smith   ASSERT_FALSE(N0->isResolved());
8811f60fd6SDuncan P. N. Exon Smith   ASSERT_FALSE(N1->isResolved());
8911f60fd6SDuncan P. N. Exon Smith   N0->resolveCycles();
9011f60fd6SDuncan P. N. Exon Smith   ASSERT_TRUE(N0->isResolved());
9111f60fd6SDuncan P. N. Exon Smith   ASSERT_TRUE(N1->isResolved());
9211f60fd6SDuncan P. N. Exon Smith 
9311f60fd6SDuncan P. N. Exon Smith   // Seed the value map to map G0 to G1 and map the nodes.  The output should
9411f60fd6SDuncan P. N. Exon Smith   // have new nodes that reference G1 (instead of G0).
9511f60fd6SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
9611f60fd6SDuncan P. N. Exon Smith   VM[G0.get()] = G1.get();
9739423b02SDuncan P. N. Exon Smith   MDNode *MappedN0 = ValueMapper(VM).mapMDNode(*N0);
9839423b02SDuncan P. N. Exon Smith   MDNode *MappedN1 = ValueMapper(VM).mapMDNode(*N1);
9911f60fd6SDuncan P. N. Exon Smith   EXPECT_NE(N0, MappedN0);
10011f60fd6SDuncan P. N. Exon Smith   EXPECT_NE(N1, MappedN1);
10111f60fd6SDuncan P. N. Exon Smith   EXPECT_EQ(ConstantAsMetadata::get(G1.get()), MappedN1->getOperand(1));
10211f60fd6SDuncan P. N. Exon Smith 
10311f60fd6SDuncan P. N. Exon Smith   // Check that the output nodes are resolved.
10411f60fd6SDuncan P. N. Exon Smith   EXPECT_TRUE(MappedN0->isResolved());
10511f60fd6SDuncan P. N. Exon Smith   EXPECT_TRUE(MappedN1->isResolved());
10611f60fd6SDuncan P. N. Exon Smith }
10711f60fd6SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeUnresolved)10839423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeUnresolved) {
109170c26d7SDuncan P. N. Exon Smith   LLVMContext Context;
110170c26d7SDuncan P. N. Exon Smith   TempMDTuple T = MDTuple::getTemporary(Context, None);
111170c26d7SDuncan P. N. Exon Smith 
112170c26d7SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
11339423b02SDuncan P. N. Exon Smith   EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T));
114170c26d7SDuncan P. N. Exon Smith }
115170c26d7SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeDistinct)11639423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeDistinct) {
1174fb46cb8SDuncan P. N. Exon Smith   LLVMContext Context;
1184fb46cb8SDuncan P. N. Exon Smith   auto *D = MDTuple::getDistinct(Context, None);
1194fb46cb8SDuncan P. N. Exon Smith 
1204fb46cb8SDuncan P. N. Exon Smith   {
1214fb46cb8SDuncan P. N. Exon Smith     // The node should be cloned.
1224fb46cb8SDuncan P. N. Exon Smith     ValueToValueMapTy VM;
12339423b02SDuncan P. N. Exon Smith     EXPECT_NE(D, ValueMapper(VM).mapMDNode(*D));
1244fb46cb8SDuncan P. N. Exon Smith   }
1254fb46cb8SDuncan P. N. Exon Smith   {
1264fb46cb8SDuncan P. N. Exon Smith     // The node should be moved.
1274fb46cb8SDuncan P. N. Exon Smith     ValueToValueMapTy VM;
128fa35c1f8SDuncan P. N. Exon Smith     EXPECT_EQ(D, ValueMapper(VM, RF_ReuseAndMutateDistinctMDs).mapMDNode(*D));
1294fb46cb8SDuncan P. N. Exon Smith   }
1304fb46cb8SDuncan P. N. Exon Smith }
1314fb46cb8SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeDistinctOperands)13239423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeDistinctOperands) {
1334fb46cb8SDuncan P. N. Exon Smith   LLVMContext Context;
1344fb46cb8SDuncan P. N. Exon Smith   Metadata *Old = MDTuple::getDistinct(Context, None);
1354fb46cb8SDuncan P. N. Exon Smith   auto *D = MDTuple::getDistinct(Context, Old);
1364fb46cb8SDuncan P. N. Exon Smith   ASSERT_EQ(Old, D->getOperand(0));
1374fb46cb8SDuncan P. N. Exon Smith 
1384fb46cb8SDuncan P. N. Exon Smith   Metadata *New = MDTuple::getDistinct(Context, None);
1394fb46cb8SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
1404fb46cb8SDuncan P. N. Exon Smith   VM.MD()[Old].reset(New);
1414fb46cb8SDuncan P. N. Exon Smith 
1424fb46cb8SDuncan P. N. Exon Smith   // Make sure operands are updated.
143fa35c1f8SDuncan P. N. Exon Smith   EXPECT_EQ(D, ValueMapper(VM, RF_ReuseAndMutateDistinctMDs).mapMDNode(*D));
1444fb46cb8SDuncan P. N. Exon Smith   EXPECT_EQ(New, D->getOperand(0));
1454fb46cb8SDuncan P. N. Exon Smith }
1464fb46cb8SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeSeeded)14739423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeSeeded) {
148da4a56d1SDuncan P. N. Exon Smith   LLVMContext Context;
149da4a56d1SDuncan P. N. Exon Smith   auto *D = MDTuple::getDistinct(Context, None);
150da4a56d1SDuncan P. N. Exon Smith 
151da4a56d1SDuncan P. N. Exon Smith   // The node should be moved.
152da4a56d1SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
153da4a56d1SDuncan P. N. Exon Smith   EXPECT_EQ(None, VM.getMappedMD(D));
154da4a56d1SDuncan P. N. Exon Smith 
155da4a56d1SDuncan P. N. Exon Smith   VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
156da4a56d1SDuncan P. N. Exon Smith   EXPECT_EQ(D, *VM.getMappedMD(D));
15739423b02SDuncan P. N. Exon Smith   EXPECT_EQ(D, ValueMapper(VM).mapMDNode(*D));
158da4a56d1SDuncan P. N. Exon Smith }
159da4a56d1SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMDNodeSeededWithNull)16039423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMDNodeSeededWithNull) {
161da4a56d1SDuncan P. N. Exon Smith   LLVMContext Context;
162da4a56d1SDuncan P. N. Exon Smith   auto *D = MDTuple::getDistinct(Context, None);
163da4a56d1SDuncan P. N. Exon Smith 
164da4a56d1SDuncan P. N. Exon Smith   // The node should be moved.
165da4a56d1SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
166da4a56d1SDuncan P. N. Exon Smith   EXPECT_EQ(None, VM.getMappedMD(D));
167da4a56d1SDuncan P. N. Exon Smith 
168da4a56d1SDuncan P. N. Exon Smith   VM.MD().insert(std::make_pair(D, TrackingMDRef()));
169da4a56d1SDuncan P. N. Exon Smith   EXPECT_EQ(nullptr, *VM.getMappedMD(D));
17039423b02SDuncan P. N. Exon Smith   EXPECT_EQ(nullptr, ValueMapper(VM).mapMDNode(*D));
171da4a56d1SDuncan P. N. Exon Smith }
172da4a56d1SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMetadataNullMapGlobalWithIgnoreMissingLocals)17339423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMetadataNullMapGlobalWithIgnoreMissingLocals) {
174fdccad92SDuncan P. N. Exon Smith   LLVMContext C;
175fdccad92SDuncan P. N. Exon Smith   FunctionType *FTy =
176fdccad92SDuncan P. N. Exon Smith       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
177fdccad92SDuncan P. N. Exon Smith   std::unique_ptr<Function> F(
178fdccad92SDuncan P. N. Exon Smith       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
179fdccad92SDuncan P. N. Exon Smith 
180fdccad92SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
181fdccad92SDuncan P. N. Exon Smith   RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
18239423b02SDuncan P. N. Exon Smith   EXPECT_EQ(nullptr, ValueMapper(VM, Flags).mapValue(*F));
183fdccad92SDuncan P. N. Exon Smith }
184fdccad92SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMetadataMDString)18539423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMetadataMDString) {
186e05ff7c1SDuncan P. N. Exon Smith   LLVMContext C;
187e05ff7c1SDuncan P. N. Exon Smith   auto *S1 = MDString::get(C, "S1");
188e05ff7c1SDuncan P. N. Exon Smith   ValueToValueMapTy VM;
189e05ff7c1SDuncan P. N. Exon Smith 
190e05ff7c1SDuncan P. N. Exon Smith   // Make sure S1 maps to itself, but isn't memoized.
19139423b02SDuncan P. N. Exon Smith   EXPECT_EQ(S1, ValueMapper(VM).mapMetadata(*S1));
192e05ff7c1SDuncan P. N. Exon Smith   EXPECT_EQ(None, VM.getMappedMD(S1));
193e05ff7c1SDuncan P. N. Exon Smith 
194e05ff7c1SDuncan P. N. Exon Smith   // We still expect VM.MD() to be respected.
195e05ff7c1SDuncan P. N. Exon Smith   auto *S2 = MDString::get(C, "S2");
196e05ff7c1SDuncan P. N. Exon Smith   VM.MD()[S1].reset(S2);
19739423b02SDuncan P. N. Exon Smith   EXPECT_EQ(S2, ValueMapper(VM).mapMetadata(*S1));
198e05ff7c1SDuncan P. N. Exon Smith }
199e05ff7c1SDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMetadataGetMappedMD)20039423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMetadataGetMappedMD) {
20169341e6aSDuncan P. N. Exon Smith   LLVMContext C;
20269341e6aSDuncan P. N. Exon Smith   auto *N0 = MDTuple::get(C, None);
20369341e6aSDuncan P. N. Exon Smith   auto *N1 = MDTuple::get(C, N0);
20469341e6aSDuncan P. N. Exon Smith 
20569341e6aSDuncan P. N. Exon Smith   // Make sure hasMD and getMappedMD work correctly.
20669341e6aSDuncan P. N. Exon Smith   ValueToValueMapTy VM;
20769341e6aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.hasMD());
20839423b02SDuncan P. N. Exon Smith   EXPECT_EQ(N0, ValueMapper(VM).mapMetadata(*N0));
20939423b02SDuncan P. N. Exon Smith   EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1));
21069341e6aSDuncan P. N. Exon Smith   EXPECT_TRUE(VM.hasMD());
21169341e6aSDuncan P. N. Exon Smith   ASSERT_NE(None, VM.getMappedMD(N0));
21269341e6aSDuncan P. N. Exon Smith   ASSERT_NE(None, VM.getMappedMD(N1));
21369341e6aSDuncan P. N. Exon Smith   EXPECT_EQ(N0, *VM.getMappedMD(N0));
21469341e6aSDuncan P. N. Exon Smith   EXPECT_EQ(N1, *VM.getMappedMD(N1));
21569341e6aSDuncan P. N. Exon Smith }
21669341e6aSDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMetadataNoModuleLevelChanges)21739423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMetadataNoModuleLevelChanges) {
21869341e6aSDuncan P. N. Exon Smith   LLVMContext C;
21969341e6aSDuncan P. N. Exon Smith   auto *N0 = MDTuple::get(C, None);
22069341e6aSDuncan P. N. Exon Smith   auto *N1 = MDTuple::get(C, N0);
22169341e6aSDuncan P. N. Exon Smith 
22269341e6aSDuncan P. N. Exon Smith   // Nothing should be memoized when RF_NoModuleLevelChanges.
22369341e6aSDuncan P. N. Exon Smith   ValueToValueMapTy VM;
22469341e6aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.hasMD());
22539423b02SDuncan P. N. Exon Smith   EXPECT_EQ(N0, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0));
22639423b02SDuncan P. N. Exon Smith   EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1));
22769341e6aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.hasMD());
22869341e6aSDuncan P. N. Exon Smith   EXPECT_EQ(None, VM.getMappedMD(N0));
22969341e6aSDuncan P. N. Exon Smith   EXPECT_EQ(None, VM.getMappedMD(N1));
23069341e6aSDuncan P. N. Exon Smith }
23169341e6aSDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapMetadataConstantAsMetadata)23239423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMetadataConstantAsMetadata) {
2334ec55f8aSDuncan P. N. Exon Smith   LLVMContext C;
2344ec55f8aSDuncan P. N. Exon Smith   FunctionType *FTy =
2354ec55f8aSDuncan P. N. Exon Smith       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
2364ec55f8aSDuncan P. N. Exon Smith   std::unique_ptr<Function> F(
2374ec55f8aSDuncan P. N. Exon Smith       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
2384ec55f8aSDuncan P. N. Exon Smith 
2394ec55f8aSDuncan P. N. Exon Smith   auto *CAM = ConstantAsMetadata::get(F.get());
2404ec55f8aSDuncan P. N. Exon Smith   {
241a77d0733SDuncan P. N. Exon Smith     // ConstantAsMetadata shouldn't be memoized.
2424ec55f8aSDuncan P. N. Exon Smith     ValueToValueMapTy VM;
24339423b02SDuncan P. N. Exon Smith     EXPECT_EQ(CAM, ValueMapper(VM).mapMetadata(*CAM));
244a77d0733SDuncan P. N. Exon Smith     EXPECT_FALSE(VM.MD().count(CAM));
24539423b02SDuncan P. N. Exon Smith     EXPECT_EQ(CAM, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
246a77d0733SDuncan P. N. Exon Smith     EXPECT_FALSE(VM.MD().count(CAM));
2474ec55f8aSDuncan P. N. Exon Smith 
248a77d0733SDuncan P. N. Exon Smith     // But it should respect a mapping that gets seeded.
2494ec55f8aSDuncan P. N. Exon Smith     auto *N = MDTuple::get(C, None);
2504ec55f8aSDuncan P. N. Exon Smith     VM.MD()[CAM].reset(N);
25139423b02SDuncan P. N. Exon Smith     EXPECT_EQ(N, ValueMapper(VM).mapMetadata(*CAM));
25239423b02SDuncan P. N. Exon Smith     EXPECT_EQ(N, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
2534ec55f8aSDuncan P. N. Exon Smith   }
2544ec55f8aSDuncan P. N. Exon Smith 
2554ec55f8aSDuncan P. N. Exon Smith   std::unique_ptr<Function> F2(
2564ec55f8aSDuncan P. N. Exon Smith       Function::Create(FTy, GlobalValue::ExternalLinkage, "F2"));
2574ec55f8aSDuncan P. N. Exon Smith   ValueToValueMapTy VM;
2584ec55f8aSDuncan P. N. Exon Smith   VM[F.get()] = F2.get();
25939423b02SDuncan P. N. Exon Smith   auto *F2MD = ValueMapper(VM).mapMetadata(*CAM);
260a77d0733SDuncan P. N. Exon Smith   EXPECT_FALSE(VM.MD().count(CAM));
2614ec55f8aSDuncan P. N. Exon Smith   EXPECT_TRUE(F2MD);
2624ec55f8aSDuncan P. N. Exon Smith   EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue());
2634ec55f8aSDuncan P. N. Exon Smith }
2644ec55f8aSDuncan P. N. Exon Smith 
2654ec55f8aSDuncan P. N. Exon Smith #ifdef GTEST_HAS_DEATH_TEST
2664ec55f8aSDuncan P. N. Exon Smith #ifndef NDEBUG
TEST(ValueMapperTest,mapMetadataLocalAsMetadata)26739423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapMetadataLocalAsMetadata) {
2684ec55f8aSDuncan P. N. Exon Smith   LLVMContext C;
2694ec55f8aSDuncan P. N. Exon Smith   FunctionType *FTy =
2704ec55f8aSDuncan P. N. Exon Smith       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
2714ec55f8aSDuncan P. N. Exon Smith   std::unique_ptr<Function> F(
2724ec55f8aSDuncan P. N. Exon Smith       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
2734ec55f8aSDuncan P. N. Exon Smith   Argument &A = *F->arg_begin();
2744ec55f8aSDuncan P. N. Exon Smith 
27539423b02SDuncan P. N. Exon Smith   // mapMetadata doesn't support LocalAsMetadata.  The only valid container for
2764ec55f8aSDuncan P. N. Exon Smith   // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
2774ec55f8aSDuncan P. N. Exon Smith   auto *LAM = LocalAsMetadata::get(&A);
2784ec55f8aSDuncan P. N. Exon Smith   ValueToValueMapTy VM;
27939423b02SDuncan P. N. Exon Smith   EXPECT_DEATH(ValueMapper(VM).mapMetadata(*LAM), "Unexpected local metadata");
28039423b02SDuncan P. N. Exon Smith   EXPECT_DEATH(ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*LAM),
2814ec55f8aSDuncan P. N. Exon Smith                "Unexpected local metadata");
2824ec55f8aSDuncan P. N. Exon Smith }
2834ec55f8aSDuncan P. N. Exon Smith #endif
2844ec55f8aSDuncan P. N. Exon Smith #endif
2854ec55f8aSDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapValueLocalAsMetadata)28639423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapValueLocalAsMetadata) {
2874ec55f8aSDuncan P. N. Exon Smith   LLVMContext C;
2884ec55f8aSDuncan P. N. Exon Smith   FunctionType *FTy =
2894ec55f8aSDuncan P. N. Exon Smith       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
2904ec55f8aSDuncan P. N. Exon Smith   std::unique_ptr<Function> F(
2914ec55f8aSDuncan P. N. Exon Smith       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
2924ec55f8aSDuncan P. N. Exon Smith   Argument &A = *F->arg_begin();
2934ec55f8aSDuncan P. N. Exon Smith 
2944ec55f8aSDuncan P. N. Exon Smith   auto *LAM = LocalAsMetadata::get(&A);
2954ec55f8aSDuncan P. N. Exon Smith   auto *MAV = MetadataAsValue::get(C, LAM);
2964ec55f8aSDuncan P. N. Exon Smith 
2974ec55f8aSDuncan P. N. Exon Smith   // The principled answer to a LocalAsMetadata of an unmapped SSA value would
2984ec55f8aSDuncan P. N. Exon Smith   // be to return nullptr (regardless of RF_IgnoreMissingLocals).
2994ec55f8aSDuncan P. N. Exon Smith   //
3004ec55f8aSDuncan P. N. Exon Smith   // However, algorithms that use RemapInstruction assume that each instruction
3014ec55f8aSDuncan P. N. Exon Smith   // only references SSA values from previous instructions.  Arguments of
3024ec55f8aSDuncan P. N. Exon Smith   // such as "metadata i32 %x" don't currently successfully maintain that
3034ec55f8aSDuncan P. N. Exon Smith   // property.  To keep RemapInstruction from crashing we need a non-null
3044ec55f8aSDuncan P. N. Exon Smith   // return here, but we also shouldn't reference the unmapped local.  Use
3054ec55f8aSDuncan P. N. Exon Smith   // "metadata !{}".
3064ec55f8aSDuncan P. N. Exon Smith   auto *N0 = MDTuple::get(C, None);
3074ec55f8aSDuncan P. N. Exon Smith   auto *N0AV = MetadataAsValue::get(C, N0);
3084ec55f8aSDuncan P. N. Exon Smith   ValueToValueMapTy VM;
30939423b02SDuncan P. N. Exon Smith   EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV));
31039423b02SDuncan P. N. Exon Smith   EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
3114ec55f8aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.count(MAV));
3124ec55f8aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.count(&A));
3134ec55f8aSDuncan P. N. Exon Smith   EXPECT_EQ(None, VM.getMappedMD(LAM));
3144ec55f8aSDuncan P. N. Exon Smith 
3154ec55f8aSDuncan P. N. Exon Smith   VM[MAV] = MAV;
31639423b02SDuncan P. N. Exon Smith   EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV));
31739423b02SDuncan P. N. Exon Smith   EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
3184ec55f8aSDuncan P. N. Exon Smith   EXPECT_TRUE(VM.count(MAV));
3194ec55f8aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.count(&A));
3204ec55f8aSDuncan P. N. Exon Smith 
3214ec55f8aSDuncan P. N. Exon Smith   VM[MAV] = &A;
32239423b02SDuncan P. N. Exon Smith   EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV));
32339423b02SDuncan P. N. Exon Smith   EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
3244ec55f8aSDuncan P. N. Exon Smith   EXPECT_TRUE(VM.count(MAV));
3254ec55f8aSDuncan P. N. Exon Smith   EXPECT_FALSE(VM.count(&A));
3264ec55f8aSDuncan P. N. Exon Smith }
3274ec55f8aSDuncan P. N. Exon Smith 
TEST(ValueMapperTest,mapValueLocalInArgList)328*32417b32SStephen Tozer TEST(ValueMapperTest, mapValueLocalInArgList) {
329*32417b32SStephen Tozer   LLVMContext C;
330*32417b32SStephen Tozer   FunctionType *FTy =
331*32417b32SStephen Tozer       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
332*32417b32SStephen Tozer   std::unique_ptr<Function> F(
333*32417b32SStephen Tozer       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
334*32417b32SStephen Tozer   Argument &A = *F->arg_begin();
335*32417b32SStephen Tozer 
336*32417b32SStephen Tozer   auto *LAM = LocalAsMetadata::get(&A);
337*32417b32SStephen Tozer   std::vector<ValueAsMetadata*> Elts;
338*32417b32SStephen Tozer   Elts.push_back(LAM);
339*32417b32SStephen Tozer   auto *ArgList = DIArgList::get(C, Elts);
340*32417b32SStephen Tozer   auto *MAV = MetadataAsValue::get(C, ArgList);
341*32417b32SStephen Tozer 
342*32417b32SStephen Tozer   // The principled answer to a LocalAsMetadata of an unmapped SSA value would
343*32417b32SStephen Tozer   // be to return nullptr (regardless of RF_IgnoreMissingLocals).
344*32417b32SStephen Tozer   //
345*32417b32SStephen Tozer   // However, algorithms that use RemapInstruction assume that each instruction
346*32417b32SStephen Tozer   // only references SSA values from previous instructions.  Arguments of
347*32417b32SStephen Tozer   // such as "metadata i32 %x" don't currently successfully maintain that
348*32417b32SStephen Tozer   // property.  To keep RemapInstruction from crashing we need a non-null
349*32417b32SStephen Tozer   // return here, but we also shouldn't reference the unmapped local.  Use
350*32417b32SStephen Tozer   // undef for uses in a DIArgList.
351*32417b32SStephen Tozer   auto *N0 = UndefValue::get(Type::getInt8Ty(C));
352*32417b32SStephen Tozer   auto *N0AM = ValueAsMetadata::get(N0);
353*32417b32SStephen Tozer   std::vector<ValueAsMetadata*> N0Elts;
354*32417b32SStephen Tozer   N0Elts.push_back(N0AM);
355*32417b32SStephen Tozer   auto *N0ArgList = DIArgList::get(C, N0Elts);
356*32417b32SStephen Tozer   auto *N0AV = MetadataAsValue::get(C, N0ArgList);
357*32417b32SStephen Tozer   ValueToValueMapTy VM;
358*32417b32SStephen Tozer   EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV));
359*32417b32SStephen Tozer   EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
360*32417b32SStephen Tozer   EXPECT_FALSE(VM.count(MAV));
361*32417b32SStephen Tozer   EXPECT_FALSE(VM.count(&A));
362*32417b32SStephen Tozer   EXPECT_EQ(None, VM.getMappedMD(LAM));
363*32417b32SStephen Tozer   EXPECT_EQ(None, VM.getMappedMD(ArgList));
364*32417b32SStephen Tozer 
365*32417b32SStephen Tozer   VM[MAV] = MAV;
366*32417b32SStephen Tozer   EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV));
367*32417b32SStephen Tozer   EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
368*32417b32SStephen Tozer   EXPECT_TRUE(VM.count(MAV));
369*32417b32SStephen Tozer   EXPECT_FALSE(VM.count(&A));
370*32417b32SStephen Tozer 
371*32417b32SStephen Tozer   VM[MAV] = &A;
372*32417b32SStephen Tozer   EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV));
373*32417b32SStephen Tozer   EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
374*32417b32SStephen Tozer   EXPECT_TRUE(VM.count(MAV));
375*32417b32SStephen Tozer   EXPECT_FALSE(VM.count(&A));
376*32417b32SStephen Tozer }
377*32417b32SStephen Tozer 
TEST(ValueMapperTest,mapValueLocalAsMetadataToConstant)37839423b02SDuncan P. N. Exon Smith TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) {
3794ec55f8aSDuncan P. N. Exon Smith   LLVMContext Context;
3804ec55f8aSDuncan P. N. Exon Smith   auto *Int8 = Type::getInt8Ty(Context);
3814ec55f8aSDuncan P. N. Exon Smith   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false);
3824ec55f8aSDuncan P. N. Exon Smith   std::unique_ptr<Function> F(
3834ec55f8aSDuncan P. N. Exon Smith       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
3844ec55f8aSDuncan P. N. Exon Smith 
3854ec55f8aSDuncan P. N. Exon Smith   // Map a local value to a constant.
3864ec55f8aSDuncan P. N. Exon Smith   Argument &A = *F->arg_begin();
3874ec55f8aSDuncan P. N. Exon Smith   Constant &C = *ConstantInt::get(Int8, 42);
3884ec55f8aSDuncan P. N. Exon Smith   ValueToValueMapTy VM;
3894ec55f8aSDuncan P. N. Exon Smith   VM[&A] = &C;
3904ec55f8aSDuncan P. N. Exon Smith 
3914ec55f8aSDuncan P. N. Exon Smith   // Look up the metadata-as-value wrapper.  Don't crash.
3924ec55f8aSDuncan P. N. Exon Smith   auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A));
3934ec55f8aSDuncan P. N. Exon Smith   auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C));
3944ec55f8aSDuncan P. N. Exon Smith   EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata()));
3954ec55f8aSDuncan P. N. Exon Smith   EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata()));
39639423b02SDuncan P. N. Exon Smith   EXPECT_EQ(&C, ValueMapper(VM).mapValue(A));
39739423b02SDuncan P. N. Exon Smith   EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA));
3984ec55f8aSDuncan P. N. Exon Smith }
3994ec55f8aSDuncan P. N. Exon Smith 
400ddbb1cd4SDuncan P. N. Exon Smith } // end namespace
401