[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / Transforms / TailCallElim / dont_reorder_load.ll
blobb10936310a2cbcda9ee87ce546a56b59cd958aa6
1 ; RUN: opt < %s -tailcallelim -verify-dom-info -S | grep call | count 4
2 ; PR4323
4 ; Several cases where tail call elimination should not move the load above the
5 ; call, and thus can't eliminate the tail recursion.
8 @extern_weak_global = extern_weak global i32            ; <i32*> [#uses=1]
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
18 if:             ; preds = %entry
19         ret i32 37
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
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
36 if:             ; preds = %entry
37         store i32 1, i32* %a_arg
38         ret i32 0
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
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
55 if:             ; preds = %entry
56         ret i32 0
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
66 ; This load can NOT be moved above the call because the a_arg is not
67 ; sufficiently dereferenceable.
68 define fastcc i32 @no_tailrecelim_4(i32* dereferenceable(2) %a_arg, i32 %a_len_arg, i32 %start_arg) readonly {
69 entry:
70         %tmp2 = icmp sge i32 %start_arg, %a_len_arg             ; <i1> [#uses=1]
71         br i1 %tmp2, label %if, label %else
73 if:             ; preds = %entry
74         ret i32 0
76 else:           ; preds = %entry
77         %tmp7 = add i32 %start_arg, 1           ; <i32> [#uses=1]
78         %tmp8 = call fastcc i32 @no_tailrecelim_4(i32* %a_arg, i32 %a_len_arg, i32 %tmp7)               ; <i32> [#uses=1]
79         %tmp9 = load i32, i32* %a_arg           ; <i32> [#uses=1]
80         %tmp10 = add i32 %tmp9, %tmp8           ; <i32> [#uses=1]
81         ret i32 %tmp10