diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-03-26 02:28:59 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-03-26 02:28:59 +0000 |
commit | d934545ae6a00aa8a8179a93d11cbd93a5240849 (patch) | |
tree | ab44db08aa63a8f94a3e09d6491c4156c624af96 /test/Transforms/ObjCARC | |
parent | 868d4470cdfa9472353ea2a49a6c456ddae9c95b (diff) | |
parent | c204410d6bc435e7cb8ea768759a54135e8e92b5 (diff) |
Updating branches/google/testing to r177703testing
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/testing@177985 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/ObjCARC')
-rw-r--r-- | test/Transforms/ObjCARC/dont-infinite-loop-during-block-escape-analysis.ll | 87 | ||||
-rw-r--r-- | test/Transforms/ObjCARC/retain-block-escape-analysis.ll | 127 |
2 files changed, 127 insertions, 87 deletions
diff --git a/test/Transforms/ObjCARC/dont-infinite-loop-during-block-escape-analysis.ll b/test/Transforms/ObjCARC/dont-infinite-loop-during-block-escape-analysis.ll deleted file mode 100644 index bdee2be94f..0000000000 --- a/test/Transforms/ObjCARC/dont-infinite-loop-during-block-escape-analysis.ll +++ /dev/null @@ -1,87 +0,0 @@ -; RUN: opt -S -objc-arc < %s -; bugzilla://14551 -; rdar://12851911 - -; Make sure that we do not hang clang during escape analysis. - -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" -target triple = "x86_64-darwin" - -%struct.__block_descriptor = type { i64, i64 } -%struct.__block_byref_foo = type { i8*, %struct.__block_byref_foo*, i32, i32, i32 } - -@_NSConcreteGlobalBlock = external global i8* -@.str = private unnamed_addr constant [6 x i8] c"v8@?0\00", align 1 -@__block_descriptor_tmp = internal constant { i64, i64, i8*, i8* } { i64 0, i64 32, i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i8* null } -@__block_literal_global = internal constant { i8**, i32, i32, i8*, %struct.__block_descriptor* } { i8** @_NSConcreteGlobalBlock, i32 1342177280, i32 0, i8* bitcast (void (i8*)* @__hang_clang_block_invoke to i8*), %struct.__block_descriptor* bitcast ({ i64, i64, i8*, i8* }* @__block_descriptor_tmp to %struct.__block_descriptor*) }, align 8 - -define void @hang_clang() uwtable optsize ssp { -entry: - %foo = alloca %struct.__block_byref_foo, align 8 - %byref.isa = getelementptr inbounds %struct.__block_byref_foo* %foo, i64 0, i32 0 - store i8* null, i8** %byref.isa, align 8 - %byref.forwarding = getelementptr inbounds %struct.__block_byref_foo* %foo, i64 0, i32 1 - store %struct.__block_byref_foo* %foo, %struct.__block_byref_foo** %byref.forwarding, align 8 - %byref.flags = getelementptr inbounds %struct.__block_byref_foo* %foo, i64 0, i32 2 - store i32 536870912, i32* %byref.flags, align 8 - %byref.size = getelementptr inbounds %struct.__block_byref_foo* %foo, i64 0, i32 3 - store i32 32, i32* %byref.size, align 4 - %foo1 = getelementptr inbounds %struct.__block_byref_foo* %foo, i64 0, i32 4 - store i32 0, i32* %foo1, align 8, !tbaa !4 - br label %for.body - -for.body: ; preds = %for.inc.for.body_crit_edge, %entry - %0 = phi i1 [ true, %entry ], [ %phitmp, %for.inc.for.body_crit_edge ] - %i.06 = phi i32 [ 1, %entry ], [ %phitmp8, %for.inc.for.body_crit_edge ] - %block.05 = phi void (...)* [ null, %entry ], [ %block.1, %for.inc.for.body_crit_edge ] - br i1 %0, label %for.inc, label %if.then - -if.then: ; preds = %for.body - %1 = call i8* @objc_retainBlock(i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global to i8*)) nounwind, !clang.arc.copy_on_escape !7 - %2 = bitcast i8* %1 to void (...)* - %3 = bitcast void (...)* %block.05 to i8* - call void @objc_release(i8* %3) nounwind, !clang.imprecise_release !7 - br label %for.inc - -for.inc: ; preds = %for.body, %if.then - %block.1 = phi void (...)* [ %2, %if.then ], [ %block.05, %for.body ] - %exitcond = icmp eq i32 %i.06, 10 - br i1 %exitcond, label %for.end, label %for.inc.for.body_crit_edge - -for.inc.for.body_crit_edge: ; preds = %for.inc - %.pre = load %struct.__block_byref_foo** %byref.forwarding, align 8 - %foo2.phi.trans.insert = getelementptr inbounds %struct.__block_byref_foo* %.pre, i64 0, i32 4 - %.pre7 = load i32* %foo2.phi.trans.insert, align 4, !tbaa !4 - %phitmp = icmp eq i32 %.pre7, 0 - %phitmp8 = add i32 %i.06, 1 - br label %for.body - -for.end: ; preds = %for.inc - %4 = bitcast %struct.__block_byref_foo* %foo to i8* - call void @_Block_object_dispose(i8* %4, i32 8) - %5 = bitcast void (...)* %block.1 to i8* - call void @objc_release(i8* %5) nounwind, !clang.imprecise_release !7 - ret void -} - -define internal void @__hang_clang_block_invoke(i8* nocapture %.block_descriptor) nounwind uwtable readnone optsize ssp { -entry: - ret void -} - -declare i8* @objc_retainBlock(i8*) - -declare void @objc_release(i8*) nonlazybind - -declare void @_Block_object_dispose(i8*, i32) - -!llvm.module.flags = !{!0, !1, !2, !3} - -!0 = metadata !{i32 1, metadata !"Objective-C Version", i32 2} -!1 = metadata !{i32 1, metadata !"Objective-C Image Info Version", i32 0} -!2 = metadata !{i32 1, metadata !"Objective-C Image Info Section", metadata !"__DATA, __objc_imageinfo, regular, no_dead_strip"} -!3 = metadata !{i32 4, metadata !"Objective-C Garbage Collection", i32 0} -!4 = metadata !{metadata !"int", metadata !5} -!5 = metadata !{metadata !"omnipotent char", metadata !6} -!6 = metadata !{metadata !"Simple C/C++ TBAA"} -!7 = metadata !{} diff --git a/test/Transforms/ObjCARC/retain-block-escape-analysis.ll b/test/Transforms/ObjCARC/retain-block-escape-analysis.ll new file mode 100644 index 0000000000..2c1ddce328 --- /dev/null +++ b/test/Transforms/ObjCARC/retain-block-escape-analysis.ll @@ -0,0 +1,127 @@ +; RUN: opt -S -objc-arc < %s | FileCheck %s + +declare i8* @objc_retain(i8*) nonlazybind +declare void @objc_release(i8*) nonlazybind +declare i8* @objc_retainBlock(i8*) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; Use by an instruction which copies the value is an escape if the ; +; result is an escape. The current instructions with this property are: ; +; ; +; 1. BitCast. ; +; 2. GEP. ; +; 3. PhiNode. ; +; 4. SelectInst. ; +; ; +; Make sure that such instructions do not confuse the optimizer into removing ; +; an objc_retainBlock that is needed. ; +; ; +; rdar://13273675. (With extra test cases to handle bitcast, phi, and select. ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +define void @bitcasttest(i8* %storage, void (...)* %block) { +; CHECK: define void @bitcasttest +entry: + %t1 = bitcast void (...)* %block to i8* +; CHECK-NOT: tail call i8* @objc_retain + %t2 = tail call i8* @objc_retain(i8* %t1) +; CHECK: tail call i8* @objc_retainBlock + %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0 + %t4 = bitcast i8* %storage to void (...)** + %t5 = bitcast i8* %t3 to void (...)* + store void (...)* %t5, void (...)** %t4, align 8 +; CHECK-NOT: call void @objc_release + call void @objc_release(i8* %t1) + ret void +} + +define void @geptest(void (...)** %storage_array, void (...)* %block) { +; CHECK: define void @geptest +entry: + %t1 = bitcast void (...)* %block to i8* +; CHECK-NOT: tail call i8* @objc_retain + %t2 = tail call i8* @objc_retain(i8* %t1) +; CHECK: tail call i8* @objc_retainBlock + %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0 + %t4 = bitcast i8* %t3 to void (...)* + + %storage = getelementptr inbounds void (...)** %storage_array, i64 0 + + store void (...)* %t4, void (...)** %storage, align 8 +; CHECK-NOT: call void @objc_release + call void @objc_release(i8* %t1) + ret void +} + +define void @selecttest(void (...)** %store1, void (...)** %store2, + void (...)* %block) { +; CHECK: define void @selecttest +entry: + %t1 = bitcast void (...)* %block to i8* +; CHECK-NOT: tail call i8* @objc_retain + %t2 = tail call i8* @objc_retain(i8* %t1) +; CHECK: tail call i8* @objc_retainBlock + %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0 + %t4 = bitcast i8* %t3 to void (...)* + %store = select i1 undef, void (...)** %store1, void (...)** %store2 + store void (...)* %t4, void (...)** %store, align 8 +; CHECK-NOT: call void @objc_release + call void @objc_release(i8* %t1) + ret void +} + +define void @phinodetest(void (...)** %storage1, + void (...)** %storage2, + void (...)* %block) { +; CHECK: define void @phinodetest +entry: + %t1 = bitcast void (...)* %block to i8* +; CHECK-NOT: tail call i8* @objc_retain + %t2 = tail call i8* @objc_retain(i8* %t1) +; CHECK: tail call i8* @objc_retainBlock + %t3 = tail call i8* @objc_retainBlock(i8* %t1), !clang.arc.copy_on_escape !0 + %t4 = bitcast i8* %t3 to void (...)* + br i1 undef, label %store1_set, label %store2_set + +store1_set: + br label %end + +store2_set: + br label %end + +end: + %storage = phi void (...)** [ %storage1, %store1_set ], [ %storage2, %store2_set] + store void (...)* %t4, void (...)** %storage, align 8 +; CHECK-NOT: call void @objc_release + call void @objc_release(i8* %t1) + ret void +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; This test makes sure that we do not hang clang when visiting a use ; +; cycle caused by phi nodes during objc-arc analysis. *NOTE* This ; +; test case looks a little convoluted since it was produced by ; +; bugpoint. ; +; ; +; bugzilla://14551 ; +; rdar://12851911 ; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +define void @phinode_use_cycle(i8* %block) uwtable optsize ssp { +; CHECK: define void @phinode_use_cycle(i8* %block) +entry: + br label %for.body + +for.body: ; preds = %if.then, %for.body, %entry + %block.05 = phi void (...)* [ null, %entry ], [ %1, %if.then ], [ %block.05, %for.body ] + br i1 undef, label %for.body, label %if.then + +if.then: ; preds = %for.body + %0 = call i8* @objc_retainBlock(i8* %block), !clang.arc.copy_on_escape !0 + %1 = bitcast i8* %0 to void (...)* + %2 = bitcast void (...)* %block.05 to i8* + call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0 + br label %for.body +} + +!0 = metadata !{} |