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