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/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 "llvm/Transforms/Utils/ValueMapper.h" 16 #include "gtest/gtest.h" 17 18 using namespace llvm; 19 20 namespace { 21 22 TEST(ValueMapperTest, MapMetadata) { 23 LLVMContext Context; 24 auto *U = MDTuple::get(Context, None); 25 26 // The node should be unchanged. 27 ValueToValueMapTy VM; 28 EXPECT_EQ(U, MapMetadata(U, VM, RF_None)); 29 } 30 31 TEST(ValueMapperTest, MapMetadataCycle) { 32 LLVMContext Context; 33 MDNode *U0; 34 MDNode *U1; 35 { 36 Metadata *Ops[] = {nullptr}; 37 auto T = MDTuple::getTemporary(Context, Ops); 38 Ops[0] = T.get(); 39 U0 = MDTuple::get(Context, Ops); 40 T->replaceOperandWith(0, U0); 41 U1 = MDNode::replaceWithUniqued(std::move(T)); 42 U0->resolveCycles(); 43 } 44 45 EXPECT_TRUE(U0->isResolved()); 46 EXPECT_TRUE(U0->isUniqued()); 47 EXPECT_TRUE(U1->isResolved()); 48 EXPECT_TRUE(U1->isUniqued()); 49 EXPECT_EQ(U1, U0->getOperand(0)); 50 EXPECT_EQ(U0, U1->getOperand(0)); 51 52 // Cycles shouldn't be duplicated. 53 { 54 ValueToValueMapTy VM; 55 EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None)); 56 EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None)); 57 } 58 59 // Check the other order. 60 { 61 ValueToValueMapTy VM; 62 EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None)); 63 EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None)); 64 } 65 } 66 67 TEST(ValueMapperTest, MapMetadataDuplicatedCycle) { 68 LLVMContext Context; 69 auto *PtrTy = Type::getInt8Ty(Context)->getPointerTo(); 70 std::unique_ptr<GlobalVariable> G0 = llvm::make_unique<GlobalVariable>( 71 PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G0"); 72 std::unique_ptr<GlobalVariable> G1 = llvm::make_unique<GlobalVariable>( 73 PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G1"); 74 75 // Create a cycle that references G0. 76 MDNode *N0; // !0 = !{!1} 77 MDNode *N1; // !1 = !{!0, i8* @G0} 78 { 79 auto T0 = MDTuple::getTemporary(Context, nullptr); 80 Metadata *Ops1[] = {T0.get(), ConstantAsMetadata::get(G0.get())}; 81 N1 = MDTuple::get(Context, Ops1); 82 T0->replaceOperandWith(0, N1); 83 N0 = MDNode::replaceWithUniqued(std::move(T0)); 84 } 85 86 // Resolve N0 and N1. 87 ASSERT_FALSE(N0->isResolved()); 88 ASSERT_FALSE(N1->isResolved()); 89 N0->resolveCycles(); 90 ASSERT_TRUE(N0->isResolved()); 91 ASSERT_TRUE(N1->isResolved()); 92 93 // Seed the value map to map G0 to G1 and map the nodes. The output should 94 // have new nodes that reference G1 (instead of G0). 95 ValueToValueMapTy VM; 96 VM[G0.get()] = G1.get(); 97 MDNode *MappedN0 = MapMetadata(N0, VM); 98 MDNode *MappedN1 = MapMetadata(N1, VM); 99 EXPECT_NE(N0, MappedN0); 100 EXPECT_NE(N1, MappedN1); 101 EXPECT_EQ(ConstantAsMetadata::get(G1.get()), MappedN1->getOperand(1)); 102 103 // Check that the output nodes are resolved. 104 EXPECT_TRUE(MappedN0->isResolved()); 105 EXPECT_TRUE(MappedN1->isResolved()); 106 } 107 108 TEST(ValueMapperTest, MapMetadataUnresolved) { 109 LLVMContext Context; 110 TempMDTuple T = MDTuple::getTemporary(Context, None); 111 112 ValueToValueMapTy VM; 113 EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges)); 114 } 115 116 TEST(ValueMapperTest, MapMetadataDistinct) { 117 LLVMContext Context; 118 auto *D = MDTuple::getDistinct(Context, None); 119 120 { 121 // The node should be cloned. 122 ValueToValueMapTy VM; 123 EXPECT_NE(D, MapMetadata(D, VM, RF_None)); 124 } 125 { 126 // The node should be moved. 127 ValueToValueMapTy VM; 128 EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs)); 129 } 130 } 131 132 TEST(ValueMapperTest, MapMetadataDistinctOperands) { 133 LLVMContext Context; 134 Metadata *Old = MDTuple::getDistinct(Context, None); 135 auto *D = MDTuple::getDistinct(Context, Old); 136 ASSERT_EQ(Old, D->getOperand(0)); 137 138 Metadata *New = MDTuple::getDistinct(Context, None); 139 ValueToValueMapTy VM; 140 VM.MD()[Old].reset(New); 141 142 // Make sure operands are updated. 143 EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs)); 144 EXPECT_EQ(New, D->getOperand(0)); 145 } 146 147 TEST(ValueMapperTest, MapMetadataSeeded) { 148 LLVMContext Context; 149 auto *D = MDTuple::getDistinct(Context, None); 150 151 // The node should be moved. 152 ValueToValueMapTy VM; 153 EXPECT_EQ(None, VM.getMappedMD(D)); 154 155 VM.MD().insert(std::make_pair(D, TrackingMDRef(D))); 156 EXPECT_EQ(D, *VM.getMappedMD(D)); 157 EXPECT_EQ(D, MapMetadata(D, VM, RF_None)); 158 } 159 160 TEST(ValueMapperTest, MapMetadataSeededWithNull) { 161 LLVMContext Context; 162 auto *D = MDTuple::getDistinct(Context, None); 163 164 // The node should be moved. 165 ValueToValueMapTy VM; 166 EXPECT_EQ(None, VM.getMappedMD(D)); 167 168 VM.MD().insert(std::make_pair(D, TrackingMDRef())); 169 EXPECT_EQ(nullptr, *VM.getMappedMD(D)); 170 EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None)); 171 } 172 173 TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) { 174 LLVMContext C; 175 FunctionType *FTy = 176 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 177 std::unique_ptr<Function> F( 178 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 179 180 ValueToValueMapTy VM; 181 RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues; 182 EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags)); 183 } 184 185 TEST(ValueMapperTest, MapMetadataMDString) { 186 LLVMContext C; 187 auto *S1 = MDString::get(C, "S1"); 188 ValueToValueMapTy VM; 189 190 // Make sure S1 maps to itself, but isn't memoized. 191 EXPECT_EQ(S1, MapMetadata(S1, VM)); 192 EXPECT_EQ(None, VM.getMappedMD(S1)); 193 194 // We still expect VM.MD() to be respected. 195 auto *S2 = MDString::get(C, "S2"); 196 VM.MD()[S1].reset(S2); 197 EXPECT_EQ(S2, MapMetadata(S1, VM)); 198 } 199 200 TEST(ValueMapperTest, MapMetadataGetMappedMD) { 201 LLVMContext C; 202 auto *N0 = MDTuple::get(C, None); 203 auto *N1 = MDTuple::get(C, N0); 204 205 // Make sure hasMD and getMappedMD work correctly. 206 ValueToValueMapTy VM; 207 EXPECT_FALSE(VM.hasMD()); 208 EXPECT_EQ(N0, MapMetadata(N0, VM)); 209 EXPECT_EQ(N1, MapMetadata(N1, VM)); 210 EXPECT_TRUE(VM.hasMD()); 211 ASSERT_NE(None, VM.getMappedMD(N0)); 212 ASSERT_NE(None, VM.getMappedMD(N1)); 213 EXPECT_EQ(N0, *VM.getMappedMD(N0)); 214 EXPECT_EQ(N1, *VM.getMappedMD(N1)); 215 } 216 217 TEST(ValueMapperTest, MapMetadataNoModuleLevelChanges) { 218 LLVMContext C; 219 auto *N0 = MDTuple::get(C, None); 220 auto *N1 = MDTuple::get(C, N0); 221 222 // Nothing should be memoized when RF_NoModuleLevelChanges. 223 ValueToValueMapTy VM; 224 EXPECT_FALSE(VM.hasMD()); 225 EXPECT_EQ(N0, MapMetadata(N0, VM, RF_NoModuleLevelChanges)); 226 EXPECT_EQ(N1, MapMetadata(N1, VM, RF_NoModuleLevelChanges)); 227 EXPECT_FALSE(VM.hasMD()); 228 EXPECT_EQ(None, VM.getMappedMD(N0)); 229 EXPECT_EQ(None, VM.getMappedMD(N1)); 230 } 231 232 TEST(ValueMapperTest, MapMetadataConstantAsMetadata) { 233 LLVMContext C; 234 FunctionType *FTy = 235 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 236 std::unique_ptr<Function> F( 237 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 238 239 auto *CAM = ConstantAsMetadata::get(F.get()); 240 { 241 ValueToValueMapTy VM; 242 EXPECT_EQ(CAM, MapMetadata(CAM, VM)); 243 EXPECT_TRUE(VM.MD().count(CAM)); 244 VM.MD().erase(CAM); 245 EXPECT_EQ(CAM, MapMetadata(CAM, VM, RF_IgnoreMissingLocals)); 246 EXPECT_TRUE(VM.MD().count(CAM)); 247 248 auto *N = MDTuple::get(C, None); 249 VM.MD()[CAM].reset(N); 250 EXPECT_EQ(N, MapMetadata(CAM, VM)); 251 EXPECT_EQ(N, MapMetadata(CAM, VM, RF_IgnoreMissingLocals)); 252 } 253 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 = MapMetadata(CAM, VM); 259 EXPECT_TRUE(VM.MD().count(CAM)); 260 EXPECT_TRUE(F2MD); 261 EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue()); 262 } 263 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(); 273 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(MapMetadata(LAM, VM), "Unexpected local metadata"); 279 EXPECT_DEATH(MapMetadata(LAM, VM, RF_IgnoreMissingLocals), 280 "Unexpected local metadata"); 281 } 282 #endif 283 #endif 284 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(); 292 293 auto *LAM = LocalAsMetadata::get(&A); 294 auto *MAV = MetadataAsValue::get(C, LAM); 295 296 // The principled answer to a LocalAsMetadata of an unmapped SSA value would 297 // be to return nullptr (regardless of RF_IgnoreMissingLocals). 298 // 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, MapValue(MAV, VM)); 309 EXPECT_EQ(nullptr, MapValue(MAV, VM, RF_IgnoreMissingLocals)); 310 EXPECT_FALSE(VM.count(MAV)); 311 EXPECT_FALSE(VM.count(&A)); 312 EXPECT_EQ(None, VM.getMappedMD(LAM)); 313 314 VM[MAV] = MAV; 315 EXPECT_EQ(MAV, MapValue(MAV, VM)); 316 EXPECT_EQ(MAV, MapValue(MAV, VM, RF_IgnoreMissingLocals)); 317 EXPECT_TRUE(VM.count(MAV)); 318 EXPECT_FALSE(VM.count(&A)); 319 320 VM[MAV] = &A; 321 EXPECT_EQ(&A, MapValue(MAV, VM)); 322 EXPECT_EQ(&A, MapValue(MAV, VM, RF_IgnoreMissingLocals)); 323 EXPECT_TRUE(VM.count(MAV)); 324 EXPECT_FALSE(VM.count(&A)); 325 } 326 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")); 333 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; 339 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, MapValue(&A, VM)); 346 EXPECT_EQ(MDC, MapValue(MDA, VM)); 347 } 348 349 } // end namespace 350