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