aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/TailCallElim
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/TailCallElim')
-rw-r--r--test/Transforms/TailCallElim/accum_recursion.ll17
-rw-r--r--test/Transforms/TailCallElim/accum_recursion_constant_arg.ll22
-rw-r--r--test/Transforms/TailCallElim/ackermann.ll30
-rw-r--r--test/Transforms/TailCallElim/dg.exp3
-rw-r--r--test/Transforms/TailCallElim/dont-tce-tail-marked-call.ll12
-rw-r--r--test/Transforms/TailCallElim/intervening-inst.ll19
-rw-r--r--test/Transforms/TailCallElim/move_alloca_for_tail_call.ll12
-rw-r--r--test/Transforms/TailCallElim/return-undef.ll9
-rw-r--r--test/Transforms/TailCallElim/return_constant.ll19
-rw-r--r--test/Transforms/TailCallElim/trivial_codegen_tailcall.ll12
10 files changed, 155 insertions, 0 deletions
diff --git a/test/Transforms/TailCallElim/accum_recursion.ll b/test/Transforms/TailCallElim/accum_recursion.ll
new file mode 100644
index 0000000..d82d963
--- /dev/null
+++ b/test/Transforms/TailCallElim/accum_recursion.ll
@@ -0,0 +1,17 @@
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | not grep call
+
+int %factorial(int %x) {
+entry:
+ %tmp.1 = setgt int %x, 0
+ br bool %tmp.1, label %then, label %else
+
+then:
+ %tmp.6 = add int %x, -1
+ %tmp.4 = call int %factorial( int %tmp.6 )
+ %tmp.7 = mul int %tmp.4, %x
+ ret int %tmp.7
+
+else:
+ ret int 1
+}
+
diff --git a/test/Transforms/TailCallElim/accum_recursion_constant_arg.ll b/test/Transforms/TailCallElim/accum_recursion_constant_arg.ll
new file mode 100644
index 0000000..b103d89
--- /dev/null
+++ b/test/Transforms/TailCallElim/accum_recursion_constant_arg.ll
@@ -0,0 +1,22 @@
+; This is a more aggressive form of accumulator recursion insertion, which
+; requires noticing that X doesn't change as we perform the tailcall. Thanks
+; go out to the anonymous users of the demo script for "suggesting"
+; optimizations that should be done. :)
+
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | not grep call
+
+int %mul(int %x, int %y) {
+entry:
+ %tmp.1 = seteq int %y, 0
+ br bool %tmp.1, label %return, label %endif
+
+endif:
+ %tmp.8 = add int %y, -1
+ %tmp.5 = call int %mul( int %x, int %tmp.8 )
+ %tmp.9 = add int %tmp.5, %x
+ ret int %tmp.9
+
+return:
+ ret int %x
+}
+
diff --git a/test/Transforms/TailCallElim/ackermann.ll b/test/Transforms/TailCallElim/ackermann.ll
new file mode 100644
index 0000000..dd6e276
--- /dev/null
+++ b/test/Transforms/TailCallElim/ackermann.ll
@@ -0,0 +1,30 @@
+; This function contains two tail calls, which should be eliminated
+; RUN: llvm-upgrade < %s | llvm-as | \
+; RUN: opt -tailcallelim -stats -disable-output |& grep {2 tailcallelim}
+
+int %Ack(int %M.1, int %N.1) {
+entry:
+ %tmp.1 = seteq int %M.1, 0 ; <bool> [#uses=1]
+ br bool %tmp.1, label %then.0, label %endif.0
+
+then.0:
+ %tmp.4 = add int %N.1, 1 ; <int> [#uses=1]
+ ret int %tmp.4
+
+endif.0:
+ %tmp.6 = seteq int %N.1, 0 ; <bool> [#uses=1]
+ br bool %tmp.6, label %then.1, label %endif.1
+
+then.1:
+ %tmp.10 = add int %M.1, -1 ; <int> [#uses=1]
+ %tmp.8 = call int %Ack( int %tmp.10, int 1 ) ; <int> [#uses=1]
+ ret int %tmp.8
+
+endif.1:
+ %tmp.13 = add int %M.1, -1 ; <int> [#uses=1]
+ %tmp.17 = add int %N.1, -1 ; <int> [#uses=1]
+ %tmp.14 = call int %Ack( int %M.1, int %tmp.17 ) ; <int> [#uses=1]
+ %tmp.11 = call int %Ack( int %tmp.13, int %tmp.14 ) ; <int> [#uses=1]
+ ret int %tmp.11
+}
+
diff --git a/test/Transforms/TailCallElim/dg.exp b/test/Transforms/TailCallElim/dg.exp
new file mode 100644
index 0000000..879685c
--- /dev/null
+++ b/test/Transforms/TailCallElim/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Transforms/TailCallElim/dont-tce-tail-marked-call.ll b/test/Transforms/TailCallElim/dont-tce-tail-marked-call.ll
new file mode 100644
index 0000000..d3ba65e
--- /dev/null
+++ b/test/Transforms/TailCallElim/dont-tce-tail-marked-call.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | \
+; RUN: grep {call i32 @foo}
+
+declare void %bar(int*)
+int %foo(uint %N) {
+ %A = alloca int, uint %N ;; Should stay in entry block because of 'tail' marker
+ store int 17, int* %A
+ call void %bar(int* %A)
+
+ %X = tail call int %foo(uint %N) ;; Cannot -tailcallelim this without increasing stack usage!
+ ret int %X
+}
diff --git a/test/Transforms/TailCallElim/intervening-inst.ll b/test/Transforms/TailCallElim/intervening-inst.ll
new file mode 100644
index 0000000..a480e3b
--- /dev/null
+++ b/test/Transforms/TailCallElim/intervening-inst.ll
@@ -0,0 +1,19 @@
+; This function contains intervening instructions which should be moved out of the way
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | not grep call
+
+int %Test(int %X) {
+entry:
+ %tmp.1 = seteq int %X, 0
+ br bool %tmp.1, label %then.0, label %endif.0
+
+then.0:
+ %tmp.4 = add int %X, 1
+ ret int %tmp.4
+
+endif.0:
+ %tmp.10 = add int %X, -1
+ %tmp.8 = call int %Test(int %tmp.10)
+ %DUMMY = add int %X, 1 ;; This should not prevent elimination
+ ret int %tmp.8
+}
+
diff --git a/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll b/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll
new file mode 100644
index 0000000..1b1f0d0
--- /dev/null
+++ b/test/Transforms/TailCallElim/move_alloca_for_tail_call.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | \
+; RUN: %prcontext alloca 1 | grep {i32 @foo}
+
+declare void %bar(int*)
+int %foo() {
+ %A = alloca int ;; Should stay in entry block because of 'tail' marker
+ store int 17, int* %A
+ call void %bar(int* %A)
+
+ %X = tail call int %foo()
+ ret int %X
+}
diff --git a/test/Transforms/TailCallElim/return-undef.ll b/test/Transforms/TailCallElim/return-undef.ll
new file mode 100644
index 0000000..b7d2f81
--- /dev/null
+++ b/test/Transforms/TailCallElim/return-undef.ll
@@ -0,0 +1,9 @@
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis > %t
+; RUN: grep sub %t
+; RUN: not grep call %t
+
+int %test(int %X) {
+ %Y = sub int %X, 1
+ %Z = call int %test(int %Y)
+ ret int undef
+}
diff --git a/test/Transforms/TailCallElim/return_constant.ll b/test/Transforms/TailCallElim/return_constant.ll
new file mode 100644
index 0000000..5802024
--- /dev/null
+++ b/test/Transforms/TailCallElim/return_constant.ll
@@ -0,0 +1,19 @@
+; Though this case seems to be fairly unlikely to occur in the wild, someone
+; plunked it into the demo script, so maybe they care about it.
+;
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | not grep call
+
+int %aaa(int %c) {
+entry:
+ %tmp.1 = seteq int %c, 0 ; <bool> [#uses=1]
+ br bool %tmp.1, label %return, label %else
+
+else: ; preds = %entry
+ %tmp.5 = add int %c, -1 ; <int> [#uses=1]
+ %tmp.3 = call int %aaa( int %tmp.5 ) ; <int> [#uses=0]
+ ret int 0
+
+return: ; preds = %entry
+ ret int 0
+}
+
diff --git a/test/Transforms/TailCallElim/trivial_codegen_tailcall.ll b/test/Transforms/TailCallElim/trivial_codegen_tailcall.ll
new file mode 100644
index 0000000..98c2332
--- /dev/null
+++ b/test/Transforms/TailCallElim/trivial_codegen_tailcall.ll
@@ -0,0 +1,12 @@
+; RUN: llvm-upgrade < %s | llvm-as | opt -tailcallelim | llvm-dis | \
+; RUN: grep {tail call void @foo}
+
+declare void %foo()
+
+
+void %bar() {
+ call void %foo()
+ ret void
+}
+
+