This fixes PR47025, __builtin_va_end is preventing dead store elimination and __builtin_va_start is an escape point for the valist.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-09-06 Richard Guenther <rguent...@suse.de> PR tree-optimization/47025 * tree-ssa-alias.c (ref_maybe_used_by_call_p_1): BUILT_IN_VA_END uses nothing. (call_may_clobber_ref_p_1): BUILT_IN_VA_END is a barrier like BUILT_IN_FREE. (stmt_kills_ref_p_1): BUILT_IN_VA_END kills what its argument definitely points to. * tree-ssa-structalias.c (find_func_aliases_for_builtin_call): BUILT_IN_VA_START doesn't let its va_list argument escape. * tree-ssa-dce.c (propagate_necessity): BUILT_IN_VA_END does not make any previous stores necessary. Index: gcc/tree-ssa-alias.c =================================================================== *** gcc/tree-ssa-alias.c.orig 2011-09-06 16:24:16.000000000 +0200 --- gcc/tree-ssa-alias.c 2011-09-06 16:28:48.000000000 +0200 *************** ref_maybe_used_by_call_p_1 (gimple call, *** 1254,1259 **** --- 1254,1260 ---- case BUILT_IN_SINCOSF: case BUILT_IN_SINCOSL: case BUILT_IN_ASSUME_ALIGNED: + case BUILT_IN_VA_END: return false; /* __sync_* builtins and some OpenMP builtins act as threading barriers. */ *************** call_may_clobber_ref_p_1 (gimple call, a *** 1518,1523 **** --- 1519,1525 ---- the call has to serve as a barrier for moving loads and stores across it. */ case BUILT_IN_FREE: + case BUILT_IN_VA_END: { tree ptr = gimple_call_arg (call, 0); return ptr_deref_may_alias_ref_p_1 (ptr, ref); *************** stmt_kills_ref_p_1 (gimple stmt, ao_ref *** 1763,1772 **** / BITS_PER_UNIT))) return true; } } default:; } - } return false; } --- 1765,1787 ---- / BITS_PER_UNIT))) return true; } + break; + } + + case BUILT_IN_VA_END: + { + tree ptr = gimple_call_arg (stmt, 0); + if (TREE_CODE (ptr) == ADDR_EXPR) + { + tree base = ao_ref_base (ref); + if (TREE_OPERAND (ptr, 0) == base) + return true; + } + break; } + default:; } } return false; } Index: gcc/tree-ssa-structalias.c =================================================================== *** gcc/tree-ssa-structalias.c.orig 2011-09-06 16:23:29.000000000 +0200 --- gcc/tree-ssa-structalias.c 2011-09-06 16:24:18.000000000 +0200 *************** find_func_aliases_for_builtin_call (gimp *** 4187,4213 **** mode as well. */ case BUILT_IN_VA_START: { if (in_ipa_mode) { - tree valist = gimple_call_arg (t, 0); - struct constraint_expr rhs, *lhsp; - unsigned i; - /* The va_list gets access to pointers in variadic - arguments. */ fi = lookup_vi_for_tree (cfun->decl); - gcc_assert (fi != NULL); - get_constraint_for (valist, &lhsc); - do_deref (&lhsc); rhs = get_function_part_constraint (fi, ~0); rhs.type = ADDRESSOF; - FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp) - process_constraint (new_constraint (*lhsp, rhs)); - VEC_free (ce_s, heap, lhsc); - /* va_list is clobbered. */ - make_constraint_to (get_call_clobber_vi (t)->id, valist); - return true; } ! break; } /* va_end doesn't have any effect that matters. */ case BUILT_IN_VA_END: --- 4187,4218 ---- mode as well. */ case BUILT_IN_VA_START: { + tree valist = gimple_call_arg (t, 0); + struct constraint_expr rhs, *lhsp; + unsigned i; + get_constraint_for (valist, &lhsc); + do_deref (&lhsc); + /* The va_list gets access to pointers in variadic + arguments. Which we know in the case of IPA analysis + and otherwise are just all nonlocal variables. */ if (in_ipa_mode) { fi = lookup_vi_for_tree (cfun->decl); rhs = get_function_part_constraint (fi, ~0); rhs.type = ADDRESSOF; } ! else ! { ! rhs.var = nonlocal_id; ! rhs.type = ADDRESSOF; ! rhs.offset = 0; ! } ! FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp) ! process_constraint (new_constraint (*lhsp, rhs)); ! VEC_free (ce_s, heap, lhsc); ! /* va_list is clobbered. */ ! make_constraint_to (get_call_clobber_vi (t)->id, valist); ! return true; } /* va_end doesn't have any effect that matters. */ case BUILT_IN_VA_END: Index: gcc/tree-ssa-dce.c =================================================================== *** gcc/tree-ssa-dce.c.orig 2011-09-06 16:23:29.000000000 +0200 --- gcc/tree-ssa-dce.c 2011-09-06 16:24:18.000000000 +0200 *************** propagate_necessity (struct edge_list *e *** 836,841 **** --- 836,842 ---- || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE + || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE