1 //===- ValueMapper.cpp - Unit tests for ValueMapper -----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/Transforms/Utils/ValueMapper.h" 10 #include "llvm/IR/Constants.h" 11 #include "llvm/IR/DebugInfoMetadata.h" 12 #include "llvm/IR/Function.h" 13 #include "llvm/IR/GlobalVariable.h" 14 #include "llvm/IR/LLVMContext.h" 15 #include "llvm/IR/Metadata.h" 16 #include "gtest/gtest.h" 17 18 using namespace llvm; 19 20 namespace { 21 22 TEST(ValueMapperTest, mapMDNode) { 23 LLVMContext Context; 24 auto *U = MDTuple::get(Context, {}); 25 26 // The node should be unchanged. 27 ValueToValueMapTy VM; 28 EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U)); 29 } 30 31 TEST(ValueMapperTest, mapMDNodeCycle) { 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, ValueMapper(VM).mapMDNode(*U0)); 56 EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1)); 57 } 58 59 // Check the other order. 60 { 61 ValueToValueMapTy VM; 62 EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1)); 63 EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0)); 64 } 65 } 66 67 TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) { 68 LLVMContext Context; 69 auto *PtrTy = PointerType::get(Context, 0); 70 std::unique_ptr<GlobalVariable> G0 = std::make_unique<GlobalVariable>( 71 PtrTy, false, GlobalValue::ExternalLinkage, nullptr, "G0"); 72 std::unique_ptr<GlobalVariable> G1 = std::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 = ValueMapper(VM).mapMDNode(*N0); 98 MDNode *MappedN1 = ValueMapper(VM).mapMDNode(*N1); 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, mapMDNodeUnresolved) { 109 LLVMContext Context; 110 TempMDTuple T = MDTuple::getTemporary(Context, {}); 111 112 ValueToValueMapTy VM; 113 EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T)); 114 } 115 116 TEST(ValueMapperTest, mapMDNodeDistinct) { 117 LLVMContext Context; 118 auto *D = MDTuple::getDistinct(Context, {}); 119 120 { 121 // The node should be cloned. 122 ValueToValueMapTy VM; 123 EXPECT_NE(D, ValueMapper(VM).mapMDNode(*D)); 124 } 125 { 126 // The node should be moved. 127 ValueToValueMapTy VM; 128 EXPECT_EQ(D, ValueMapper(VM, RF_ReuseAndMutateDistinctMDs).mapMDNode(*D)); 129 } 130 } 131 132 TEST(ValueMapperTest, mapMDNodeDistinctOperands) { 133 LLVMContext Context; 134 Metadata *Old = MDTuple::getDistinct(Context, {}); 135 auto *D = MDTuple::getDistinct(Context, Old); 136 ASSERT_EQ(Old, D->getOperand(0)); 137 138 Metadata *New = MDTuple::getDistinct(Context, {}); 139 ValueToValueMapTy VM; 140 VM.MD()[Old].reset(New); 141 142 // Make sure operands are updated. 143 EXPECT_EQ(D, ValueMapper(VM, RF_ReuseAndMutateDistinctMDs).mapMDNode(*D)); 144 EXPECT_EQ(New, D->getOperand(0)); 145 } 146 147 TEST(ValueMapperTest, mapMDNodeSeeded) { 148 LLVMContext Context; 149 auto *D = MDTuple::getDistinct(Context, {}); 150 151 // The node should be moved. 152 ValueToValueMapTy VM; 153 EXPECT_EQ(std::nullopt, 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, ValueMapper(VM).mapMDNode(*D)); 158 } 159 160 TEST(ValueMapperTest, mapMDNodeSeededWithNull) { 161 LLVMContext Context; 162 auto *D = MDTuple::getDistinct(Context, {}); 163 164 // The node should be moved. 165 ValueToValueMapTy VM; 166 EXPECT_EQ(std::nullopt, VM.getMappedMD(D)); 167 168 VM.MD().insert(std::make_pair(D, TrackingMDRef())); 169 EXPECT_EQ(nullptr, *VM.getMappedMD(D)); 170 EXPECT_EQ(nullptr, ValueMapper(VM).mapMDNode(*D)); 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, ValueMapper(VM, Flags).mapValue(*F)); 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, ValueMapper(VM).mapMetadata(*S1)); 192 EXPECT_EQ(std::nullopt, 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, ValueMapper(VM).mapMetadata(*S1)); 198 } 199 200 TEST(ValueMapperTest, mapMetadataGetMappedMD) { 201 LLVMContext C; 202 auto *N0 = MDTuple::get(C, {}); 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, ValueMapper(VM).mapMetadata(*N0)); 209 EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1)); 210 EXPECT_TRUE(VM.hasMD()); 211 ASSERT_NE(std::nullopt, VM.getMappedMD(N0)); 212 ASSERT_NE(std::nullopt, 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, {}); 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, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0)); 226 EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1)); 227 EXPECT_FALSE(VM.hasMD()); 228 EXPECT_EQ(std::nullopt, VM.getMappedMD(N0)); 229 EXPECT_EQ(std::nullopt, 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 // ConstantAsMetadata shouldn't be memoized. 242 ValueToValueMapTy VM; 243 EXPECT_EQ(CAM, ValueMapper(VM).mapMetadata(*CAM)); 244 EXPECT_FALSE(VM.MD().count(CAM)); 245 EXPECT_EQ(CAM, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM)); 246 EXPECT_FALSE(VM.MD().count(CAM)); 247 248 // But it should respect a mapping that gets seeded. 249 auto *N = MDTuple::get(C, {}); 250 VM.MD()[CAM].reset(N); 251 EXPECT_EQ(N, ValueMapper(VM).mapMetadata(*CAM)); 252 EXPECT_EQ(N, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM)); 253 } 254 255 std::unique_ptr<Function> F2( 256 Function::Create(FTy, GlobalValue::ExternalLinkage, "F2")); 257 ValueToValueMapTy VM; 258 VM[F.get()] = F2.get(); 259 auto *F2MD = ValueMapper(VM).mapMetadata(*CAM); 260 EXPECT_FALSE(VM.MD().count(CAM)); 261 EXPECT_TRUE(F2MD); 262 EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue()); 263 } 264 265 #ifdef GTEST_HAS_DEATH_TEST 266 #ifndef NDEBUG 267 TEST(ValueMapperTest, mapMetadataLocalAsMetadata) { 268 LLVMContext C; 269 FunctionType *FTy = 270 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 271 std::unique_ptr<Function> F( 272 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 273 Argument &A = *F->arg_begin(); 274 275 // mapMetadata doesn't support LocalAsMetadata. The only valid container for 276 // LocalAsMetadata is a MetadataAsValue instance, so use it directly. 277 auto *LAM = LocalAsMetadata::get(&A); 278 ValueToValueMapTy VM; 279 EXPECT_DEATH(ValueMapper(VM).mapMetadata(*LAM), "Unexpected local metadata"); 280 EXPECT_DEATH(ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*LAM), 281 "Unexpected local metadata"); 282 } 283 #endif 284 #endif 285 286 TEST(ValueMapperTest, mapValueLocalAsMetadata) { 287 LLVMContext C; 288 FunctionType *FTy = 289 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 290 std::unique_ptr<Function> F( 291 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 292 Argument &A = *F->arg_begin(); 293 294 auto *LAM = LocalAsMetadata::get(&A); 295 auto *MAV = MetadataAsValue::get(C, LAM); 296 297 // The principled answer to a LocalAsMetadata of an unmapped SSA value would 298 // be to return nullptr (regardless of RF_IgnoreMissingLocals). 299 // 300 // However, algorithms that use RemapInstruction assume that each instruction 301 // only references SSA values from previous instructions. Arguments of 302 // such as "metadata i32 %x" don't currently successfully maintain that 303 // property. To keep RemapInstruction from crashing we need a non-null 304 // return here, but we also shouldn't reference the unmapped local. Use 305 // "metadata !{}". 306 auto *N0 = MDTuple::get(C, {}); 307 auto *N0AV = MetadataAsValue::get(C, N0); 308 ValueToValueMapTy VM; 309 EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV)); 310 EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); 311 EXPECT_FALSE(VM.count(MAV)); 312 EXPECT_FALSE(VM.count(&A)); 313 EXPECT_EQ(std::nullopt, VM.getMappedMD(LAM)); 314 315 VM[MAV] = MAV; 316 EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV)); 317 EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); 318 EXPECT_TRUE(VM.count(MAV)); 319 EXPECT_FALSE(VM.count(&A)); 320 321 VM[MAV] = &A; 322 EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV)); 323 EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); 324 EXPECT_TRUE(VM.count(MAV)); 325 EXPECT_FALSE(VM.count(&A)); 326 } 327 328 TEST(ValueMapperTest, mapValueLocalInArgList) { 329 LLVMContext C; 330 FunctionType *FTy = 331 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false); 332 std::unique_ptr<Function> F( 333 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 334 Argument &A = *F->arg_begin(); 335 336 auto *LAM = LocalAsMetadata::get(&A); 337 std::vector<ValueAsMetadata*> Elts; 338 Elts.push_back(LAM); 339 auto *ArgList = DIArgList::get(C, Elts); 340 auto *MAV = MetadataAsValue::get(C, ArgList); 341 342 // The principled answer to a LocalAsMetadata of an unmapped SSA value would 343 // be to return nullptr (regardless of RF_IgnoreMissingLocals). 344 // 345 // However, algorithms that use RemapInstruction assume that each instruction 346 // only references SSA values from previous instructions. Arguments of 347 // such as "metadata i32 %x" don't currently successfully maintain that 348 // property. To keep RemapInstruction from crashing we need a non-null 349 // return here, but we also shouldn't reference the unmapped local. Use 350 // poison for uses in a DIArgList. 351 auto *N0 = PoisonValue::get(Type::getInt8Ty(C)); 352 auto *N0AM = ValueAsMetadata::get(N0); 353 std::vector<ValueAsMetadata*> N0Elts; 354 N0Elts.push_back(N0AM); 355 auto *N0ArgList = DIArgList::get(C, N0Elts); 356 auto *N0AV = MetadataAsValue::get(C, N0ArgList); 357 ValueToValueMapTy VM; 358 EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV)); 359 EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); 360 EXPECT_FALSE(VM.count(MAV)); 361 EXPECT_FALSE(VM.count(&A)); 362 EXPECT_EQ(std::nullopt, VM.getMappedMD(LAM)); 363 EXPECT_EQ(std::nullopt, VM.getMappedMD(ArgList)); 364 365 VM[MAV] = MAV; 366 EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV)); 367 EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); 368 EXPECT_TRUE(VM.count(MAV)); 369 EXPECT_FALSE(VM.count(&A)); 370 371 VM[MAV] = &A; 372 EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV)); 373 EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); 374 EXPECT_TRUE(VM.count(MAV)); 375 EXPECT_FALSE(VM.count(&A)); 376 } 377 378 TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) { 379 LLVMContext Context; 380 auto *Int8 = Type::getInt8Ty(Context); 381 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false); 382 std::unique_ptr<Function> F( 383 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 384 385 // Map a local value to a constant. 386 Argument &A = *F->arg_begin(); 387 Constant &C = *ConstantInt::get(Int8, 42); 388 ValueToValueMapTy VM; 389 VM[&A] = &C; 390 391 // Look up the metadata-as-value wrapper. Don't crash. 392 auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A)); 393 auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C)); 394 EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata())); 395 EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata())); 396 EXPECT_EQ(&C, ValueMapper(VM).mapValue(A)); 397 EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA)); 398 } 399 400 // Type remapper which remaps all types to same destination. 401 class TestTypeRemapper : public ValueMapTypeRemapper { 402 public: 403 TestTypeRemapper(Type *Ty) : DstTy(Ty) { } 404 Type *remapType(Type *srcTy) { return DstTy; } 405 private: 406 Type *DstTy; 407 }; 408 409 TEST(ValueMapperTest, mapValuePoisonWithTypeRemap) { 410 LLVMContext C; 411 Type *OldTy = Type::getInt8Ty(C); 412 Type *NewTy = Type::getInt32Ty(C); 413 414 TestTypeRemapper TM(NewTy); 415 ValueToValueMapTy VM; 416 ValueMapper Mapper(VM, RF_None, &TM); 417 418 // Check that poison is still poison and has not been converted to undef. 419 auto *OldPoison = PoisonValue::get(OldTy); 420 auto *NewPoison = PoisonValue::get(NewTy); 421 EXPECT_EQ(NewPoison, Mapper.mapValue(*OldPoison)); 422 } 423 424 TEST(ValueMapperTest, mapValueConstantTargetNoneToLayoutTypeNullValue) { 425 LLVMContext C; 426 auto *OldTy = TargetExtType::get(C, "spirv.Event"); 427 Type *NewTy = OldTy->getLayoutType(); 428 429 TestTypeRemapper TM(NewTy); 430 ValueToValueMapTy VM; 431 ValueMapper Mapper(VM, RF_None, &TM); 432 433 // Check that ConstantTargetNone is mapped to '0' constant of its layout type. 434 auto *OldConstant = ConstantTargetNone::get(OldTy); 435 auto *NewConstant = Constant::getNullValue(NewTy); 436 EXPECT_EQ(NewConstant, Mapper.mapValue(*OldConstant)); 437 } 438 439 } // end namespace 440