Skip to content

Commit 643ce61

Browse files
committed
[ObjC][ARC] Don't form a StoreStrong call if it is unsafe to move the
release call findSafeStoreForStoreStrongContraction checks whether it's safe to move the release call to the store by inspecting all instructions between the two, but was ignoring retain instructions. This was causing objects to be released and deallocated before they were retained. rdar://81668577
1 parent 767496d commit 643ce61

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,6 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
226226
// of Inst.
227227
ARCInstKind Class = GetBasicARCInstKind(Inst);
228228

229-
// If Inst is an unrelated retain, we don't care about it.
230-
//
231-
// TODO: This is one area where the optimization could be made more
232-
// aggressive.
233-
if (IsRetain(Class))
234-
continue;
235-
236229
// If we have seen the store, but not the release...
237230
if (Store) {
238231
// We need to make sure that it is safe to move the release from its
@@ -248,8 +241,18 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
248241
return nullptr;
249242
}
250243

251-
// Ok, now we know we have not seen a store yet. See if Inst can write to
252-
// our load location, if it can not, just ignore the instruction.
244+
// Ok, now we know we have not seen a store yet.
245+
246+
// If Inst is a retain, we don't care about it as it doesn't prevent moving
247+
// the load to the store.
248+
//
249+
// TODO: This is one area where the optimization could be made more
250+
// aggressive.
251+
if (IsRetain(Class))
252+
continue;
253+
254+
// See if Inst can write to our load location, if it can not, just ignore
255+
// the instruction.
253256
if (!isModSet(AA->getModRefInfo(Inst, Loc)))
254257
continue;
255258

llvm/test/Transforms/ObjCARC/contract-storestrong.ll

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,25 @@ define i8* @test13(i8* %a0, i8* %a1, i8** %addr, i8* %new) {
256256
ret i8* %retained
257257
}
258258

259+
; Cannot form a storeStrong call because it's unsafe to move the release call to
260+
; the store.
261+
262+
; CHECK-LABEL: define void @test14(
263+
; CHECK: %[[V0:.*]] = load i8*, i8** %a
264+
; CHECK: %[[V1:.*]] = call i8* @llvm.objc.retain(i8* %p)
265+
; CHECK: store i8* %[[V1]], i8** %a
266+
; CHECK: %[[V2:.*]] = call i8* @llvm.objc.retain(i8* %[[V0]])
267+
; CHECK: call void @llvm.objc.release(i8* %[[V2]])
268+
269+
define void @test14(i8** %a, i8* %p) {
270+
%v0 = load i8*, i8** %a, align 8
271+
%v1 = call i8* @llvm.objc.retain(i8* %p)
272+
store i8* %p, i8** %a, align 8
273+
%v2 = call i8* @llvm.objc.retain(i8* %v0)
274+
call void @llvm.objc.release(i8* %v0)
275+
ret void
276+
}
277+
259278
!0 = !{}
260279

261280
; CHECK: attributes [[NUW]] = { nounwind }

0 commit comments

Comments
 (0)