[ObjC][ARC] Clear the lists of basic blocks and instructions before

continuing the loop

This fixes a bug introduced in c6f1713c46e61bbb8ece9ac5ac329d02e7f93228.
This commit is contained in:
Akira Hatanaka 2020-11-12 18:33:29 -08:00
parent d3715b5a06
commit 09266e4af0
2 changed files with 29 additions and 1 deletions

View File

@ -2358,8 +2358,11 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
if (HasSafePathToCall &&
GetBasicARCInstKind(Retain) == ARCInstKind::RetainRV &&
GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV &&
!cast<CallInst>(*DependingInstructions.begin())->isTailCall())
!cast<CallInst>(*DependingInstructions.begin())->isTailCall()) {
DependingInstructions.clear();
Visited.clear();
continue;
}
DependingInstructions.clear();
Visited.clear();

View File

@ -427,6 +427,31 @@ lpad:
resume { i8*, i32 } %4
}
; The second retainRV/autoreleaseRV pair can be removed since the call to
; @returner is a tail call.
; CHECK-LABEL: define i8* @test30(
; CHECK: %[[V0:.*]] = call i8* @returner()
; CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V0]])
; CHECK-NEXT: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[V0]])
; CHECK-NEXT: ret i8* %[[V0]]
; CHECK: %[[V3:.*]] = tail call i8* @returner()
; CHECK-NEXT: ret i8* %[[V3]]
define i8* @test30(i1 %cond) {
br i1 %cond, label %bb0, label %bb1
bb0:
%v0 = call i8* @returner()
%v1 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %v0)
%v2 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %v0)
ret i8* %v0
bb1:
%v3 = tail call i8* @returner()
%v4 = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %v3)
%v5 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %v3)
ret i8* %v3
}
!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }