------- Comment #1 from jakub at gcc dot gnu dot org 2010-07-20 10:40 ------- /* PR debug/45003 */ /* { dg-do run { target { x86_64-*-* && lp64 } } } */ /* { dg-options "-g" } */
int __attribute__((noinline)) foo (unsigned short *p) { int a = *p; asm volatile ("nop" : : "D" ((int) *p)); asm volatile ("nop" : : "D" ((int) *p));/* { dg-final { gdb-test 10 "a" "0x8078" } } */ return 0; } int __attribute__((noinline)) bar (short *p) { unsigned int a = *p; asm volatile ("nop" : : "D" ((unsigned int) *p)); asm volatile ("nop" : : "D" ((unsigned int) *p));/* { dg-final { gdb-test 19 "a" "-32648" } } */ return 0; } int main () { unsigned short us = 0x8078; foo (&us); short s = -32648; bar (&s); return 0; } There are two problems. One is that in DEBUG_INSN we use wrong extension (in foo SIGN_EXTEND instead of ZERO_EXTEND, in bar the other way around). The second issue is that debug temporaries prevent us to see that the value actually is still live in the %edi register, because one VALUE is used for (zero_extend:SI (debug_expr:HI D#1)) and another one for (zero_extend:SI (mem:HI (...)) where the debug temporary is the MEM. For the second issue, one possibility would be to find debug temporaries that are set just once and use their associated VALUE directly instead of the DEBUG_EXPR. The other possibility would be if we see that SIGN_EXTEND or ZERO_EXTEND of something is loaded into a register, note not just that the SIGN_EXTEND/ZERO_EXTEND VALUE lives in that register, but also that the operand's VALUE lives in the low part of that register. Alex, what do you think? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45003