diff options
Diffstat (limited to 'test/Transforms/TailCallElim')
-rw-r--r-- | test/Transforms/TailCallElim/accum_recursion.ll | 17 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/accum_recursion_constant_arg.ll | 22 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/ackermann.ll | 30 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/dg.exp | 3 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/dont-tce-tail-marked-call.ll | 12 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/intervening-inst.ll | 19 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/move_alloca_for_tail_call.ll | 12 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/return-undef.ll | 9 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/return_constant.ll | 19 | ||||
-rw-r--r-- | test/Transforms/TailCallElim/trivial_codegen_tailcall.ll | 12 |
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 +} + + |