diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -398,13 +398,17 @@ SmallVector MappedArgs; for (auto *VAM : AL->getArgs()) { // Map both Local and Constant VAMs here; they will both ultimately - // be mapped via mapValue (apart from constants when we have no - // module level changes, which have an identity mapping). + // be mapped via mapValue. The exceptions are constants when we have no + // module level changes and locals when they have no existing mapped + // value and RF_IgnoreMissingLocals is set; these have identity + // mappings. if ((Flags & RF_NoModuleLevelChanges) && isa(VAM)) { MappedArgs.push_back(VAM); } else if (Value *LV = mapValue(VAM->getValue())) { MappedArgs.push_back( LV == VAM->getValue() ? VAM : ValueAsMetadata::get(LV)); + } else if ((Flags & RF_IgnoreMissingLocals) && isa(VAM)) { + MappedArgs.push_back(VAM); } else { // If we cannot map the value, set the argument as undef. MappedArgs.push_back(ValueAsMetadata::get( diff --git a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp --- a/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp +++ b/llvm/unittests/Transforms/Utils/ValueMapperTest.cpp @@ -8,6 +8,7 @@ #include "llvm/Transforms/Utils/ValueMapper.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/LLVMContext.h" @@ -291,7 +292,11 @@ Argument &A = *F->arg_begin(); auto *LAM = LocalAsMetadata::get(&A); - auto *MAV = MetadataAsValue::get(C, LAM); + auto *MAV0 = MetadataAsValue::get(C, LAM); + std::vector Elts; + Elts.push_back(LAM); + auto *ArgList = DIArgList::get(C, Elts); + auto *MAV1 = MetadataAsValue::get(C, ArgList); // The principled answer to a LocalAsMetadata of an unmapped SSA value would // be to return nullptr (regardless of RF_IgnoreMissingLocals). @@ -301,26 +306,45 @@ // such as "metadata i32 %x" don't currently successfully maintain that // property. To keep RemapInstruction from crashing we need a non-null // return here, but we also shouldn't reference the unmapped local. Use - // "metadata !{}". + // "metadata !{}" for direct LocalAsMetadata, and undef for uses in a + // DIArgList. auto *N0 = MDTuple::get(C, None); auto *N0AV = MetadataAsValue::get(C, N0); + auto *N1 = UndefValue::get(Type::getInt8Ty(C)); + auto *N1AM = ValueAsMetadata::get(N1); + std::vector N1Elts; + N1Elts.push_back(N1AM); + auto *N1ArgList = DIArgList::get(C, N1Elts); + auto *N1AV = MetadataAsValue::get(C, N1ArgList); ValueToValueMapTy VM; - EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV)); - EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); - EXPECT_FALSE(VM.count(MAV)); + EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV0)); + EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV0)); + EXPECT_EQ(N1AV, ValueMapper(VM).mapValue(*MAV1)); + EXPECT_EQ(MAV1, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV1)); + EXPECT_FALSE(VM.count(MAV0)); + EXPECT_FALSE(VM.count(MAV1)); EXPECT_FALSE(VM.count(&A)); EXPECT_EQ(None, VM.getMappedMD(LAM)); - - VM[MAV] = MAV; - EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV)); - EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); - EXPECT_TRUE(VM.count(MAV)); + EXPECT_EQ(None, VM.getMappedMD(ArgList)); + + VM[MAV0] = MAV0; + VM[MAV1] = MAV1; + EXPECT_EQ(MAV0, ValueMapper(VM).mapValue(*MAV0)); + EXPECT_EQ(MAV0, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV0)); + EXPECT_EQ(MAV1, ValueMapper(VM).mapValue(*MAV1)); + EXPECT_EQ(MAV1, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV1)); + EXPECT_TRUE(VM.count(MAV0)); + EXPECT_TRUE(VM.count(MAV1)); EXPECT_FALSE(VM.count(&A)); - VM[MAV] = &A; - EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV)); - EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV)); - EXPECT_TRUE(VM.count(MAV)); + VM[MAV0] = &A; + VM[MAV1] = &A; + EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV0)); + EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV0)); + EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV1)); + EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV1)); + EXPECT_TRUE(VM.count(MAV0)); + EXPECT_TRUE(VM.count(MAV1)); EXPECT_FALSE(VM.count(&A)); }