public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/36303]  New: location list incomplete for spilled registers
@ 2008-05-22 16:32 gcaprino at gmail dot com
  2008-05-22 17:15 ` [Bug middle-end/36303] " pinskia at gcc dot gnu dot org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: gcaprino at gmail dot com @ 2008-05-22 16:32 UTC (permalink / raw)
  To: gcc-bugs

Location list created for the following test case is incomplete for parameter
"p1":

cc1 -v -dD fs.c -dA -m64 -mcmodel=small -gdwarf-2 -O2 -fno-omit-frame-pointer
-quiet

typedef struct s2 {
   unsigned short f1;
   unsigned short length;
   char data[64];
} s2;

int func(s2 *p1, const char *p2)
{
   if (((_LogEffectiveLevel(57)) >= (3))) {
     _Log("abc",
        (__FUNCTION__+((__FUNCTION__[(sizeof("FSS") - 1)] == '_') ?
(sizeof("FSS") - 1) + 1 : (sizeof("FSS") - 1))),
        237 ,
        (p1)->f1,
        (p1)->length,
        *((unsigned int *)(&(p1)->data[0])),
        *((unsigned int *)(&(p1)->data[4])),
        *((unsigned int *)(&(p1)->data[8])),
        *((unsigned int *)(&(p1)->data[12])),
        *((unsigned int *)(&(p1)->data[16])),
        *((unsigned int *)(&(p1)->data[20])),
        *((unsigned int *)(&(p1)->data[24])),
        *((unsigned int *)(&(p1)->data[28])),
        *((unsigned long *)(&(p1)->data[32])),
        *((unsigned long *)(&(p1)->data[40])),
        *((unsigned long *)(&(p1)->data[48])),
        *((unsigned long *)(&(p1)->data[56])), p2);
   }
   return 0;
}

The generated assembly shows the following:
  .uleb128 0xb    # (DIE (0xb2) DW_TAG_formal_parameter)
  .ascii "p1\0"   # DW_AT_name
  .byte   0x1     # DW_AT_decl_file (fs.c)
  .byte   0x8     # DW_AT_decl_line
  .long   0xea    # DW_AT_type
  .long   .LLST1  # DW_AT_location

.LLST1:
  .quad   .LVL0-.Ltext0   # Location list begin address (*.LLST1)
  .quad   .LVL1-.Ltext0   # Location list end address (*.LLST1)
  .value  0x1             # Location expression size
  .byte   0x55            # DW_OP_reg5
  .quad   .LVL1-.Ltext0   # Location list begin address (*.LLST1)
  .quad   .LVL2-.Ltext0   # Location list end address (*.LLST1)
  .value  0x1             # Location expression size
  .byte   0x5b            # DW_OP_reg11
  .quad   .LVL4-.Ltext0   # Location list begin address (*.LLST1)
  .quad   .LVL5-.Ltext0   # Location list end address (*.LLST1)
  .value  0x1             # Location expression size
  .byte   0x5b            # DW_OP_reg11
  .quad   0x0             # Location list terminator begin (*.LLST1)
  .quad   0x0             # Location list terminator end (*.LLST1)

This does not cover instructions between .LVL2 and .LVL4.
Looking at the assembly, you see that R11 is being saved to the stack across
the call to _LogEffectiveLevel() and then reloaded *before* .LVL4:

        # fs.c:10
.LM4:
        movq    %r11, -48(%rbp)
.LVL2:
        call    _LogEffectiveLevel
.LVL3:
        cmpl    $2, %eax
        movq    -48(%rbp), %r11
        jle     .L2
        # basic block 3
        # fs.c:11
.LM5:
        movl    28(%r11), %ecx
.LVL4:
        movq    60(%r11), %rax
        movq    52(%r11), %rdx

So when gdb is stopped at line fs.c:11 it reports that p1's <value is optimized
out>.

I debugged var-tracking.c, and it does not look like it is tracking duplicate
locations, such as when a register is saved and restored from the stack.
It's also possible that one of the previous passes does not give enough
information to var-tracking.c about the variable being saved/restored.
I can see the following in the var tracking output:

(insn:TI 7 102 107 2 fs.c:10 (set (reg:SI 5 di)
        (const_int 57 [0x39])) 47 {*movsi_1} (nil))

(note 107 7 83 2 ( p1 (expr_list:REG_DEP_TRUE (reg/v/f:DI 40 r11 [orig:75 p1 ]
[75])
    (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION)
....
(insn 78 90 108 2 fs.c:10 (set (mem/c:DI (plus:DI (reg/f:DI 6 bp)
                (const_int -48 [0xffffffffffffffd0])) [10 S8 A8])
        (reg:DI 40 r11)) 89 {*movdi_1_rex64} (expr_list:REG_DEAD (reg:DI 40
r11)
        (nil)))

(note 108 78 9 2 ( p1 (nil)) NOTE_INSN_VAR_LOCATION)
....
(insn 79 11 12 2 fs.c:10 (set (reg:DI 40 r11)
        (mem/c:DI (plus:DI (reg/f:DI 6 bp)
                (const_int -48 [0xffffffffffffffd0])) [10 S8 A8])) 89
{*movdi_1_rex64} (nil))

It seems that when r11 is saved in insn 78 and reloaded in insn 79 it is not
marked as containing "p1".
Unfortunately I don't have enough knowledge to continue debugging gcc to be
sure it's var-tracking.c or someone else's fault.

This happens with gcc 4.2.3 and gcc 4.3.0.
It does not happen with -O1, or if I remove even a single parameter from the
call to _LogEffectiveLevel().
However we observe a lot of <value optimized out> messages in other parts of
our code, and most of the time I tracked it to incomplete info in the location
list.

I hope this is enough information. Let me know if you need more.
Thanks,
Giampiero Caprino


-- 
           Summary: location list incomplete for spilled registers
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: gcaprino at gmail dot com
  GCC host triplet: host-i686-pc-linux-gnu
GCC target triplet: x86_64-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36303


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/36303] location list incomplete for spilled registers
  2008-05-22 16:32 [Bug c/36303] New: location list incomplete for spilled registers gcaprino at gmail dot com
@ 2008-05-22 17:15 ` pinskia at gcc dot gnu dot org
  2008-05-22 18:16 ` gcaprino at gmail dot com
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2008-05-22 17:15 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from pinskia at gcc dot gnu dot org  2008-05-22 17:15 -------
This code also does violates C aliasing rules.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pinskia at gcc dot gnu dot
                   |                            |org
          Component|c                           |middle-end


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36303


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/36303] location list incomplete for spilled registers
  2008-05-22 16:32 [Bug c/36303] New: location list incomplete for spilled registers gcaprino at gmail dot com
  2008-05-22 17:15 ` [Bug middle-end/36303] " pinskia at gcc dot gnu dot org
@ 2008-05-22 18:16 ` gcaprino at gmail dot com
  2008-05-22 22:39 ` pinskia at gcc dot gnu dot org
  2008-05-22 23:04 ` gcaprino at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: gcaprino at gmail dot com @ 2008-05-22 18:16 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from gcaprino at gmail dot com  2008-05-22 18:15 -------
(In reply to comment #1)
> This code also does violates C aliasing rules.

I'm sorry, but I don't understand what you mean.
Do you think there is a problem with the code portion
such that it's not legal, safe C code?
(btw this is part of a larger function which I reduced
to facilitate debugging of this issue).

It seems to me that nothing can change the value of "p1", since
no addresses are taken to write into the stack.
"p2" could point inside the structure pointed by "p1", but it
should not be possible for "p2" to point at "p1", right?
Besides, "p2" is only used after the register is saved/reloaded
from the stack.

Could you elaborate?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36303


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/36303] location list incomplete for spilled registers
  2008-05-22 16:32 [Bug c/36303] New: location list incomplete for spilled registers gcaprino at gmail dot com
  2008-05-22 17:15 ` [Bug middle-end/36303] " pinskia at gcc dot gnu dot org
  2008-05-22 18:16 ` gcaprino at gmail dot com
@ 2008-05-22 22:39 ` pinskia at gcc dot gnu dot org
  2008-05-22 23:04 ` gcaprino at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2008-05-22 22:39 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from pinskia at gcc dot gnu dot org  2008-05-22 22:38 -------
>I'm sorry, but I don't understand what you mean.

        *((unsigned int *)(&(p1)->data[0])),

You are accessing a char array as an unsigned int which violates C/C++ aliasing
rules and causes undefined code at runtime.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36303


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Bug middle-end/36303] location list incomplete for spilled registers
  2008-05-22 16:32 [Bug c/36303] New: location list incomplete for spilled registers gcaprino at gmail dot com
                   ` (2 preceding siblings ...)
  2008-05-22 22:39 ` pinskia at gcc dot gnu dot org
@ 2008-05-22 23:04 ` gcaprino at gmail dot com
  3 siblings, 0 replies; 5+ messages in thread
From: gcaprino at gmail dot com @ 2008-05-22 23:04 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from gcaprino at gmail dot com  2008-05-22 23:03 -------
(In reply to comment #3)
> >I'm sorry, but I don't understand what you mean.
>         *((unsigned int *)(&(p1)->data[0])),
> You are accessing a char array as an unsigned int which violates C/C++ aliasing
> rules and causes undefined code at runtime.

Ah, I see what you mean. Yes, you are right.
That came out of some macro expansion.
Unfortunately I can still see the problem in the
location list when I reference the array elements
without the casts:
     _Log("abc",
        (__FUNCTION__+((__FUNCTION__[(sizeof("FSS") - 1)] == '_') ?
(sizeof("FSS") - 1) + 1 : (sizeof("FSS") - 1))),
        237 , (p1)->f1, (p1)->length,
        p1->data[0], p1->data[4],  p1->data[8],
        p1->data[12], p1->data[16], p1->data[20],
        p1->data[24], p1->data[28], p1->data[32],
        p1->data[40], p1->data[48], p1->data[56], p2);


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36303


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-05-22 23:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-22 16:32 [Bug c/36303] New: location list incomplete for spilled registers gcaprino at gmail dot com
2008-05-22 17:15 ` [Bug middle-end/36303] " pinskia at gcc dot gnu dot org
2008-05-22 18:16 ` gcaprino at gmail dot com
2008-05-22 22:39 ` pinskia at gcc dot gnu dot org
2008-05-22 23:04 ` gcaprino at gmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).