[ObjC][ARC] Convert the retainRV marker that is passed as a named

metadata into a module flag in the auto-upgrader and make the ARC
contract pass read the marker as a module flag.

This is needed to fix a bug where ARC contract wasn't inserting the
retainRV marker when LTO was enabled, which caused objects returned
from a function to be auto-released.

rdar://problem/49464214

Differential Revision: https://reviews.llvm.org/D60303

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358047 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2019-04-10 06:20:20 +00:00
parent be304b73c9
commit 9eaa79da9e
6 changed files with 17 additions and 23 deletions

View File

@ -3765,8 +3765,8 @@ bool llvm::UpgradeDebugInfo(Module &M) {
bool llvm::UpgradeRetainReleaseMarker(Module &M) {
bool Changed = false;
NamedMDNode *ModRetainReleaseMarker =
M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker");
const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
if (ModRetainReleaseMarker) {
MDNode *Op = ModRetainReleaseMarker->getOperand(0);
if (Op) {
@ -3776,11 +3776,11 @@ bool llvm::UpgradeRetainReleaseMarker(Module &M) {
ID->getString().split(ValueComp, "#");
if (ValueComp.size() == 2) {
std::string NewValue = ValueComp[0].str() + ";" + ValueComp[1].str();
Metadata *Ops[1] = {MDString::get(M.getContext(), NewValue)};
ModRetainReleaseMarker->setOperand(0,
MDNode::get(M.getContext(), Ops));
Changed = true;
ID = MDString::get(M.getContext(), NewValue);
}
M.addModuleFlag(Module::Error, MarkerKey, ID);
M.eraseNamedMetadata(ModRetainReleaseMarker);
Changed = true;
}
}
}

View File

@ -744,15 +744,8 @@ bool ObjCARCContract::doInitialization(Module &M) {
EP.init(&M);
// Initialize RVInstMarker.
RVInstMarker = nullptr;
if (NamedMDNode *NMD =
M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker"))
if (NMD->getNumOperands() == 1) {
const MDNode *N = NMD->getOperand(0);
if (N->getNumOperands() == 1)
if (const MDString *S = dyn_cast<MDString>(N->getOperand(0)))
RVInstMarker = S;
}
const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
return false;
}

View File

@ -2,5 +2,5 @@
;
; RUN: llvm-dis < %s.bc | FileCheck %s
; CHECK: "mov\09fp, fp\09\09; marker for objc_retainAutoreleaseReturnValue"
; CHECK: !llvm.module.flags = !{!0}
; CHECK: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09fp, fp\09\09; marker for objc_retainAutoreleaseReturnValue"}

View File

@ -48,8 +48,9 @@ declare dllimport i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
declare dllimport void @llvm.objc.release(i8*)
!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
!0 = !{!"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"}
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"}
; CHECK-LABEL: catch
; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]

View File

@ -38,8 +38,8 @@ declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
declare void @bar(i8*)
!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
!llvm.module.flags = !{!0}
!0 = !{!"mov\09r7, r7\09\09@ marker for return value optimization"}
!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09r7, r7\09\09@ marker for return value optimization"}
; CHECK: attributes [[NUW]] = { nounwind }

View File

@ -87,9 +87,9 @@ lpad: ; preds = %entry
resume { i8*, i32 } undef
}
!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
!llvm.module.flags = !{!0}
!0 = !{!"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
; CHECK: attributes #0 = { optsize }
; CHECK: attributes [[NUW]] = { nounwind }