This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: pass_stdarg problem when run after pass_lim


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]