pass_stdarg problem when run after pass_lim

Tom de Vries Tom_deVries@mentor.com
Mon Feb 2 14:33:00 GMT 2015


On 30-01-15 14:11, Michael Matz wrote:
> Hi,
>
> On Fri, 30 Jan 2015, Tom de Vries wrote:
>
>>> Maybe you want to pick up the work?
>>
>> In principle yes, depending on the amount of work (at this point I have no
>> idea what remains to be done and how long that would take me).
>>
>> Michael, are your patches posted somewhere?
>
> I don't think I ever sent them.  Pasted below, from somewhen October last
> year.  This essentially moves expanding va_arg to pass_stdarg.  But it
> does not yet make use of the possibilities this would bring, namely
> throwing away a whole lot of fragile code in pass_stdarg that tries to
> recover from expanding va_arg too early.
>
> To avoid having to touch each backend it retains expanding va_arg as a
> tree expression that needs to go through the gimplifier, which can create
> new basic blocks that need to be discovered after the fact, so there's
> some shuffling of code in tree-cfg as well.
>
> I also seem to remember that there was a problem with my using temporaries
> of the LHS for the new va_arg internal call, some types can't be copied
> and hence no temporaries can be created.  I can't seem to trigger this
> right now, but this needs to be dealt with somehow I think (but that
> requires the final lvalue be available when lowering the VA_ARG_EXPR).
>
> I think that's about it, hence, updating to current compiler, fixing the
> above problem (if it's still one), and then cleaning up pass_stdarg to
> make use of the availability of IFN_VA_ARG.
>

Hi Michael,

thanks for the patch.

FYI I've:
- added -ftree-stdarg-opt to be able to skip the va_list_gpr/fpr_size
   optimization (at least useful for developing this patch series)
- split off the internal-fn.def part (since it triggers rebuild for a lot of
   files)
- split off the part that is just refactoring (to get the patch containing
   the actual changes as small as possible)
- pushed the series to vries/expand-va-arg-at-pass-stdarg

Atm, at least these tests are failing:
...
FAIL: gcc.target/x86_64/abi/callabi/vaarg-4a.c execution test
FAIL: gcc.target/x86_64/abi/callabi/vaarg-5a.c execution test
...

I've minimized the vaarg-4a.c failure, and added it as testcase to the patch 
series as gcc.target/x86_64/abi/callabi/vaarg-4.c.

The problem is in this code:
...
   e = va_arg (argp, char *);
   e = va_arg (argp, char *);
...

which is translated into:
...
   <bb 2>:
   argp.1 = argp_3(D);

   <bb 5>:
   argp.12_11 = &argp.1;
   _12 = *argp.12_11;
   _13 = _12 + 8;
   *argp.12_11 = _13;

   <bb 6>:
   argp.3 = argp_3(D);

   <bb 7>:
   argp.13_15 = &argp.3;
   _16 = *argp.13_15;
   _17 = _16 + 8;
   *argp.13_15 = _17;
   _19 = MEM[(char * *)_16];
   e_8 = _19;
...

We copy the value of argp to a temp (bb2), get the addres of the temp, and use 
it to read the value of the temp, and increment the value of the temp (bb5).

However, subsequently we copy the _unmodified_ value of argp to a second temp 
(bb6), get the addres of that temp, and use it to read and increment (bb7).

Obviously, the first and second read return the same value, while they shouldn't.

Thanks,
- Tom



More information about the Gcc mailing list