[llvm] RuntimeLibcalls: Add entries for objc runtime calls (PR #147920)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 10 05:21:19 PDT 2025
https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/147920
>From 06fa21c62e5fb3c8906f08704b8e71dc7cdbb942 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 10 Jul 2025 17:11:06 +0900
Subject: [PATCH] RuntimeLibcalls: Add entries for objc runtime calls
Stop emitting these calls by name in PreISelIntrinsicLowering. This
is still kind of a hack. We should be going through the abstract
RTLIB:Libcall, and then checking if the call is really supported in
this module. Do this as a placeholder until RuntimeLibcalls is a
module analysis.
---
llvm/include/llvm/IR/RuntimeLibcalls.td | 59 ++++++++++++++++++
llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp | 62 ++++++++++---------
2 files changed, 93 insertions(+), 28 deletions(-)
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index cd676e1661d62..c236e698759cc 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -387,6 +387,34 @@ def HEXAGON_MEMCPY_LIKELY_ALIGNED_MIN32BYTES_MULT8BYTES : RuntimeLibcall;
// XCore calls
def MEMCPY_ALIGN_4 : RuntimeLibcall;
+// Objective-C calls
+def OBJC_AUTORELEASE : RuntimeLibcall;
+def OBJC_AUTORELEASEPOOLPOP : RuntimeLibcall;
+def OBJC_AUTORELEASEPOOLPUSH : RuntimeLibcall;
+def OBJC_AUTORELEASERETURNVALUE : RuntimeLibcall;
+def OBJC_COPYWEAK : RuntimeLibcall;
+def OBJC_DESTROYWEAK : RuntimeLibcall;
+def OBJC_INITWEAK : RuntimeLibcall;
+def OBJC_LOADWEAK : RuntimeLibcall;
+def OBJC_LOADWEAKRETAINED : RuntimeLibcall;
+def OBJC_MOVEWEAK : RuntimeLibcall;
+def OBJC_RELEASE : RuntimeLibcall;
+def OBJC_RETAIN : RuntimeLibcall;
+def OBJC_RETAINAUTORELEASE : RuntimeLibcall;
+def OBJC_RETAINAUTORELEASERETURNVALUE : RuntimeLibcall;
+def OBJC_RETAINAUTORELEASEDRETURNVALUE : RuntimeLibcall;
+def OBJC_CLAIMAUTORELEASEDRETURNVALUE : RuntimeLibcall;
+def OBJC_RETAINBLOCK : RuntimeLibcall;
+def OBJC_STORESTRONG : RuntimeLibcall;
+def OBJC_STOREWEAK : RuntimeLibcall;
+def OBJC_UNSAFECLAIMAUTORELEASEDRETURNVALUE : RuntimeLibcall;
+def OBJC_RETAINEDOBJECT : RuntimeLibcall;
+def OBJC_UNRETAINEDOBJECT : RuntimeLibcall;
+def OBJC_UNRETAINEDPOINTER : RuntimeLibcall;
+def OBJC_RETAIN_AUTORELEASE : RuntimeLibcall;
+def OBJC_SYNC_ENTER : RuntimeLibcall;
+def OBJC_SYNC_EXIT : RuntimeLibcall;
+
//--------------------------------------------------------------------
// Define implementation default libcalls
//--------------------------------------------------------------------
@@ -1032,6 +1060,37 @@ defvar LibmHasSinCosF80 = LibcallImpls<(add sincos_f80), hasSinCos>;
defvar LibmHasSinCosF128 = LibcallImpls<(add sincos_f128), hasSinCos>;
defvar LibmHasSinCosPPCF128 = LibcallImpls<(add sincos_ppcf128), hasSinCos>;
+//===----------------------------------------------------------------------===//
+// Objective-C Runtime Libcalls
+//===----------------------------------------------------------------------===//
+
+def objc_autorelease : RuntimeLibcallImpl<OBJC_AUTORELEASE>;
+def objc_autoreleasePoolPop : RuntimeLibcallImpl<OBJC_AUTORELEASEPOOLPOP>;
+def objc_autoreleasePoolPush : RuntimeLibcallImpl<OBJC_AUTORELEASEPOOLPUSH>;
+def objc_autoreleaseReturnValue : RuntimeLibcallImpl<OBJC_AUTORELEASERETURNVALUE>;
+def objc_copyWeak : RuntimeLibcallImpl<OBJC_COPYWEAK>;
+def objc_destroyWeak : RuntimeLibcallImpl<OBJC_DESTROYWEAK>;
+def objc_initWeak : RuntimeLibcallImpl<OBJC_INITWEAK>;
+def objc_loadWeak : RuntimeLibcallImpl<OBJC_LOADWEAK>;
+def objc_loadWeakRetained : RuntimeLibcallImpl<OBJC_LOADWEAKRETAINED>;
+def objc_moveWeak : RuntimeLibcallImpl<OBJC_MOVEWEAK>;
+def objc_release : RuntimeLibcallImpl<OBJC_RELEASE>;
+def objc_retain : RuntimeLibcallImpl<OBJC_RETAIN>;
+def objc_retainAutorelease : RuntimeLibcallImpl<OBJC_RETAINAUTORELEASE>;
+def objc_retainAutoreleaseReturnValue : RuntimeLibcallImpl<OBJC_RETAINAUTORELEASERETURNVALUE>;
+def objc_retainAutoreleasedReturnValue : RuntimeLibcallImpl<OBJC_RETAINAUTORELEASEDRETURNVALUE>;
+def objc_claimAutoreleasedReturnValue : RuntimeLibcallImpl<OBJC_CLAIMAUTORELEASEDRETURNVALUE>;
+def objc_retainBlock : RuntimeLibcallImpl<OBJC_RETAINBLOCK>;
+def objc_storeStrong : RuntimeLibcallImpl<OBJC_STORESTRONG>;
+def objc_storeWeak : RuntimeLibcallImpl<OBJC_STOREWEAK>;
+def objc_unsafeClaimAutoreleasedReturnValue : RuntimeLibcallImpl<OBJC_UNSAFECLAIMAUTORELEASEDRETURNVALUE>;
+def objc_retainedObject : RuntimeLibcallImpl<OBJC_RETAINEDOBJECT>;
+def objc_unretainedObject : RuntimeLibcallImpl<OBJC_UNRETAINEDOBJECT>;
+def objc_unretainedPointer : RuntimeLibcallImpl<OBJC_UNRETAINEDPOINTER>;
+def objc_retain_autorelease : RuntimeLibcallImpl<OBJC_RETAIN_AUTORELEASE>;
+def objc_sync_enter : RuntimeLibcallImpl<OBJC_SYNC_ENTER>;
+def objc_sync_exit : RuntimeLibcallImpl<OBJC_SYNC_EXIT>;
+
//===----------------------------------------------------------------------===//
// AArch64 Runtime Libcalls
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
index 265a32cf4d127..925ce5dd79512 100644
--- a/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
+++ b/llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
@@ -25,6 +25,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/RuntimeLibcalls.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/InitializePasses.h"
@@ -135,17 +136,22 @@ static CallInst::TailCallKind getOverridingTailCallKind(const Function &F) {
return CallInst::TCK_None;
}
-static bool lowerObjCCall(Function &F, const char *NewFn,
+static bool lowerObjCCall(Function &F, RTLIB::LibcallImpl NewFn,
bool setNonLazyBind = false) {
assert(IntrinsicInst::mayLowerToFunctionCall(F.getIntrinsicID()) &&
"Pre-ISel intrinsics do lower into regular function calls");
if (F.use_empty())
return false;
+ // FIXME: When RuntimeLibcalls is an analysis, check if the function is really
+ // supported, and go through RTLIB::Libcall.
+ const char *NewFnName = RTLIB::RuntimeLibcallsInfo::getLibcallImplName(NewFn);
+
// If we haven't already looked up this function, check to see if the
// program already contains a function with this name.
Module *M = F.getParent();
- FunctionCallee FCache = M->getOrInsertFunction(NewFn, F.getFunctionType());
+ FunctionCallee FCache =
+ M->getOrInsertFunction(NewFnName, F.getFunctionType());
if (Function *Fn = dyn_cast<Function>(FCache.getCallee())) {
Fn->setLinkage(F.getLinkage());
@@ -501,82 +507,82 @@ bool PreISelIntrinsicLowering::lowerIntrinsics(Module &M) const {
});
break;
case Intrinsic::objc_autorelease:
- Changed |= lowerObjCCall(F, "objc_autorelease");
+ Changed |= lowerObjCCall(F, RTLIB::objc_autorelease);
break;
case Intrinsic::objc_autoreleasePoolPop:
- Changed |= lowerObjCCall(F, "objc_autoreleasePoolPop");
+ Changed |= lowerObjCCall(F, RTLIB::objc_autoreleasePoolPop);
break;
case Intrinsic::objc_autoreleasePoolPush:
- Changed |= lowerObjCCall(F, "objc_autoreleasePoolPush");
+ Changed |= lowerObjCCall(F, RTLIB::objc_autoreleasePoolPush);
break;
case Intrinsic::objc_autoreleaseReturnValue:
- Changed |= lowerObjCCall(F, "objc_autoreleaseReturnValue");
+ Changed |= lowerObjCCall(F, RTLIB::objc_autoreleaseReturnValue);
break;
case Intrinsic::objc_copyWeak:
- Changed |= lowerObjCCall(F, "objc_copyWeak");
+ Changed |= lowerObjCCall(F, RTLIB::objc_copyWeak);
break;
case Intrinsic::objc_destroyWeak:
- Changed |= lowerObjCCall(F, "objc_destroyWeak");
+ Changed |= lowerObjCCall(F, RTLIB::objc_destroyWeak);
break;
case Intrinsic::objc_initWeak:
- Changed |= lowerObjCCall(F, "objc_initWeak");
+ Changed |= lowerObjCCall(F, RTLIB::objc_initWeak);
break;
case Intrinsic::objc_loadWeak:
- Changed |= lowerObjCCall(F, "objc_loadWeak");
+ Changed |= lowerObjCCall(F, RTLIB::objc_loadWeak);
break;
case Intrinsic::objc_loadWeakRetained:
- Changed |= lowerObjCCall(F, "objc_loadWeakRetained");
+ Changed |= lowerObjCCall(F, RTLIB::objc_loadWeakRetained);
break;
case Intrinsic::objc_moveWeak:
- Changed |= lowerObjCCall(F, "objc_moveWeak");
+ Changed |= lowerObjCCall(F, RTLIB::objc_moveWeak);
break;
case Intrinsic::objc_release:
- Changed |= lowerObjCCall(F, "objc_release", true);
+ Changed |= lowerObjCCall(F, RTLIB::objc_release, true);
break;
case Intrinsic::objc_retain:
- Changed |= lowerObjCCall(F, "objc_retain", true);
+ Changed |= lowerObjCCall(F, RTLIB::objc_retain, true);
break;
case Intrinsic::objc_retainAutorelease:
- Changed |= lowerObjCCall(F, "objc_retainAutorelease");
+ Changed |= lowerObjCCall(F, RTLIB::objc_retainAutorelease);
break;
case Intrinsic::objc_retainAutoreleaseReturnValue:
- Changed |= lowerObjCCall(F, "objc_retainAutoreleaseReturnValue");
+ Changed |= lowerObjCCall(F, RTLIB::objc_retainAutoreleaseReturnValue);
break;
case Intrinsic::objc_retainAutoreleasedReturnValue:
- Changed |= lowerObjCCall(F, "objc_retainAutoreleasedReturnValue");
+ Changed |= lowerObjCCall(F, RTLIB::objc_retainAutoreleasedReturnValue);
break;
case Intrinsic::objc_claimAutoreleasedReturnValue:
- Changed |= lowerObjCCall(F, "objc_claimAutoreleasedReturnValue");
+ Changed |= lowerObjCCall(F, RTLIB::objc_claimAutoreleasedReturnValue);
break;
case Intrinsic::objc_retainBlock:
- Changed |= lowerObjCCall(F, "objc_retainBlock");
+ Changed |= lowerObjCCall(F, RTLIB::objc_retainBlock);
break;
case Intrinsic::objc_storeStrong:
- Changed |= lowerObjCCall(F, "objc_storeStrong");
+ Changed |= lowerObjCCall(F, RTLIB::objc_storeStrong);
break;
case Intrinsic::objc_storeWeak:
- Changed |= lowerObjCCall(F, "objc_storeWeak");
+ Changed |= lowerObjCCall(F, RTLIB::objc_storeWeak);
break;
case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
- Changed |= lowerObjCCall(F, "objc_unsafeClaimAutoreleasedReturnValue");
+ Changed |= lowerObjCCall(F, RTLIB::objc_unsafeClaimAutoreleasedReturnValue);
break;
case Intrinsic::objc_retainedObject:
- Changed |= lowerObjCCall(F, "objc_retainedObject");
+ Changed |= lowerObjCCall(F, RTLIB::objc_retainedObject);
break;
case Intrinsic::objc_unretainedObject:
- Changed |= lowerObjCCall(F, "objc_unretainedObject");
+ Changed |= lowerObjCCall(F, RTLIB::objc_unretainedObject);
break;
case Intrinsic::objc_unretainedPointer:
- Changed |= lowerObjCCall(F, "objc_unretainedPointer");
+ Changed |= lowerObjCCall(F, RTLIB::objc_unretainedPointer);
break;
case Intrinsic::objc_retain_autorelease:
- Changed |= lowerObjCCall(F, "objc_retain_autorelease");
+ Changed |= lowerObjCCall(F, RTLIB::objc_retain_autorelease);
break;
case Intrinsic::objc_sync_enter:
- Changed |= lowerObjCCall(F, "objc_sync_enter");
+ Changed |= lowerObjCCall(F, RTLIB::objc_sync_enter);
break;
case Intrinsic::objc_sync_exit:
- Changed |= lowerObjCCall(F, "objc_sync_exit");
+ Changed |= lowerObjCCall(F, RTLIB::objc_sync_exit);
break;
case Intrinsic::exp:
case Intrinsic::exp2:
More information about the llvm-commits
mailing list