brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · f1ae141 Raw
83 lines · plain
1; RUN: opt < %s -passes=tailcallelim -verify-dom-info -S | grep call | count 42; PR43233 4; Several cases where tail call elimination should not move the load above the5; call, and thus can't eliminate the tail recursion.6 7 8@extern_weak_global = extern_weak global i32		; <ptr> [#uses=1]9 10 11; This load can't be safely moved above the call because the load is from an12; extern_weak global and may trap, but the call may unwind before that happens.13define fastcc i32 @no_tailrecelim_1(ptr %a_arg, i32 %a_len_arg, i32 %start_arg) readonly {14entry:15	%tmp2 = icmp sge i32 %start_arg, %a_len_arg		; <i1> [#uses=1]16	br i1 %tmp2, label %if, label %else17 18if:		; preds = %entry19	ret i32 3720 21else:		; preds = %entry22	%tmp7 = add i32 %start_arg, 1		; <i32> [#uses=1]23	%tmp8 = call fastcc i32 @no_tailrecelim_1(ptr %a_arg, i32 %a_len_arg, i32 %tmp7)		; <i32> [#uses=1]24	%tmp9 = load i32, ptr @extern_weak_global		; <i32> [#uses=1]25	%tmp10 = add i32 %tmp9, %tmp8		; <i32> [#uses=1]26	ret i32 %tmp1027}28 29 30; This load can't be safely moved above the call because function may write to the pointer.31define fastcc i32 @no_tailrecelim_2(ptr %a_arg, i32 %a_len_arg, i32 %start_arg) nounwind {32entry:33	%tmp2 = icmp sge i32 %start_arg, %a_len_arg		; <i1> [#uses=1]34	br i1 %tmp2, label %if, label %else35 36if:		; preds = %entry37	store i32 1, ptr %a_arg38        ret i32 039 40else:		; preds = %entry41	%tmp7 = add i32 %start_arg, 1		; <i32> [#uses=1]42	%tmp8 = call fastcc i32 @no_tailrecelim_2(ptr %a_arg, i32 %a_len_arg, i32 %tmp7)		; <i32> [#uses=1]43	%tmp9 = load i32, ptr %a_arg		; <i32> [#uses=1]44	%tmp10 = add i32 %tmp9, %tmp8		; <i32> [#uses=1]45	ret i32 %tmp1046}47 48; This load can't be safely moved above the call because that would change the49; order in which the load volatiles are performed.50define fastcc i32 @no_tailrecelim_3(ptr %a_arg, i32 %a_len_arg, i32 %start_arg) nounwind {51entry:52	%tmp2 = icmp sge i32 %start_arg, %a_len_arg		; <i1> [#uses=1]53	br i1 %tmp2, label %if, label %else54 55if:		; preds = %entry56        ret i32 057 58else:		; preds = %entry59	%tmp7 = add i32 %start_arg, 1		; <i32> [#uses=1]60	%tmp8 = call fastcc i32 @no_tailrecelim_3(ptr %a_arg, i32 %a_len_arg, i32 %tmp7)		; <i32> [#uses=1]61	%tmp9 = load volatile i32, ptr %a_arg		; <i32> [#uses=1]62	%tmp10 = add i32 %tmp9, %tmp8		; <i32> [#uses=1]63	ret i32 %tmp1064}65 66; This load can NOT be moved above the call because the a_arg is not67; sufficiently dereferenceable.68define fastcc i32 @no_tailrecelim_4(ptr dereferenceable(2) %a_arg, i32 %a_len_arg, i32 %start_arg) readonly {69entry:70	%tmp2 = icmp sge i32 %start_arg, %a_len_arg		; <i1> [#uses=1]71	br i1 %tmp2, label %if, label %else72 73if:		; preds = %entry74	ret i32 075 76else:		; preds = %entry77	%tmp7 = add i32 %start_arg, 1		; <i32> [#uses=1]78	%tmp8 = call fastcc i32 @no_tailrecelim_4(ptr %a_arg, i32 %a_len_arg, i32 %tmp7)		; <i32> [#uses=1]79	%tmp9 = load i32, ptr %a_arg		; <i32> [#uses=1]80	%tmp10 = add i32 %tmp9, %tmp8		; <i32> [#uses=1]81	ret i32 %tmp1082}83