Add a test for r253323
[oota-llvm.git] / test / Transforms / TailCallElim / dont_reorder_load.ll
1 ; RUN: opt < %s -tailcallelim -S | grep call | count 3
2 ; PR4323
3
4 ; Several cases where tail call elimination should not move the load above the
5 ; call, and thus can't eliminate the tail recursion.
6
7
8 @extern_weak_global = extern_weak global i32            ; <i32*> [#uses=1]
9
10
11 ; This load can't be safely moved above the call because the load is from an
12 ; extern_weak global and may trap, but the call may unwind before that happens.
13 define fastcc i32 @no_tailrecelim_1(i32* %a_arg, i32 %a_len_arg, i32 %start_arg) readonly {
14 entry:
15         %tmp2 = icmp sge i32 %start_arg, %a_len_arg             ; <i1> [#uses=1]
16         br i1 %tmp2, label %if, label %else
17
18 if:             ; preds = %entry
19         ret i32 37
20
21 else:           ; preds = %entry
22         %tmp7 = add i32 %start_arg, 1           ; <i32> [#uses=1]
23         %tmp8 = call fastcc i32 @no_tailrecelim_1(i32* %a_arg, i32 %a_len_arg, i32 %tmp7)               ; <i32> [#uses=1]
24         %tmp9 = load i32, i32* @extern_weak_global              ; <i32> [#uses=1]
25         %tmp10 = add i32 %tmp9, %tmp8           ; <i32> [#uses=1]
26         ret i32 %tmp10
27 }
28
29
30 ; This load can't be safely moved above the call because function may write to the pointer.
31 define fastcc i32 @no_tailrecelim_2(i32* %a_arg, i32 %a_len_arg, i32 %start_arg) nounwind {
32 entry:
33         %tmp2 = icmp sge i32 %start_arg, %a_len_arg             ; <i1> [#uses=1]
34         br i1 %tmp2, label %if, label %else
35
36 if:             ; preds = %entry
37         store i32 1, i32* %a_arg
38         ret i32 0
39
40 else:           ; preds = %entry
41         %tmp7 = add i32 %start_arg, 1           ; <i32> [#uses=1]
42         %tmp8 = call fastcc i32 @no_tailrecelim_2(i32* %a_arg, i32 %a_len_arg, i32 %tmp7)               ; <i32> [#uses=1]
43         %tmp9 = load i32, i32* %a_arg           ; <i32> [#uses=1]
44         %tmp10 = add i32 %tmp9, %tmp8           ; <i32> [#uses=1]
45         ret i32 %tmp10
46 }
47
48 ; This load can't be safely moved above the call because that would change the
49 ; order in which the load volatiles are performed.
50 define fastcc i32 @no_tailrecelim_3(i32* %a_arg, i32 %a_len_arg, i32 %start_arg) nounwind {
51 entry:
52         %tmp2 = icmp sge i32 %start_arg, %a_len_arg             ; <i1> [#uses=1]
53         br i1 %tmp2, label %if, label %else
54
55 if:             ; preds = %entry
56         ret i32 0
57
58 else:           ; preds = %entry
59         %tmp7 = add i32 %start_arg, 1           ; <i32> [#uses=1]
60         %tmp8 = call fastcc i32 @no_tailrecelim_3(i32* %a_arg, i32 %a_len_arg, i32 %tmp7)               ; <i32> [#uses=1]
61         %tmp9 = load volatile i32, i32* %a_arg          ; <i32> [#uses=1]
62         %tmp10 = add i32 %tmp9, %tmp8           ; <i32> [#uses=1]
63         ret i32 %tmp10
64 }