mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 22:20:37 +00:00
[objc-arc] Convert the one directional retain/release relation assert to a conditional check + fail.
Due to the previously added overflow checks, we can have a retain/release relation that is one directional. This occurs specifically when we run into an additive overflow causing us to drop state in only one direction. If that occurs, we should bail and not optimize that retain/release instead of asserting. Apologies for the size of the testcase. It is necessary to cause the additive cfg overflow to trigger. rdar://15377890 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194083 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
04ae34b0aa
commit
f23af8bfd8
@ -2405,7 +2405,15 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
|
|||||||
if (Jt == Releases.end())
|
if (Jt == Releases.end())
|
||||||
return false;
|
return false;
|
||||||
const RRInfo &NewRetainReleaseRRI = Jt->second;
|
const RRInfo &NewRetainReleaseRRI = Jt->second;
|
||||||
assert(NewRetainReleaseRRI.Calls.count(NewRetain));
|
|
||||||
|
// If the release does not have a reference to the retain as well,
|
||||||
|
// something happened which is unaccounted for. Do not do anything.
|
||||||
|
//
|
||||||
|
// This can happen if we catch an additive overflow during path count
|
||||||
|
// merging.
|
||||||
|
if (!NewRetainReleaseRRI.Calls.count(NewRetain))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (ReleasesToMove.Calls.insert(NewRetainRelease)) {
|
if (ReleasesToMove.Calls.insert(NewRetainRelease)) {
|
||||||
|
|
||||||
// If we overflow when we compute the path count, don't remove/move
|
// If we overflow when we compute the path count, don't remove/move
|
||||||
@ -2481,9 +2489,16 @@ ObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
|
|||||||
if (Jt == Retains.end())
|
if (Jt == Retains.end())
|
||||||
return false;
|
return false;
|
||||||
const RRInfo &NewReleaseRetainRRI = Jt->second;
|
const RRInfo &NewReleaseRetainRRI = Jt->second;
|
||||||
assert(NewReleaseRetainRRI.Calls.count(NewRelease));
|
|
||||||
if (RetainsToMove.Calls.insert(NewReleaseRetain)) {
|
|
||||||
|
|
||||||
|
// If the retain does not have a reference to the release as well,
|
||||||
|
// something happened which is unaccounted for. Do not do anything.
|
||||||
|
//
|
||||||
|
// This can happen if we catch an additive overflow during path count
|
||||||
|
// merging.
|
||||||
|
if (!NewReleaseRetainRRI.Calls.count(NewRelease))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (RetainsToMove.Calls.insert(NewReleaseRetain)) {
|
||||||
// If we overflow when we compute the path count, don't remove/move
|
// If we overflow when we compute the path count, don't remove/move
|
||||||
// anything.
|
// anything.
|
||||||
const BBState &NRRBBState = BBStates[NewReleaseRetain->getParent()];
|
const BBState &NRRBBState = BBStates[NewReleaseRetain->getParent()];
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
; rdar://12277446
|
; rdar://12277446
|
||||||
; rdar://12480535
|
; rdar://12480535
|
||||||
; rdar://14590914
|
; rdar://14590914
|
||||||
|
; rdar://15377890
|
||||||
|
|
||||||
; The total number of paths grows exponentially with the number of branches, and a
|
; The total number of paths grows exponentially with the number of branches, and a
|
||||||
; computation of this number can overflow any reasonable fixed-sized
|
; computation of this number can overflow any reasonable fixed-sized
|
||||||
@ -15,6 +16,7 @@ target triple = "thumbv7-apple-ios5.0.0"
|
|||||||
%struct.CGPoint = type { float, float }
|
%struct.CGPoint = type { float, float }
|
||||||
|
|
||||||
@_unnamed_cfstring = external constant %struct.NSConstantString, section "__DATA,__cfstring"
|
@_unnamed_cfstring = external constant %struct.NSConstantString, section "__DATA,__cfstring"
|
||||||
|
@_unnamed_cfstring_2 = external constant %struct.NSConstantString, section "__DATA,__cfstring"
|
||||||
|
|
||||||
declare i8* @objc_retain(i8*) nonlazybind
|
declare i8* @objc_retain(i8*) nonlazybind
|
||||||
declare i8* @objc_retainAutoreleasedReturnValue(i8*) nonlazybind
|
declare i8* @objc_retainAutoreleasedReturnValue(i8*) nonlazybind
|
||||||
@ -24,6 +26,7 @@ declare i8* @objc_msgSend(i8*, i8*, ...) nonlazybind
|
|||||||
declare void @NSLog(i8*, ...)
|
declare void @NSLog(i8*, ...)
|
||||||
declare void @objc_msgSend_stret(i8*, i8*, ...)
|
declare void @objc_msgSend_stret(i8*, i8*, ...)
|
||||||
declare i32 @__gxx_personality_sj0(...)
|
declare i32 @__gxx_personality_sj0(...)
|
||||||
|
declare i32 @__objc_personality_v0(...)
|
||||||
|
|
||||||
|
|
||||||
define hidden void @test1() {
|
define hidden void @test1() {
|
||||||
@ -1914,4 +1917,277 @@ eh.resume: ; preds = %lpad580, %ehcleanup
|
|||||||
resume { i8*, i32 } undef
|
resume { i8*, i32 } undef
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@"OBJC_EHTYPE_$_NSException" = external global i8
|
||||||
|
|
||||||
|
define void @test4() {
|
||||||
|
entry:
|
||||||
|
br i1 undef, label %if.end13, label %if.then10
|
||||||
|
|
||||||
|
if.then10: ; preds = %entry
|
||||||
|
br label %if.end13
|
||||||
|
|
||||||
|
if.end13: ; preds = %if.then10, %entry
|
||||||
|
%0 = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*, i64, i8*, i8)*)(i8* undef, i8* undef, i8* bitcast (%struct.NSConstantString* @_unnamed_cfstring to i8*), i64 2, i8* bitcast (%struct.NSConstantString* @_unnamed_cfstring_2 to i8*), i8 signext 0), !clang.arc.no_objc_arc_exceptions !0
|
||||||
|
br i1 undef, label %if.then17, label %if.end18
|
||||||
|
|
||||||
|
if.then17: ; preds = %if.end13
|
||||||
|
br label %if.end18
|
||||||
|
|
||||||
|
if.end18: ; preds = %if.then17, %if.end13
|
||||||
|
br i1 undef, label %if.then64, label %if.end73
|
||||||
|
|
||||||
|
if.then64: ; preds = %if.end18
|
||||||
|
br i1 undef, label %cond.end71, label %cond.true68
|
||||||
|
|
||||||
|
cond.true68: ; preds = %if.then64
|
||||||
|
br label %cond.end71
|
||||||
|
|
||||||
|
cond.end71: ; preds = %cond.true68, %if.then64
|
||||||
|
br i1 undef, label %cleanup.action, label %cleanup.done
|
||||||
|
|
||||||
|
cleanup.action: ; preds = %cond.end71
|
||||||
|
br label %cleanup.done
|
||||||
|
|
||||||
|
cleanup.done: ; preds = %cleanup.action, %cond.end71
|
||||||
|
br label %if.end73
|
||||||
|
|
||||||
|
if.end73: ; preds = %cleanup.done, %if.end18
|
||||||
|
br i1 undef, label %forcoll.empty, label %forcoll.loopinit
|
||||||
|
|
||||||
|
forcoll.loopinit: ; preds = %if.end73
|
||||||
|
br label %forcoll.loopbody.outer
|
||||||
|
|
||||||
|
forcoll.loopbody.outer: ; preds = %forcoll.refetch, %forcoll.loopinit
|
||||||
|
br label %forcoll.loopbody
|
||||||
|
|
||||||
|
forcoll.loopbody: ; preds = %forcoll.notmutated, %forcoll.loopbody.outer
|
||||||
|
br i1 undef, label %forcoll.notmutated, label %forcoll.mutated
|
||||||
|
|
||||||
|
forcoll.mutated: ; preds = %forcoll.loopbody
|
||||||
|
br label %forcoll.notmutated
|
||||||
|
|
||||||
|
forcoll.notmutated: ; preds = %forcoll.mutated, %forcoll.loopbody
|
||||||
|
br i1 undef, label %forcoll.loopbody, label %forcoll.refetch
|
||||||
|
|
||||||
|
forcoll.refetch: ; preds = %forcoll.notmutated
|
||||||
|
br i1 undef, label %forcoll.empty, label %forcoll.loopbody.outer
|
||||||
|
|
||||||
|
forcoll.empty: ; preds = %forcoll.refetch, %if.end73
|
||||||
|
br i1 undef, label %if.end85, label %if.then82
|
||||||
|
|
||||||
|
if.then82: ; preds = %forcoll.empty
|
||||||
|
br label %if.end85
|
||||||
|
|
||||||
|
if.end85: ; preds = %if.then82, %forcoll.empty
|
||||||
|
br i1 undef, label %if.then87, label %if.end102
|
||||||
|
|
||||||
|
if.then87: ; preds = %if.end85
|
||||||
|
br i1 undef, label %if.end94, label %if.then91
|
||||||
|
|
||||||
|
if.then91: ; preds = %if.then87
|
||||||
|
br label %if.end94
|
||||||
|
|
||||||
|
if.end94: ; preds = %if.then91, %if.then87
|
||||||
|
br i1 undef, label %if.end101, label %if.then98
|
||||||
|
|
||||||
|
if.then98: ; preds = %if.end94
|
||||||
|
br label %if.end101
|
||||||
|
|
||||||
|
if.end101: ; preds = %if.then98, %if.end94
|
||||||
|
br label %if.end102
|
||||||
|
|
||||||
|
if.end102: ; preds = %if.end101, %if.end85
|
||||||
|
br i1 undef, label %do.body113, label %if.then107
|
||||||
|
|
||||||
|
if.then107: ; preds = %if.end102
|
||||||
|
br label %do.body113
|
||||||
|
|
||||||
|
do.body113: ; preds = %if.then107, %if.end102
|
||||||
|
br i1 undef, label %if.then116, label %if.end117
|
||||||
|
|
||||||
|
if.then116: ; preds = %do.body113
|
||||||
|
br label %if.end117
|
||||||
|
|
||||||
|
if.end117: ; preds = %if.then116, %do.body113
|
||||||
|
br i1 undef, label %if.then125, label %if.end126
|
||||||
|
|
||||||
|
if.then125: ; preds = %if.end117
|
||||||
|
br label %if.end126
|
||||||
|
|
||||||
|
if.end126: ; preds = %if.then125, %if.end117
|
||||||
|
br i1 undef, label %do.end166, label %cond.true132
|
||||||
|
|
||||||
|
cond.true132: ; preds = %if.end126
|
||||||
|
br i1 undef, label %do.body148, label %cond.true151
|
||||||
|
|
||||||
|
do.body148: ; preds = %cond.true132
|
||||||
|
br i1 undef, label %do.end166, label %cond.true151
|
||||||
|
|
||||||
|
cond.true151: ; preds = %do.body148, %cond.true132
|
||||||
|
br i1 undef, label %if.then162, label %do.end166
|
||||||
|
|
||||||
|
if.then162: ; preds = %cond.true151
|
||||||
|
br label %do.end166
|
||||||
|
|
||||||
|
do.end166: ; preds = %if.then162, %cond.true151, %do.body148, %if.end126
|
||||||
|
br i1 undef, label %if.then304, label %if.then170
|
||||||
|
|
||||||
|
if.then170: ; preds = %do.end166
|
||||||
|
br i1 undef, label %do.end193, label %cond.true179
|
||||||
|
|
||||||
|
cond.true179: ; preds = %if.then170
|
||||||
|
br i1 undef, label %if.then190, label %do.end193
|
||||||
|
|
||||||
|
if.then190: ; preds = %cond.true179
|
||||||
|
br label %do.end193
|
||||||
|
|
||||||
|
do.end193: ; preds = %if.then190, %cond.true179, %if.then170
|
||||||
|
br i1 undef, label %do.body200, label %do.body283
|
||||||
|
|
||||||
|
do.body200: ; preds = %do.end193
|
||||||
|
br i1 undef, label %do.end254, label %cond.true203
|
||||||
|
|
||||||
|
cond.true203: ; preds = %do.body200
|
||||||
|
br i1 undef, label %do.body218, label %cond.true221
|
||||||
|
|
||||||
|
do.body218: ; preds = %cond.true203
|
||||||
|
br i1 undef, label %do.end254, label %cond.true221
|
||||||
|
|
||||||
|
cond.true221: ; preds = %do.body218, %cond.true203
|
||||||
|
br i1 undef, label %if.then232, label %do.body236
|
||||||
|
|
||||||
|
if.then232: ; preds = %cond.true221
|
||||||
|
br label %do.body236
|
||||||
|
|
||||||
|
do.body236: ; preds = %if.then232, %cond.true221
|
||||||
|
br i1 undef, label %do.end254, label %cond.true239
|
||||||
|
|
||||||
|
cond.true239: ; preds = %do.body236
|
||||||
|
br i1 undef, label %if.then250, label %do.end254
|
||||||
|
|
||||||
|
if.then250: ; preds = %cond.true239
|
||||||
|
br label %do.end254
|
||||||
|
|
||||||
|
do.end254: ; preds = %if.then250, %cond.true239, %do.body236, %do.body218, %do.body200
|
||||||
|
br i1 undef, label %do.end277, label %cond.true263
|
||||||
|
|
||||||
|
cond.true263: ; preds = %do.end254
|
||||||
|
br i1 undef, label %if.then274, label %do.end277
|
||||||
|
|
||||||
|
if.then274: ; preds = %cond.true263
|
||||||
|
unreachable
|
||||||
|
|
||||||
|
do.end277: ; preds = %cond.true263, %do.end254
|
||||||
|
br i1 undef, label %if.then280, label %do.body283
|
||||||
|
|
||||||
|
if.then280: ; preds = %do.end277
|
||||||
|
br label %do.body283
|
||||||
|
|
||||||
|
do.body283: ; preds = %if.then280, %do.end277, %do.end193
|
||||||
|
br i1 undef, label %if.end301, label %cond.true286
|
||||||
|
|
||||||
|
cond.true286: ; preds = %do.body283
|
||||||
|
br i1 undef, label %if.then297, label %if.end301
|
||||||
|
|
||||||
|
if.then297: ; preds = %cond.true286
|
||||||
|
br label %if.end301
|
||||||
|
|
||||||
|
if.end301: ; preds = %if.then297, %cond.true286, %do.body283
|
||||||
|
br i1 undef, label %if.then304, label %do.body351
|
||||||
|
|
||||||
|
if.then304: ; preds = %if.end301, %do.end166
|
||||||
|
br i1 undef, label %do.body309.lr.ph, label %do.body351
|
||||||
|
|
||||||
|
do.body309.lr.ph: ; preds = %if.then304
|
||||||
|
br label %do.body309
|
||||||
|
|
||||||
|
do.body309: ; preds = %for.cond.backedge, %do.body309.lr.ph
|
||||||
|
br i1 undef, label %do.end328, label %cond.true312
|
||||||
|
|
||||||
|
cond.true312: ; preds = %do.body309
|
||||||
|
br i1 undef, label %if.then323, label %do.end328
|
||||||
|
|
||||||
|
if.then323: ; preds = %cond.true312
|
||||||
|
br label %do.end328
|
||||||
|
|
||||||
|
do.end328: ; preds = %if.then323, %cond.true312, %do.body309
|
||||||
|
br i1 undef, label %for.cond.backedge, label %cond.true335
|
||||||
|
|
||||||
|
for.cond.backedge: ; preds = %if.then346, %cond.true335, %do.end328
|
||||||
|
br i1 undef, label %do.body309, label %do.body351
|
||||||
|
|
||||||
|
cond.true335: ; preds = %do.end328
|
||||||
|
br i1 undef, label %if.then346, label %for.cond.backedge
|
||||||
|
|
||||||
|
if.then346: ; preds = %cond.true335
|
||||||
|
br label %for.cond.backedge
|
||||||
|
|
||||||
|
do.body351: ; preds = %for.cond.backedge, %if.then304, %if.end301
|
||||||
|
br i1 undef, label %if.then354, label %if.end355
|
||||||
|
|
||||||
|
if.then354: ; preds = %do.body351
|
||||||
|
br label %if.end355
|
||||||
|
|
||||||
|
if.end355: ; preds = %if.then354, %do.body351
|
||||||
|
br i1 undef, label %if.else, label %if.then364
|
||||||
|
|
||||||
|
if.then364: ; preds = %if.end355
|
||||||
|
br label %do.body366
|
||||||
|
|
||||||
|
if.else: ; preds = %if.end355
|
||||||
|
br label %do.body366
|
||||||
|
|
||||||
|
do.body366: ; preds = %if.else, %if.then364
|
||||||
|
br i1 undef, label %if.then369, label %if.end377.critedge
|
||||||
|
|
||||||
|
if.then369: ; preds = %do.body366
|
||||||
|
br label %if.end377
|
||||||
|
|
||||||
|
if.end377.critedge: ; preds = %do.body366
|
||||||
|
br label %if.end377
|
||||||
|
|
||||||
|
if.end377: ; preds = %if.end377.critedge, %if.then369
|
||||||
|
br i1 undef, label %if.then383, label %if.end392.critedge
|
||||||
|
|
||||||
|
if.then383: ; preds = %if.end377
|
||||||
|
br label %if.end392
|
||||||
|
|
||||||
|
if.end392.critedge: ; preds = %if.end377
|
||||||
|
br label %if.end392
|
||||||
|
|
||||||
|
if.end392: ; preds = %if.end392.critedge, %if.then383
|
||||||
|
br i1 undef, label %if.then398, label %if.end399
|
||||||
|
|
||||||
|
if.then398: ; preds = %if.end392
|
||||||
|
br label %if.end399
|
||||||
|
|
||||||
|
if.end399: ; preds = %if.then398, %if.end392
|
||||||
|
invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* undef, i8* undef)
|
||||||
|
to label %eh.cont unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
|
||||||
|
|
||||||
|
eh.cont: ; preds = %if.end399
|
||||||
|
br i1 undef, label %if.then430, label %if.end439.critedge
|
||||||
|
|
||||||
|
if.then430: ; preds = %eh.cont
|
||||||
|
%1 = call i8* @objc_retain(i8* %0)
|
||||||
|
br label %if.end439
|
||||||
|
|
||||||
|
lpad: ; preds = %if.end399
|
||||||
|
%2 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
|
||||||
|
catch i8* @"OBJC_EHTYPE_$_NSException"
|
||||||
|
unreachable
|
||||||
|
|
||||||
|
if.end439.critedge: ; preds = %eh.cont
|
||||||
|
%3 = call i8* @objc_retain(i8* %0)
|
||||||
|
br label %if.end439
|
||||||
|
|
||||||
|
if.end439: ; preds = %if.end439.critedge, %if.then430
|
||||||
|
call void @objc_release(i8* %0), !clang.imprecise_release !0
|
||||||
|
unreachable
|
||||||
|
|
||||||
|
return: ; No predecessors!
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
!0 = metadata !{}
|
!0 = metadata !{}
|
||||||
|
Loading…
Reference in New Issue
Block a user