diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -420,6 +420,10 @@ setValueName(V->getValueName()); V->setValueName(nullptr); getValueName()->setValue(this); + if (Function *F = dyn_cast(V)) + F->recalculateIntrinsicID(); + if (Function *F = dyn_cast(this)) + F->recalculateIntrinsicID(); return; } @@ -432,6 +436,11 @@ V->setValueName(nullptr); getValueName()->setValue(this); + if (Function *F = dyn_cast(V)) + F->recalculateIntrinsicID(); + if (Function *F = dyn_cast(this)) + F->recalculateIntrinsicID(); + if (ST) ST->reinsertValue(this); } diff --git a/llvm/unittests/IR/ValueTest.cpp b/llvm/unittests/IR/ValueTest.cpp --- a/llvm/unittests/IR/ValueTest.cpp +++ b/llvm/unittests/IR/ValueTest.cpp @@ -312,4 +312,48 @@ ASSERT_TRUE(ExitDbg->getValue(0) == cast(B)); ASSERT_TRUE(Ret->getOperand(0) == cast(B)); } + +TEST(ValueTest, IntrinsicFunctionNames) { + LLVMContext C; + const char *ModuleString = "declare void @llvm.foo(i32)\n"; + + SMDiagnostic Err; + std::unique_ptr M = parseAssemblyString(ModuleString, Err, C); + + // Any function beginning with "llvm." has an LLVM-reserved name and is + // considered an intrinsic. + Function *F = M->getFunction("llvm.foo"); + EXPECT_TRUE(F->isIntrinsic()); + + // Create an intrinsic function explicitly. Check that it is indeed an + // intrinsic. + auto *FTy = F->getFunctionType(); + auto *F1 = Function::Create(FTy, GlobalValue::ExternalLinkage, "llvm.foo", *M); + EXPECT_TRUE(F1->isIntrinsic()); + + // Create a new non-intrinsic function. Set the name from a known intrinsic - + // this should become an intrinsic. The old function should still be an + // intrinsic. + auto *F2 = Function::Create(FTy, GlobalValue::ExternalLinkage, "bar", *M); + F2->setName(F1->getName()); + EXPECT_TRUE(F2->isIntrinsic()); + EXPECT_TRUE(F1->isIntrinsic()); + + // Create a new non-intrinsic function. *Take* the name from an intrinsic - + // this should become be an intrinsic. The old function should no longer be + // an intrinsic. + auto *F3 = Function::Create(FTy, GlobalValue::ExternalLinkage, "baz", *M); + F3->takeName(F); + EXPECT_FALSE(F->isIntrinsic()); + EXPECT_TRUE(F3->isIntrinsic()); + + F->setName("baz"); + EXPECT_FALSE(F->isIntrinsic()); + + // Have an intrinsic take the name of a non-intrinsic and neither are + // intrinsics afterwards. + F3->takeName(F); + EXPECT_FALSE(F3->isIntrinsic()); + EXPECT_FALSE(F->isIntrinsic()); +} } // end anonymous namespace