aboutsummaryrefslogtreecommitdiffstats
path: root/test/CodeGen/Generic/GC
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2010-02-10 11:10:31 -0800
committerShih-wei Liao <sliao@google.com>2010-02-10 11:10:31 -0800
commite264f62ca09a8f65c87a46d562a4d0f9ec5d457e (patch)
tree59e3d57ef656cef79afa708ae0a3daf25cd91fcf /test/CodeGen/Generic/GC
downloadexternal_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.zip
external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.gz
external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.bz2
Check in LLVM r95781.
Diffstat (limited to 'test/CodeGen/Generic/GC')
-rw-r--r--test/CodeGen/Generic/GC/alloc_loop.ll53
-rw-r--r--test/CodeGen/Generic/GC/argpromotion.ll19
-rw-r--r--test/CodeGen/Generic/GC/badreadproto.ll13
-rw-r--r--test/CodeGen/Generic/GC/badrootproto.ll13
-rw-r--r--test/CodeGen/Generic/GC/badwriteproto.ll22
-rw-r--r--test/CodeGen/Generic/GC/deadargelim.ll16
-rw-r--r--test/CodeGen/Generic/GC/dg.exp3
-rw-r--r--test/CodeGen/Generic/GC/fat.ll10
-rw-r--r--test/CodeGen/Generic/GC/inline.ll23
-rw-r--r--test/CodeGen/Generic/GC/inline2.ll24
-rw-r--r--test/CodeGen/Generic/GC/lower_gcroot.ll11
-rw-r--r--test/CodeGen/Generic/GC/outside.ll10
-rw-r--r--test/CodeGen/Generic/GC/redundant_init.ll17
-rw-r--r--test/CodeGen/Generic/GC/simple_ocaml.ll42
14 files changed, 276 insertions, 0 deletions
diff --git a/test/CodeGen/Generic/GC/alloc_loop.ll b/test/CodeGen/Generic/GC/alloc_loop.ll
new file mode 100644
index 0000000..fb78ba2
--- /dev/null
+++ b/test/CodeGen/Generic/GC/alloc_loop.ll
@@ -0,0 +1,53 @@
+; RUN: llc < %s
+
+
+declare i8* @llvm_gc_allocate(i32)
+declare void @llvm_gc_initialize(i32)
+
+declare void @llvm.gcroot(i8**, i8*)
+declare void @llvm.gcwrite(i8*, i8*, i8**)
+
+define i32 @main() gc "shadow-stack" {
+entry:
+ %A = alloca i8*
+ %B = alloca i8**
+
+ call void @llvm_gc_initialize(i32 1048576) ; Start with 1MB heap
+
+ ;; void *A;
+ call void @llvm.gcroot(i8** %A, i8* null)
+
+ ;; A = gcalloc(10);
+ %Aptr = call i8* @llvm_gc_allocate(i32 10)
+ store i8* %Aptr, i8** %A
+
+ ;; void **B;
+ %tmp.1 = bitcast i8*** %B to i8**
+ call void @llvm.gcroot(i8** %tmp.1, i8* null)
+
+ ;; B = gcalloc(4);
+ %B.upgrd.1 = call i8* @llvm_gc_allocate(i32 8)
+ %tmp.2 = bitcast i8* %B.upgrd.1 to i8**
+ store i8** %tmp.2, i8*** %B
+
+ ;; *B = A;
+ %B.1 = load i8*** %B
+ %A.1 = load i8** %A
+ call void @llvm.gcwrite(i8* %A.1, i8* %B.upgrd.1, i8** %B.1)
+
+ br label %AllocLoop
+
+AllocLoop:
+ %i = phi i32 [ 0, %entry ], [ %indvar.next, %AllocLoop ]
+ ;; Allocated mem: allocated memory is immediately dead.
+ call i8* @llvm_gc_allocate(i32 100)
+
+ %indvar.next = add i32 %i, 1
+ %exitcond = icmp eq i32 %indvar.next, 10000000
+ br i1 %exitcond, label %Exit, label %AllocLoop
+
+Exit:
+ ret i32 0
+}
+
+declare void @__main()
diff --git a/test/CodeGen/Generic/GC/argpromotion.ll b/test/CodeGen/Generic/GC/argpromotion.ll
new file mode 100644
index 0000000..dda376d
--- /dev/null
+++ b/test/CodeGen/Generic/GC/argpromotion.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -anders-aa -argpromotion
+
+declare void @llvm.gcroot(i8**, i8*)
+
+define i32 @g() {
+entry:
+ %var = alloca i32
+ store i32 1, i32* %var
+ %x = call i32 @f(i32* %var)
+ ret i32 %x
+}
+
+define internal i32 @f(i32* %xp) gc "example" {
+entry:
+ %var = alloca i8*
+ call void @llvm.gcroot(i8** %var, i8* null)
+ %x = load i32* %xp
+ ret i32 %x
+}
diff --git a/test/CodeGen/Generic/GC/badreadproto.ll b/test/CodeGen/Generic/GC/badreadproto.ll
new file mode 100644
index 0000000..4fe90b9
--- /dev/null
+++ b/test/CodeGen/Generic/GC/badreadproto.ll
@@ -0,0 +1,13 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+ %list = type { i32, %list* }
+
+; This usage is invalid now; instead, objects must be bitcast to i8* for input
+; to the gc intrinsics.
+declare %list* @llvm.gcread(%list*, %list**)
+
+define %list* @tl(%list* %l) gc "example" {
+ %hd.ptr = getelementptr %list* %l, i32 0, i32 0
+ %hd = call %list* @llvm.gcread(%list* %l, %list** %hd.ptr)
+ ret i32 %tmp
+}
diff --git a/test/CodeGen/Generic/GC/badrootproto.ll b/test/CodeGen/Generic/GC/badrootproto.ll
new file mode 100644
index 0000000..ff86d03
--- /dev/null
+++ b/test/CodeGen/Generic/GC/badrootproto.ll
@@ -0,0 +1,13 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+ %list = type { i32, %list* }
+ %meta = type opaque
+
+; This usage is invalid now; instead, objects must be bitcast to i8* for input
+; to the gc intrinsics.
+declare void @llvm.gcroot(%list*, %meta*)
+
+define void @root() gc "example" {
+ %x.var = alloca i8*
+ call void @llvm.gcroot(i8** %x.var, %meta* null)
+}
diff --git a/test/CodeGen/Generic/GC/badwriteproto.ll b/test/CodeGen/Generic/GC/badwriteproto.ll
new file mode 100644
index 0000000..be81f84
--- /dev/null
+++ b/test/CodeGen/Generic/GC/badwriteproto.ll
@@ -0,0 +1,22 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+ %list = type { i32, %list* }
+
+; This usage is invalid now; instead, objects must be bitcast to i8* for input
+; to the gc intrinsics.
+declare void @llvm.gcwrite(%list*, %list*, %list**)
+
+define %list* @cons(i32 %hd, %list* %tl) gc "example" {
+ %tmp = call i8* @gcalloc(i32 bitcast(%list* getelementptr(%list* null, i32 1) to i32))
+ %cell = bitcast i8* %tmp to %list*
+
+ %hd.ptr = getelementptr %list* %cell, i32 0, i32 0
+ store i32 %hd, i32* %hd.ptr
+
+ %tl.ptr = getelementptr %list* %cell, i32 0, i32 0
+ call void @llvm.gcwrite(%list* %tl, %list* %cell, %list** %tl.ptr)
+
+ ret %cell.2
+}
+
+declare i8* @gcalloc(i32)
diff --git a/test/CodeGen/Generic/GC/deadargelim.ll b/test/CodeGen/Generic/GC/deadargelim.ll
new file mode 100644
index 0000000..1760190
--- /dev/null
+++ b/test/CodeGen/Generic/GC/deadargelim.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -deadargelim
+
+declare void @llvm.gcroot(i8**, i8*)
+
+define void @g() {
+entry:
+ call void @f(i32 0)
+ ret void
+}
+
+define internal void @f(i32 %unused) gc "example" {
+entry:
+ %var = alloca i8*
+ call void @llvm.gcroot(i8** %var, i8* null)
+ ret void
+}
diff --git a/test/CodeGen/Generic/GC/dg.exp b/test/CodeGen/Generic/GC/dg.exp
new file mode 100644
index 0000000..f200589
--- /dev/null
+++ b/test/CodeGen/Generic/GC/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/test/CodeGen/Generic/GC/fat.ll b/test/CodeGen/Generic/GC/fat.ll
new file mode 100644
index 0000000..d05ca3d
--- /dev/null
+++ b/test/CodeGen/Generic/GC/fat.ll
@@ -0,0 +1,10 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+declare void @llvm.gcroot(i8**, i8*) nounwind
+
+define void @f() gc "x" {
+ %st = alloca { i8*, i1 } ; <{ i8*, i1 }*> [#uses=1]
+ %st_ptr = bitcast { i8*, i1 }* %st to i8** ; <i8**> [#uses=1]
+ call void @llvm.gcroot(i8** %st_ptr, i8* null)
+ ret void
+}
diff --git a/test/CodeGen/Generic/GC/inline.ll b/test/CodeGen/Generic/GC/inline.ll
new file mode 100644
index 0000000..9da33ae
--- /dev/null
+++ b/test/CodeGen/Generic/GC/inline.ll
@@ -0,0 +1,23 @@
+; RUN: opt < %s -inline -S | grep example
+
+ %IntArray = type { i32, [0 x i32*] }
+
+declare void @llvm.gcroot(i8**, i8*) nounwind
+
+define i32 @f() {
+ %x = call i32 @g( ) ; <i32> [#uses=1]
+ ret i32 %x
+}
+
+define internal i32 @g() gc "example" {
+ %root = alloca i8* ; <i8**> [#uses=2]
+ call void @llvm.gcroot( i8** %root, i8* null )
+ %obj = call %IntArray* @h( ) ; <%IntArray*> [#uses=2]
+ %obj.2 = bitcast %IntArray* %obj to i8* ; <i8*> [#uses=1]
+ store i8* %obj.2, i8** %root
+ %Length.ptr = getelementptr %IntArray* %obj, i32 0, i32 0 ; <i32*> [#uses=1]
+ %Length = load i32* %Length.ptr ; <i32> [#uses=1]
+ ret i32 %Length
+}
+
+declare %IntArray* @h()
diff --git a/test/CodeGen/Generic/GC/inline2.ll b/test/CodeGen/Generic/GC/inline2.ll
new file mode 100644
index 0000000..1594705
--- /dev/null
+++ b/test/CodeGen/Generic/GC/inline2.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -inline -S | grep sample
+; RUN: opt < %s -inline -S | grep example
+
+ %IntArray = type { i32, [0 x i32*] }
+
+declare void @llvm.gcroot(i8**, i8*) nounwind
+
+define i32 @f() gc "sample" {
+ %x = call i32 @g( ) ; <i32> [#uses=1]
+ ret i32 %x
+}
+
+define internal i32 @g() gc "example" {
+ %root = alloca i8* ; <i8**> [#uses=2]
+ call void @llvm.gcroot( i8** %root, i8* null )
+ %obj = call %IntArray* @h( ) ; <%IntArray*> [#uses=2]
+ %obj.2 = bitcast %IntArray* %obj to i8* ; <i8*> [#uses=1]
+ store i8* %obj.2, i8** %root
+ %Length.ptr = getelementptr %IntArray* %obj, i32 0, i32 0 ; <i32*> [#uses=1]
+ %Length = load i32* %Length.ptr ; <i32> [#uses=1]
+ ret i32 %Length
+}
+
+declare %IntArray* @h()
diff --git a/test/CodeGen/Generic/GC/lower_gcroot.ll b/test/CodeGen/Generic/GC/lower_gcroot.ll
new file mode 100644
index 0000000..c2d418a
--- /dev/null
+++ b/test/CodeGen/Generic/GC/lower_gcroot.ll
@@ -0,0 +1,11 @@
+; RUN: llc < %s
+
+ %Env = type i8*
+
+define void @.main(%Env) gc "shadow-stack" {
+ %Root = alloca %Env
+ call void @llvm.gcroot( %Env* %Root, %Env null )
+ unreachable
+}
+
+declare void @llvm.gcroot(%Env*, %Env)
diff --git a/test/CodeGen/Generic/GC/outside.ll b/test/CodeGen/Generic/GC/outside.ll
new file mode 100644
index 0000000..2968c69
--- /dev/null
+++ b/test/CodeGen/Generic/GC/outside.ll
@@ -0,0 +1,10 @@
+; RUN: not llvm-as < %s >& /dev/null
+
+declare void @llvm.gcroot(i8**, i8*)
+
+define void @f(i8* %x) {
+ %root = alloca i8*
+ call void @llvm.gcroot(i8** %root, i8* null)
+ store i8* %x, i8** %root
+ ret void
+}
diff --git a/test/CodeGen/Generic/GC/redundant_init.ll b/test/CodeGen/Generic/GC/redundant_init.ll
new file mode 100644
index 0000000..10c70e7
--- /dev/null
+++ b/test/CodeGen/Generic/GC/redundant_init.ll
@@ -0,0 +1,17 @@
+; RUN: llc < %s -march=x86 | \
+; RUN: ignore grep {movl..0} | count 0
+
+%struct.obj = type { i8*, %struct.obj* }
+
+declare void @g() gc "shadow-stack"
+
+define void @f(i8* %o) gc "shadow-stack" {
+entry:
+ %root = alloca i8*
+ call void @llvm.gcroot(i8** %root, i8* null)
+ store i8* %o, i8** %root
+ call void @g()
+ ret void
+}
+
+declare void @llvm.gcroot(i8**, i8*)
diff --git a/test/CodeGen/Generic/GC/simple_ocaml.ll b/test/CodeGen/Generic/GC/simple_ocaml.ll
new file mode 100644
index 0000000..f765dc0
--- /dev/null
+++ b/test/CodeGen/Generic/GC/simple_ocaml.ll
@@ -0,0 +1,42 @@
+; RUN: llc < %s | grep caml.*__frametable
+; RUN: llc < %s -march=x86 | grep {movl .0}
+
+%struct.obj = type { i8*, %struct.obj* }
+
+define %struct.obj* @fun(%struct.obj* %head) gc "ocaml" {
+entry:
+ %gcroot.0 = alloca i8*
+ %gcroot.1 = alloca i8*
+
+ call void @llvm.gcroot(i8** %gcroot.0, i8* null)
+ call void @llvm.gcroot(i8** %gcroot.1, i8* null)
+
+ %local.0 = bitcast i8** %gcroot.0 to %struct.obj**
+ %local.1 = bitcast i8** %gcroot.1 to %struct.obj**
+
+ store %struct.obj* %head, %struct.obj** %local.0
+ br label %bb.loop
+bb.loop:
+ %t0 = load %struct.obj** %local.0
+ %t1 = getelementptr %struct.obj* %t0, i32 0, i32 1
+ %t2 = bitcast %struct.obj* %t0 to i8*
+ %t3 = bitcast %struct.obj** %t1 to i8**
+ %t4 = call i8* @llvm.gcread(i8* %t2, i8** %t3)
+ %t5 = bitcast i8* %t4 to %struct.obj*
+ %t6 = icmp eq %struct.obj* %t5, null
+ br i1 %t6, label %bb.loop, label %bb.end
+bb.end:
+ %t7 = malloc %struct.obj
+ store %struct.obj* %t7, %struct.obj** %local.1
+ %t8 = bitcast %struct.obj* %t7 to i8*
+ %t9 = load %struct.obj** %local.0
+ %t10 = getelementptr %struct.obj* %t9, i32 0, i32 1
+ %t11 = bitcast %struct.obj* %t9 to i8*
+ %t12 = bitcast %struct.obj** %t10 to i8**
+ call void @llvm.gcwrite(i8* %t8, i8* %t11, i8** %t12)
+ ret %struct.obj* %t7
+}
+
+declare void @llvm.gcroot(i8** %value, i8* %tag)
+declare void @llvm.gcwrite(i8* %value, i8* %obj, i8** %field)
+declare i8* @llvm.gcread(i8* %obj, i8** %field)