Preserve the linkage for objc* intrinsics as clang will set them to weak_external...
authorPete Cooper <peter_cooper@apple.com>
Tue, 18 Dec 2018 22:42:08 +0000 (22:42 +0000)
committerPete Cooper <peter_cooper@apple.com>
Tue, 18 Dec 2018 22:42:08 +0000 (22:42 +0000)
Clang uses weak linkage for objc runtime functions when they are not available on the platform.

The intrinsic has this linkage so we just need to pass that on to the runtime call.

llvm-svn: 349559

llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp
llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll

index 3689dab2331064cb6b869f937b85cc7aadb79a01..b0e9ac03612d10c45cc6e51ff9e7f5cf7e206183 100644 (file)
@@ -66,12 +66,15 @@ static bool lowerObjCCall(Function &F, const char *NewFn,
   // program already contains a function with this name.
   Module *M = F.getParent();
   Constant* FCache = M->getOrInsertFunction(NewFn, F.getFunctionType());
-  
-  // If we have Native ARC, set nonlazybind attribute for these APIs for
-  // performance.
-  if (setNonLazyBind)
-    if (Function* Fn = dyn_cast<Function>(FCache))
+
+  if (Function* Fn = dyn_cast<Function>(FCache)) {
+    Fn->setLinkage(F.getLinkage());
+    if (setNonLazyBind && !Fn->isWeakForLinker()) {
+      // If we have Native ARC, set nonlazybind attribute for these APIs for
+      // performance.
       Fn->addFnAttr(Attribute::NonLazyBind);
+    }
+  }
 
   for (auto I = F.use_begin(), E = F.use_end(); I != E;) {
     auto *CI = dyn_cast<CallInst>(I->getUser());
index 235ef65beee266a5295e302dd81aa84a0006b79c..8b7d11ea75f43314f16d45c6f8caa89edc625164 100644 (file)
@@ -260,7 +260,7 @@ declare i8* @llvm.objc.autoreleasePoolPush()
 declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
 declare void @llvm.objc.copyWeak(i8**, i8**)
 declare void @llvm.objc.destroyWeak(i8**)
-declare i8* @llvm.objc.initWeak(i8**, i8*)
+declare extern_weak i8* @llvm.objc.initWeak(i8**, i8*)
 declare i8* @llvm.objc.loadWeak(i8**)
 declare i8* @llvm.objc.loadWeakRetained(i8**)
 declare void @llvm.objc.moveWeak(i8**, i8**)
@@ -280,7 +280,33 @@ declare i8* @llvm.objc.retain.autorelease(i8*)
 declare i32 @llvm.objc.sync.enter(i8*)
 declare i32 @llvm.objc.sync.exit(i8*)
 
+attributes #0 = { nounwind }
+
+; CHECK: declare i8* @objc_autorelease(i8*)
+; CHECK: declare void @objc_autoreleasePoolPop(i8*)
+; CHECK: declare i8* @objc_autoreleasePoolPush()
+; CHECK: declare i8* @objc_autoreleaseReturnValue(i8*)
+; CHECK: declare void @objc_copyWeak(i8**, i8**)
+; CHECK: declare void @objc_destroyWeak(i8**)
+; CHECK: declare extern_weak i8* @objc_initWeak(i8**, i8*)
+; CHECK: declare i8* @objc_loadWeak(i8**)
+; CHECK: declare i8* @objc_loadWeakRetained(i8**)
+; CHECK: declare void @objc_moveWeak(i8**, i8**)
 ; CHECK: declare void @objc_release(i8*) [[NLB:#[0-9]+]]
 ; CHECK: declare i8* @objc_retain(i8*) [[NLB]]
+; CHECK: declare i8* @objc_retainAutorelease(i8*)
+; CHECK: declare i8* @objc_retainAutoreleaseReturnValue(i8*)
+; CHECK: declare i8* @objc_retainAutoreleasedReturnValue(i8*)
+; CHECK: declare i8* @objc_retainBlock(i8*)
+; CHECK: declare void @objc_storeStrong(i8**, i8*)
+; CHECK: declare i8* @objc_storeWeak(i8**, i8*)
+; CHECK: declare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*)
+; CHECK: declare i8* @objc_retainedObject(i8*)
+; CHECK: declare i8* @objc_unretainedObject(i8*)
+; CHECK: declare i8* @objc_unretainedPointer(i8*)
+; CHECK: declare i8* @objc_retain_autorelease(i8*)
+; CHECK: declare i32 @objc_sync_enter(i8*)
+; CHECK: declare i32 @objc_sync_exit(i8*)
 
+; CHECK: attributes #0 = { nounwind }
 ; CHECK: attributes [[NLB]] = { nonlazybind }