Postpone expanding va_arg until pass_stdarg

Tom de Vries Tom_deVries@mentor.com
Mon Feb 16 17:22:00 GMT 2015


On 12-02-15 23:51, Tom de Vries wrote:
> On 12-02-15 14:57, Michael Matz wrote:

>>>>> I'm not really sure yet why std_gimplify_va_arg_expr has a part
>>>>> commented out. Michael, can you comment?
>>>>
>>>> I think I did that because of SSA form.  The old sequence calculated
>>>>
>>>>     vatmp = valist;
>>>>     vatmp = vatmp + boundary-1
>>>>     vatmp = vatmp & -boundary
>>>>
>>>> (where the local variable in that function 'valist_tmp' is the tree
>>>> VAR_DECL 'vatmp') and then continue to use valist_tmp.  When in SSA form
>>>> the gimplifier will rewrite this into:
>>>>
>>>>     vatmp_1 = valist;
>>>>     vatmp_2 = vatmp_1 + boundary-1
>>>>     vatmp_3 = vatmp_2 & -boundary
>>>>
>>>> but the local valist_tmp variable will continue to be the VAR_DECL, not
>>>> the vatmp_3 ssa name.  Basically whenever one gimplifies a MODIFY_EXPR
>>>> while in SSA form it's suspicious.  So the new code simply build the
>>>> expression:
>>>>
>>>>     ((valist + bound-1) & -bound)
>>>>
>>>> gimplifies that into an rvalue (most probably an SSA name) and uses that
>>>> to go on generating code by making valist_tmp be that returned rvalue.
>>>>
>>>> I think you'll find that removing that code will make the SSA verifier
>>>> scream or generate invalid code with -m32 when that hook is used.
>>>>
>>>
>>> Thanks for the detailed explanation. I'm not sure I understand the
>>> problem well enough, so I'll try to trigger it and investigate.
>>
>> Actually the above fails to mention what the real problem is :-)  The
>> problem is that the local variable valist_tmp will be used to generate
>> further code after the above expression is generated.  Without my patch it
>> will continue to point to the VAR_DECL, not to the SSA name that actually
>> holds the computed value in the generated code.
>>
>
> I have not been able to reproduce this problem (with a bootstrap build on x86_64
> for all languages, and {unix/,unix/-m32} testing), so I've dropped this bit for
> now.

Hi Michael,

Just to double-check, I added an assert to detect triggering of the 'dynamic 
alignment' bit in std_gimplify_va_arg_expr.

The assert hit during a bootstrap in libquadmath/printf/quadmath-printf.c, in 
flt128_va with -m32.

The fn_va_arg statement we start with is:
...
# .MEM_3 = VDEF <.MEM_1(D)>
d.19_4 = VA_ARG (ap_2(D), 0B); [return slot optimization]
...

The code generated by the gimplification of fn_va_arg is:
...
(gdb) call debug_bb_n (3)
<bb 3>:
D.5165 = *ap_2(D);
D.5165 = D.5165 + 15;
D.5165 = D.5165 & 4294967280B;
D.5166 = D.5165 + 16;
*ap_2(D) = D.5166;
d.19_4 = MEM[(__float128 *)D.5165];
...

and after the 'update_ssa (TODO_update_ssa)', it looks like:
...
(gdb) call debug_bb_n (3)
<bb 3>:
_8 = *ap_2(D);
_9 = _8 + 15;
_10 = _9 & 4294967280B;
_11 = _10 + 16;
*ap_2(D) = _11;
d.19_4 = MEM[(__float128 *)_10];
...

All this looks ok to me, so I see no need to re-instate this dropped bit.

Thanks,
- Tom



More information about the Gcc mailing list