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 @@ -523,6 +523,8 @@ if (isa(C)) return getVM()[V] = ConstantVector::get(Ops); // If this is a no-operand constant, it must be because the type was remapped. + if (isa(C)) + return getVM()[V] = PoisonValue::get(NewTy); if (isa(C)) return getVM()[V] = UndefValue::get(NewTy); if (isa(C)) 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 @@ -397,4 +397,28 @@ EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA)); } +// Type remapper which remaps all types to same destination. +class TestTypeRemapper : public ValueMapTypeRemapper { +public: + TestTypeRemapper(Type *Ty) : DstTy(Ty) { } + Type *remapType(Type *srcTy) { return DstTy; } +private: + Type *DstTy; +}; + +TEST(ValueMapperTest, mapValuePoisonWithTypeRemap) { + LLVMContext C; + Type *OldTy = Type::getInt8Ty(C); + Type *NewTy = Type::getInt32Ty(C); + + TestTypeRemapper TM(NewTy); + ValueToValueMapTy VM; + ValueMapper Mapper(VM, RF_None, &TM); + + // Check that poison is still poison and has not been converted to undef. + auto *OldPoison = PoisonValue::get(OldTy); + auto *NewPoison = PoisonValue::get(NewTy); + EXPECT_EQ(NewPoison, Mapper.mapValue(*OldPoison)); +} + } // end namespace