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 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* %a_arg ; <i32> [#uses=1] 62 %tmp10 = add i32 %tmp9, %tmp8 ; <i32> [#uses=1] 63 ret i32 %tmp10 64 } 65