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 18using namespace llvm; 19 20namespace { 21 22TEST(ValueMapperTest, mapMDNode) { 23 LLVMContext Context; 24 auto *U = MDTuple::get(Context, None); 25 26 // The node should be unchanged. 27 ValueToValueMapTy VM; 28 EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U)); 29} 30 31TEST(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 67TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) { 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 = 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 108TEST(ValueMapperTest, mapMDNodeUnresolved) { 109 LLVMContext Context; 110 TempMDTuple T = MDTuple::getTemporary(Context, None); 111 112 ValueToValueMapTy VM; 113 EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T)); 114} 115 116TEST(ValueMapperTest, mapMDNodeDistinct) { 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, ValueMapper(VM).mapMDNode(*D)); 124 } 125 { 126 // The node should be moved. 127 ValueToValueMapTy VM; 128 EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D)); 129 } 130} 131 132TEST(ValueMapperTest, mapMDNodeDistinctOperands) { 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, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D)); 144 EXPECT_EQ(New, D->getOperand(0)); 145} 146 147TEST(ValueMapperTest, mapMDNodeSeeded) { 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, ValueMapper(VM).mapMDNode(*D)); 158} 159 160TEST(ValueMapperTest, mapMDNodeSeededWithNull) { 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, ValueMapper(VM).mapMDNode(*D)); 171} 172 173TEST(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 185TEST(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(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, ValueMapper(VM).mapMetadata(*S1)); 198} 199 200TEST(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, ValueMapper(VM).mapMetadata(*N0)); 209 EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1)); 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 217TEST(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, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0)); 226 EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1)); 227 EXPECT_FALSE(VM.hasMD()); 228 EXPECT_EQ(None, VM.getMappedMD(N0)); 229 EXPECT_EQ(None, VM.getMappedMD(N1)); 230} 231 232TEST(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, None); 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 267TEST(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 286TEST(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, None); 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(None, 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 328TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) { 329 LLVMContext Context; 330 auto *Int8 = Type::getInt8Ty(Context); 331 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false); 332 std::unique_ptr<Function> F( 333 Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); 334 335 // Map a local value to a constant. 336 Argument &A = *F->arg_begin(); 337 Constant &C = *ConstantInt::get(Int8, 42); 338 ValueToValueMapTy VM; 339 VM[&A] = &C; 340 341 // Look up the metadata-as-value wrapper. Don't crash. 342 auto *MDA = MetadataAsValue::get(Context, ValueAsMetadata::get(&A)); 343 auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C)); 344 EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata())); 345 EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata())); 346 EXPECT_EQ(&C, ValueMapper(VM).mapValue(A)); 347 EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA)); 348} 349 350} // end namespace 351