[llvm] [LLVM-C] Upstream `LLVMGetOrInsertFunction` from rustc (PR #162235)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 7 06:01:19 PDT 2025
https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/162235
>From aa16c224b16e866e3bf42e8fcc769e8e31d983c1 Mon Sep 17 00:00:00 2001
From: AMS21 <ams21.github at gmail.com>
Date: Tue, 7 Oct 2025 09:19:57 +0200
Subject: [PATCH] [LLVM-C] Upstream `LLVMGetOrInsertFunction` from rustc
---
llvm/include/llvm-c/Core.h | 16 ++++++++++++++++
llvm/lib/IR/Core.cpp | 8 ++++++++
llvm/unittests/IR/FunctionTest.cpp | 19 +++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index d02cf984167c9..fdd0d1df2a25f 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -2988,6 +2988,22 @@ LLVM_C_ABI char *LLVMIntrinsicCopyOverloadedName2(LLVMModuleRef Mod,
*/
LLVM_C_ABI LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID);
+/**
+ * Obtain or insert a function into a module.
+ *
+ * If a function with the specified name already exists in the module, it
+ * is returned. Otherwise, a new function is created in the module with the
+ * specified name and type and is returned.
+ *
+ * The returned value corresponds to a llvm::Function instance.
+ *
+ * @see llvm::Module::getOrInsertFunction()
+ */
+LLVM_C_ABI LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
+ const char *Name,
+ size_t NameLen,
+ LLVMTypeRef FunctionTy);
+
/**
* Obtain the calling function of a function.
*
diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp
index df0c85b87ba60..abd06f4724fcd 100644
--- a/llvm/lib/IR/Core.cpp
+++ b/llvm/lib/IR/Core.cpp
@@ -2523,6 +2523,14 @@ LLVMBool LLVMIntrinsicIsOverloaded(unsigned ID) {
return llvm::Intrinsic::isOverloaded(IID);
}
+LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, const char *Name,
+ size_t NameLen, LLVMTypeRef FunctionTy) {
+ return wrap(unwrap(M)
+ ->getOrInsertFunction(StringRef(Name, NameLen),
+ unwrap<FunctionType>(FunctionTy))
+ .getCallee());
+}
+
unsigned LLVMGetFunctionCallConv(LLVMValueRef Fn) {
return unwrap<Function>(Fn)->getCallingConv();
}
diff --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp
index 7ba7584e22976..8ed76999dc13d 100644
--- a/llvm/unittests/IR/FunctionTest.cpp
+++ b/llvm/unittests/IR/FunctionTest.cpp
@@ -625,4 +625,23 @@ TEST(FunctionTest, Personality) {
EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
}
+TEST(FunctionTest, LLVMGetOrInsertFunction) {
+ LLVMContext Ctx;
+ Module M("test", Ctx);
+ Type *Int8Ty = Type::getInt8Ty(Ctx);
+ FunctionType *FTy = FunctionType::get(Int8Ty, false);
+
+ // Create the function using the C API
+ LLVMValueRef FuncRef = LLVMGetOrInsertFunction(wrap(&M), "F", 1, wrap(FTy));
+
+ // Verify that the returned value is a function and has the correct type
+ Function *Func = unwrap<Function>(FuncRef);
+ EXPECT_EQ(Func->getName(), "F");
+ EXPECT_EQ(Func->getFunctionType(), FTy);
+
+ // Call LLVMGetOrInsertFunction again to ensure it returns the same function
+ LLVMValueRef FuncRef2 = LLVMGetOrInsertFunction(wrap(&M), "F", 1, wrap(FTy));
+ EXPECT_EQ(FuncRef, FuncRef2);
+}
+
} // end namespace
More information about the llvm-commits
mailing list