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