This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

illegally shared subreg


On x86 Linux, the attached testcase passes without optimization, and
fails with -O2/O3/Os.  The problem is a subreg illegally shared across
a block boundary, something like this (conditional branches omitted
for clarity):

regX =
...
 = subregY
subregY =
L2:
 = subregX # initial value
subregX =  # REG_TICK (X)++
L3:
 = subregY # remove all subregY entries from table,
           # set REG_IN_TABLE (X) = REG_TICK (X)
 = subregX # illegally shared with initial value

The problem arises when a store to subregX is followed by a reference
to subregY; the subregY reference removes subregY from the table,
ignoring the subregX entries, and a subsequent reference to subregX is
illegally shared.  The existing code tries to catch similar cases with
a "abs(REG_TICK-REG_IN_TABLE) == 1" versus "== 2" scheme, but this
scheme doesn't correctly distinguish and catch the current testcase.

Attached is a suitable patch for cse.c.  Geoff Keating suggested I
add a vector of subregs affected when REG_TICK is incremented; his
assistance is gratefully acknowledged.

Bootstrapped on x86 Linux and OS X (ppc), passed testsuite on x86
Linux without regressions.

    * gcc/gcc/cse.c (struct cse_reg_info) Add subreg_ticked.
    SUBREG_TICKED(N) New.
    (get_cse_reg_info) Initialize it.
    (mention_regs) Use it.
    (invalidate,invalidate_for_call,addr_affects_sp_p) Reinitialize it.

Testcase: suggest gcc.c-torture/execute/20021010-1.c or equivalent:

Attachment: abbr.c
Description: Text document


Patch: gcc/gcc/cse.c:

Attachment: patch.cse.4
Description: Binary data


O.K. to commit?

stuart hastings
Apple Computer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]