fix a globalopt crash on two Adobe-C++ testcases that the recent
[llvm.git] / test / Transforms / TailCallElim / dont_reorder_load.ll
blobcc273c3ca53db2bf270bff5ce94704d49856518a
1 ; RUN: opt < %s -tailcallelim -S | grep call | count 3
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         unwind
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* @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* %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 volatile loads 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 = volatile load i32* %a_arg               ; <i32> [#uses=1]
62         %tmp10 = add i32 %tmp9, %tmp8           ; <i32> [#uses=1]
63         ret i32 %tmp10