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/Function.h" 11 #include "llvm/IR/LLVMContext.h" 12 #include "llvm/IR/Metadata.h" 13 #include "llvm/Transforms/Utils/ValueMapper.h" 14 #include "gtest/gtest.h" 15 16 using namespace llvm; 17 18 namespace { 19 20 TEST(ValueMapperTest, MapMetadata) { 21 LLVMContext Context; 22 auto *U = MDTuple::get(Context, None); 23 24 // The node should be unchanged. 25 ValueToValueMapTy VM; 26 EXPECT_EQ(U, MapMetadata(U, VM, RF_None)); 27 } 28 29 TEST(ValueMapperTest, MapMetadataCycle) { 30 LLVMContext Context; 31 MDNode *U0; 32 MDNode *U1; 33 { 34 Metadata *Ops[] = {nullptr}; 35 auto T = MDTuple::getTemporary(Context, Ops); 36 Ops[0] = T.get(); 37 U0 = MDTuple::get(Context, Ops); 38 T->replaceOperandWith(0, U0); 39 U1 = MDNode::replaceWithUniqued(std::move(T)); 40 U0->resolveCycles(); 41 } 42 43 EXPECT_TRUE(U0->isResolved()); 44 EXPECT_TRUE(U0->isUniqued()); 45 EXPECT_TRUE(U1->isResolved()); 46 EXPECT_TRUE(U1->isUniqued()); 47 EXPECT_EQ(U1, U0->getOperand(0)); 48 EXPECT_EQ(U0, U1->getOperand(0)); 49 50 // Cycles shouldn't be duplicated. 51 { 52 ValueToValueMapTy VM; 53 EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None)); 54 EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None)); 55 } 56 57 // Check the other order. 58 { 59 ValueToValueMapTy VM; 60 EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None)); 61 EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None)); 62 } 63 } 64 65 TEST(ValueMapperTest, MapMetadataUnresolved) { 66 LLVMContext Context; 67 TempMDTuple T = MDTuple::getTemporary(Context, None); 68 69 ValueToValueMapTy VM; 70 EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges)); 71 } 72 73 TEST(ValueMapperTest, MapMetadataDistinct) { 74 LLVMContext Context; 75 auto *D = MDTuple::getDistinct(Context, None); 76 77 { 78 // The node should be cloned. 79 ValueToValueMapTy VM; 80 EXPECT_NE(D, MapMetadata(D, VM, RF_None)); 81 } 82 { 83 // The node should be moved. 84 ValueToValueMapTy VM; 85 EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs)); 86 } 87 } 88 89 TEST(ValueMapperTest, MapMetadataDistinctOperands) { 90 LLVMContext Context; 91 Metadata *Old = MDTuple::getDistinct(Context, None); 92 auto *D = MDTuple::getDistinct(Context, Old); 93 ASSERT_EQ(Old, D->getOperand(0)); 94 95 Metadata *New = MDTuple::getDistinct(Context, None); 96 ValueToValueMapTy VM; 97 VM.MD()[Old].reset(New); 98 99 // Make sure operands are updated. 100 EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs)); 101 EXPECT_EQ(New, D->getOperand(0)); 102 } 103 104 TEST(ValueMapperTest, MapMetadataSeeded) { 105 LLVMContext Context; 106 auto *D = MDTuple::getDistinct(Context, None); 107 108 // The node should be moved. 109 ValueToValueMapTy VM; 110 EXPECT_EQ(None, VM.getMappedMD(D)); 111 112 VM.MD().insert(std::make_pair(D, TrackingMDRef(D))); 113 EXPECT_EQ(D, *VM.getMappedMD(D)); 114 EXPECT_EQ(D, MapMetadata(D, VM, RF_None)); 115 } 116 117 TEST(ValueMapperTest, MapMetadataSeededWithNull) { 118 LLVMContext Context; 119 auto *D = MDTuple::getDistinct(Context, None); 120 121 // The node should be moved. 122 ValueToValueMapTy VM; 123 EXPECT_EQ(None, VM.getMappedMD(D)); 124 125 VM.MD().insert(std::make_pair(D, TrackingMDRef())); 126 EXPECT_EQ(nullptr, *VM.getMappedMD(D)); 127 EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None)); 128 } 129 130 TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) { 131 LLVMContext C; 132 FunctionType *FTy = 133 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 134 std::unique_ptr<Function> F( 135 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 136 137 ValueToValueMapTy VM; 138 RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues; 139 EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags)); 140 } 141 142 TEST(ValueMapperTest, MapMetadataConstantAsMetadata) { 143 LLVMContext C; 144 FunctionType *FTy = 145 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 146 std::unique_ptr<Function> F( 147 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 148 149 auto *CAM = ConstantAsMetadata::get(F.get()); 150 { 151 ValueToValueMapTy VM; 152 EXPECT_EQ(CAM, MapMetadata(CAM, VM)); 153 EXPECT_TRUE(VM.MD().count(CAM)); 154 VM.MD().erase(CAM); 155 EXPECT_EQ(CAM, MapMetadata(CAM, VM, RF_IgnoreMissingLocals)); 156 EXPECT_TRUE(VM.MD().count(CAM)); 157 158 auto *N = MDTuple::get(C, None); 159 VM.MD()[CAM].reset(N); 160 EXPECT_EQ(N, MapMetadata(CAM, VM)); 161 EXPECT_EQ(N, MapMetadata(CAM, VM, RF_IgnoreMissingLocals)); 162 } 163 164 std::unique_ptr<Function> F2( 165 Function::Create(FTy, GlobalValue::ExternalLinkage, "F2")); 166 ValueToValueMapTy VM; 167 VM[F.get()] = F2.get(); 168 auto *F2MD = MapMetadata(CAM, VM); 169 EXPECT_TRUE(VM.MD().count(CAM)); 170 EXPECT_TRUE(F2MD); 171 EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue()); 172 } 173 174 #ifdef GTEST_HAS_DEATH_TEST 175 #ifndef NDEBUG 176 TEST(ValueMapperTest, MapMetadataLocalAsMetadata) { 177 LLVMContext C; 178 FunctionType *FTy = 179 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 180 std::unique_ptr<Function> F( 181 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 182 Argument &A = *F->arg_begin(); 183 184 // MapMetadata doesn't support LocalAsMetadata. The only valid container for 185 // LocalAsMetadata is a MetadataAsValue instance, so use it directly. 186 auto *LAM = LocalAsMetadata::get(&A); 187 ValueToValueMapTy VM; 188 EXPECT_DEATH(MapMetadata(LAM, VM), "Unexpected local metadata"); 189 EXPECT_DEATH(MapMetadata(LAM, VM, RF_IgnoreMissingLocals), 190 "Unexpected local metadata"); 191 } 192 #endif 193 #endif 194 195 TEST(ValueMapperTest, MapValueLocalAsMetadata) { 196 LLVMContext C; 197 FunctionType *FTy = 198 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 199 std::unique_ptr<Function> F( 200 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 201 Argument &A = *F->arg_begin(); 202 203 auto *LAM = LocalAsMetadata::get(&A); 204 auto *MAV = MetadataAsValue::get(C, LAM); 205 206 // The principled answer to a LocalAsMetadata of an unmapped SSA value would 207 // be to return nullptr (regardless of RF_IgnoreMissingLocals). 208 // 209 // However, algorithms that use RemapInstruction assume that each instruction 210 // only references SSA values from previous instructions. Arguments of 211 // such as "metadata i32 %x" don't currently successfully maintain that 212 // property. To keep RemapInstruction from crashing we need a non-null 213 // return here, but we also shouldn't reference the unmapped local. Use 214 // "metadata !{}". 215 auto *N0 = MDTuple::get(C, None); 216 auto *N0AV = MetadataAsValue::get(C, N0); 217 ValueToValueMapTy VM; 218 EXPECT_EQ(N0AV, MapValue(MAV, VM)); 219 EXPECT_EQ(nullptr, MapValue(MAV, VM, RF_IgnoreMissingLocals)); 220 EXPECT_FALSE(VM.count(MAV)); 221 EXPECT_FALSE(VM.count(&A)); 222 EXPECT_EQ(None, VM.getMappedMD(LAM)); 223 224 VM[MAV] = MAV; 225 EXPECT_EQ(MAV, MapValue(MAV, VM)); 226 EXPECT_EQ(MAV, MapValue(MAV, VM, RF_IgnoreMissingLocals)); 227 EXPECT_TRUE(VM.count(MAV)); 228 EXPECT_FALSE(VM.count(&A)); 229 230 VM[MAV] = &A; 231 EXPECT_EQ(&A, MapValue(MAV, VM)); 232 EXPECT_EQ(&A, MapValue(MAV, VM, RF_IgnoreMissingLocals)); 233 EXPECT_TRUE(VM.count(MAV)); 234 EXPECT_FALSE(VM.count(&A)); 235 } 236 237 } // end namespace 238