Bug 42861 - [4.4/4.5 Regression] Spill slots not tracked during var-tracking
Summary: [4.4/4.5 Regression] Spill slots not tracked during var-tracking
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 4.5.0
: P2 normal
Target Milestone: 4.5.0
Assignee: Alexandre Oliva
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-01-25 11:45 UTC by Jakub Jelinek
Modified: 2010-01-27 17:00 UTC (History)
3 users (show)

See Also:
Host:
Target: i686-linux
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
parsetok.c.bz2 (32.41 KB, application/x-bzip2)
2010-01-25 11:45 UTC, Jakub Jelinek
Details
gcc45-ppc64-pr42861.patch (964 bytes, patch)
2010-01-26 12:39 UTC, Jakub Jelinek
Details | Diff
gcc45-constant_pool.patch (1.14 KB, patch)
2010-01-26 14:11 UTC, Jakub Jelinek
Details | Diff
gcc45-ppc-delegitimize.patch (976 bytes, patch)
2010-01-26 17:11 UTC, Jakub Jelinek
Details | Diff
gcc45-s390-delegitimize.patch (302 bytes, patch)
2010-01-26 17:12 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2010-01-25 11:45:00 UTC
PR37815 introduced a regression - no decls are tracked in spill slots, as they have MEM_EXPR set to get_spill_slot_decl (false) instead of the real decl.
On the testcase I'm going to attach, the tok argument is (and clearly has to be) live through the whole function except maybe last few instructions in epilogue, but as gcc decides to use regparm(2) calling convention, var-tracking thinks the parameter isn't live in most of the function.

I'm afraid we'll need to track what values live in the spill slots during var-tracking.  Easy hack to get at least something working would be just to handle spill slots that have at most one decl stored to it - then just one vector mapping byte offsets in the spill area to decls or REG_EXPRs would be sufficient.  We'd just walk the whole function, note what is stored into the spill slots and if there are any conflicts, just remember that we can't use it.

Or we could actually track what is currently stored in each spill slot even if the slot isn't for the same decl in all places.
Comment 1 Jakub Jelinek 2010-01-25 11:45:39 UTC
Created attachment 19703 [details]
parsetok.c.bz2
Comment 2 Alexandre Oliva 2010-01-25 19:46:10 UTC
Mine.  Got a patch.
Comment 3 Jakub Jelinek 2010-01-26 12:14:02 UTC
Note the http://gcc.gnu.org/ml/gcc-patches/2010-01/msg01282.html doesn't bootstrap on the redhat/gcc-4_4-branch on ppc, while it bootstraps on the trunk on x86_64-linux and i686-linux and on the branch on those arches too.
I will try to bootstrap trunk with that patch on ppc soon to see.
Anyway, the bootstrap problem can be simplified to:
typedef struct { char **b; int c[]; } T;
int a;
extern int d[], e;
extern char f[30];

static void
foo (unsigned *x, unsigned *y, int z)
{
  int i;
  for (i = 0; i < z; i++)
    x[i] = y[i / 2];
}

void
bar (T *y)
{
  unsigned x[4];
  foo (x, (unsigned *) d, e);
  __builtin_memcpy (y->b [y->c[0]], f, a);
}

at -O2 -g -m64 this doesn't assemble, as .debug_loc contains:
.LLST3:
        .8byte  .LVL1-.Ltext0    # Location list begin address (*.LLST3)
        .8byte  .LVL7-.Ltext0    # Location list end address (*.LLST3)
        .2byte  0x1      # Location expression size
        .byte   0x59     # DW_OP_reg9
        .8byte  .LVL7-.Ltext0    # Location list begin address (*.LLST3)
        .8byte  .LVL9-1-.Ltext0  # Location list end address (*.LLST3)
        .2byte  0xc      # Location expression size
        .byte   0x72     # DW_OP_breg2
        .byte   0x0      # sleb128 0
        .byte   0x3      # DW_OP_addr
        .8byte  .LC2@toc
        .byte   0x22     # DW_OP_plus
        .8byte  0x0      # Location list terminator begin (*.LLST3)
        .8byte  0x0      # Location list terminator end (*.LLST3)
and @toc isn't allowed in .8byte.

There is:
(insn 41 43 40 2 random.i:18 (set (reg/f:DI 9 9 [orig:148 d.0 ] [148])
        (mem/u/c:DI (plus:DI (reg:DI 2 2)
                (const:DI (unspec:DI [
                            (symbol_ref/u:DI ("*.LC2") [flags 0x2])
                        ] 49))) [7 S8 A8])) 350 {*movdi_internal64} (expr_list:REG_DEAD (reg:DI 2 2)
        (expr_list:REG_EQUIV (symbol_ref:DI ("d") [flags 0xc0]  <var_decl 0x7fdb7e28de60 d>)
            (nil))))
...
(debug_insn 47 46 48 2 random.i:18 (var_location:DI y (reg/f:DI 9 9 [orig:148 d.0 ] [148])) -1 (nil))

before var-tracking and apparently var-tracking doesn't consider that REG_EQUIV, which leads to:
(note 142 75 89 5 (var_location y (expr_list:REG_DEP_TRUE (mem/u/c:DI (plus:DI (reg:DI 2 2)
            (const:DI (unspec:DI [
                        (symbol_ref/u:DI ("*.LC2") [flags 0x2])
                    ] 49))) [7 S8 A8])
    (const_int 0 [0x0]))) NOTE_INSN_VAR_LOCATION)
Comment 4 Jakub Jelinek 2010-01-26 12:39:25 UTC
Created attachment 19710 [details]
gcc45-ppc64-pr42861.patch

Untested patch that cures this testcase.  Not sure if the constant pool special casing is needed.
Comment 5 Jakub Jelinek 2010-01-26 13:49:18 UTC
Removing that special casing of CONSTANT_POOL_ADDRESS_P leads to invalid debug info, which points to a bug in dwarf2out.c :(, he difference is:
 .8byte .LVL7-.Ltext0 # Location list begin address (*.LLST3)
 .8byte .LVL9-1-.Ltext0 # Location list end address (*.LLST3)
-.2byte 0xa # Location expression size
+.2byte 0x9 # Location expression size
 .byte 0x3 # DW_OP_addr
 .8byte d
-.byte 0x9f # DW_OP_stack_value
 .8byte 0x0 # Location list terminator begin (*.LLST3)
 .8byte 0x0 # Location list terminator end (*.LLST3)

The problem is a weird "optimization" in mem_loc_descriptor for SYMBOL_REF.
Replacing a SYMBOL_REF with a SYMBOL_REF get_pool_constant returned doesn't look right, because that is one indirection away.  Say if get_pool_constant on ".LC2" symbol returns "d" symbol, it means (mem (symbol_ref ".LC2")) is (symbol_ref "d"), not that (symbol_ref ".LC2") is the same as (symbol_ref "d").
Comment 6 Jakub Jelinek 2010-01-26 14:11:53 UTC
Created attachment 19712 [details]
gcc45-constant_pool.patch

Patch that cures this issue.
Comment 7 Jakub Jelinek 2010-01-26 17:11:38 UTC
Created attachment 19715 [details]
gcc45-ppc-delegitimize.patch

Updated ppc delegitimize patch (after the dwarf2out.c change there is no need
to duplicate parts of avoid_constant_pool_reference there).
I've bootstrapped/regtested this on the redhat/gcc-4_4-branch so far on powerpc64-linux --with-cpu=default32, all other arches pending.  I'm also bootstrapping now the trunk on powerpc64-linux --with-cpu=default32 with Alexandre's patch to see whether the same issue can be reproduced on the trunk. bootstrap.
Comment 8 Jakub Jelinek 2010-01-26 17:12:32 UTC
Created attachment 19716 [details]
gcc45-s390-delegitimize.patch

And s390 patch I'm bootstrapping/regtesting too.
Comment 9 Jakub Jelinek 2010-01-26 22:33:55 UTC
The trunk powerpc64-linux --with-cpu=default32 bootstrap died too, this time in
libsupc++/eh_alloc.cc compilation with -m64, again because of .8byte .LCXX@toc
in .debug_loc.
I'm going to bootstrap/regtest the patches on the trunk/powerpc64-linux now.
Comment 10 Jakub Jelinek 2010-01-27 16:37:20 UTC
Subject: Bug 42861

Author: jakub
Date: Wed Jan 27 16:36:57 2010
New Revision: 156292

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156292
Log:
	PR debug/42861
	* var-tracking.c (val_store): Add modified argument, obey it.
	Adjust callers.
	(count_uses): Move down logging of main.
	(compute_bb_dataflow): Use val_store for MO_VAL_USEs that
	don't need resolution.
	(emit_notes_in_bb): Likewise.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/var-tracking.c

Comment 11 Jakub Jelinek 2010-01-27 17:00:13 UTC
Fixed.