Home | History | Annotate | Download | only in TailCallElim
      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* @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* %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 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
     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 = volatile load i32* %a_arg		; <i32> [#uses=1]
     62 	%tmp10 = add i32 %tmp9, %tmp8		; <i32> [#uses=1]
     63 	ret i32 %tmp10
     64 }
     65