https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66010
--- Comment #6 from vries at gcc dot gnu.org --- Created attachment 35480 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35480&action=edit Tentative patch (In reply to Richard Biener from comment #5) > apD.1859 = &apD.1844; > > # .MEM_7 = VDEF <.MEM_3> > # USE = nonlocal null { D.1844 D.1859 } (escaped) > # CLB = nonlocal null { D.1844 D.1859 } (escaped) > _6 = VA_ARG (&apD.1859, > > > this also looks like double-indirection (and thus wrong-code?) > It looks wrong to me as well, but I haven't seen any wrong generated code as a consequence. There's some fixup code in gimplify_va_arg_internal, that adds an occasional addr expression, I suspect this bit is handling (or balancing out) this extra indirection: ... /* For this case, the backends will be expecting a pointer to TREE_TYPE (abi), but it's possible we've actually been given an array (an actual TARGET_FN_ABI_VA_LIST). So fix it. */ if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) { tree p1 = build_pointer_type (TREE_TYPE (have_va_type)); valist = fold_convert_loc (loc, p1, build_fold_addr_expr_loc (loc, valist)); } gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue); ... > > Note that I'd defer all possible optimization issues to _after_ re-writing > the stdarg pass to take advantage of va_arg not being lowered. Right. But the double indirection is suspicious, so I tried to get rid of it. Attached tentative patch achieves this. It manages to generate: ... f2_1 (struct * ap) { intD.6 D.1852; # USE = anything # CLB = anything D.1852 = VA_ARG (apD.1837, 0B, 0); return D.1852; } ... And after early inlinling we get in f2: ... # .MEM_2 = VDEF <.MEM_1(D)> # USE = anything # CLB = anything __builtin_va_startD.1030 (&apD.1844, 0); # .MEM_3 = VDEF <.MEM_2> # USE = anything # CLB = anything _8 = VA_ARG (&apD.1844, 0B, 0); ... That fixes this PR: ... f2: va_list escapes 0, needs to save 8 GPR units and 0 FPR units. ...