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; }