On Sun, May 22, 2011 at 10:51:30PM +0200, Eric Botcazou wrote:
> var-tracking doesn't fully work with dynamic stack realignment on x86 when a 
> DRAP register is used for a function: the value of the incoming parameters is 
> very quickly wrong (as soon as the DRAP register is clobbered), in particular
> in backtraces.  The reason is that var-tracking doesn't track parameters 
> passed 
> on the stack and, therefore, doesn't invalidate their location when the DRAP 
> register is reused for something else.
> 
> Small Ada testcase attached, compile p1.adb with either -mforce-drap -O -g 
> or -mforce-drap -O -g -fno-var-tracking-assignments, break on Diff and 
> display 
> a backtrace: the arguments for Func are wrong.

Do you mean something like the attached one?  We don't have guality
testsuite for ada and I think ada testcases are quite unreadable for most
people.  Definitely to me.  Plus it is always better to have a single
file testcase over 5 files.

> The fix is (1) to arrange for var-tracking to track parameters passed on the 
> stack and (2) to invalidate their location where there is a DRAP register and 
> it is clobbered.

I guess this might be somewhat related to Alex'
http://gcc.gnu.org/ml/gcc-patches/2011-02/msg00981.html, but haven't tried
that patch.  But with tracking addresses as VALUEs var-tracking should
hopefully figure out that when %ecx as the DRAP register is saved into a
non-aliased stack location and then (maybe) clobbered during the call
that the addresses shouldn't use that hard reg afterwards, but need to
read it from the mem slot.  Anyway, IMHO the desired outcome is that the
parameters will have DW_OP_fbreg {0,4} as their location, so perhaps the
DRAP register needs to be remapped somehow during adjust_insn.

> Tested on x86_64-suse-linux and i586-suse-linux.  Is there an (unofficial) 
> maintainter for the var-tracking code?  Jakub?

I think Alex, who rewrote big chunks of var-tracking.c, is a better
unofficial reviewer.

        Jakub
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
/* { dg-options "-g -mforce-drap" } */

volatile int v;

__attribute__((noinline, noclone)) int
bar (int a, int b)
{
  int t = 0;
  asm volatile ("" : "+c" (t));
  return 0;
}

__attribute__((noinline, noclone)) int
foo (int a, int b)
{
  __attribute__((aligned (32))) int c = bar (a, b);
  v++;                          /* { dg-final { gdb-test 18 "a" "5" } } */
  return a + b + c;             /* { dg-final { gdb-test 18 "b" "6" } } */
}

int
main ()
{
  foo (5, 6);
  return 0;
}

Reply via email to