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] |
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] |