Message ID | 1409311619.31600.11.camel@surprise |
---|---|
State | New |
Headers | show |
On Fri, 2014-08-29 at 07:26 -0400, David Malcolm wrote: > On Fri, 2014-08-29 at 06:13 +0200, Hans-Peter Nilsson wrote: > > Sorry for the context-less mail but I didn't find a proper > > obvious gcc-patches-message to reply to. (Also, I can't log > > into bugzilla because to enter a PR as there appears to have > > been some SSL changes such that my old firefox and gcc.gnu.org > > can no longer agree on a cipher or something.) But, since > > r214690 and at up to and including r214714 (HEAD as of this > > writing), a build for cris-elf fails on trunk as follows: > > > > /tmp/hpautotest-gcc1/cris-elf/gccobj/./gcc/xgcc -B/tmp/hpautotest-gcc1/cris-elf/gccobj/./gcc/ -nostdinc -B/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/newlib/ -isystem /tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/newlib/targ-include -isystem /tmp/hpautotest-gcc1/gcc/newlib/libc/include -B/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/libgloss/cris -L/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/libgloss/libnosys -L/tmp/hpautotest-gcc1/gcc/libgloss/cris -B/tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/bin/ -B/tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/lib/ -isystem /tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/include -isystem /tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/sys-include -g -O2 -march=v8 -mbest-lib-options -O2 -g -O2 -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -I. -I. -I../../../! ./! > gcc > > -I/tmp/ > > hpautotest-gcc1/gcc/libgcc -I/tmp/hpautotest-gcc1/gcc/libgcc/. -I/tmp/hpautotest-gcc1/gcc/libgcc/../gcc -I/tmp/hpautotest-gcc1/gcc/libgcc/../include -DHAVE_CC_TLS -DUSE_EMUTLS -o _lshrdi3.o -MT _lshrdi3.o -MD -MP -MF _lshrdi3.dep -DL_lshrdi3 -c /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c -fvisibility=hidden -DHIDE_EXPORTS > > /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c: In function '__lshrdi3': > > /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c:426:1: internal compiler error: in safe_as_a, at is-a.h:205 > > } > > ^ > > 0x9119c2 safe_as_a<rtx_insn*, rtx_def> > > /tmp/hpautotest-gcc1/gcc/gcc/is-a.h:205 > > 0x9119c2 JUMP_LABEL_AS_INSN > > /tmp/hpautotest-gcc1/gcc/gcc/rtl.h:1663 > > 0x9119c2 find_dead_or_set_registers > > /tmp/hpautotest-gcc1/gcc/gcc/resource.c:500 > > 0x912408 mark_target_live_regs(rtx_insn*, rtx_insn*, resources*) > > /tmp/hpautotest-gcc1/gcc/gcc/resource.c:1115 > > 0x90cb4b fill_slots_from_thread > > /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:2404 > > 0x90ff45 fill_eager_delay_slots > > /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:2933 > > 0x90ff45 dbr_schedule > > /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3742 > > 0x9108ef rest_of_handle_delay_slots > > /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3885 > > 0x9108ef execute > > /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3916 > > Please submit a full bug report, > > with preprocessed source if appropriate. > > Please include the complete backtrace with any bug report. > > See <http://gcc.gnu.org/bugs.html> for instructions. > > make[4]: *** [_lshrdi3.o] Error 1 > > > > Use "./cc1 -fpreprocessed this.i -O2" to repeat. > > > > struct DWstruct {int low, high;}; > > > > typedef union > > { > > struct DWstruct s; > > long long ll; > > } DWunion; > > > > long long > > __lshrdi3 (long long u, int b) > > { > > if (b == 0) > > return u; > > > > const DWunion uu = {.ll = u}; > > const int bm = (4 * (8)) - b; > > DWunion w; > > > > if (bm <= 0) > > { > > w.s.high = 0; > > w.s.low = (unsigned int) uu.s.high >> -bm; > > } > > else > > { > > const unsigned int carries = (unsigned int) uu.s.high << bm; > > > > w.s.high = (unsigned int) uu.s.high >> b; > > w.s.low = ((unsigned int) uu.s.low >> b) | carries; > > } > > > > return w.ll; > > } > > Sorry about this. > > Looks like I introduced this bug in r214693 (aka patch #225). > > The issue is within resource.c: > 499 { > 500 next = JUMP_LABEL_AS_INSN (this_jump_insn); > 501 if (ANY_RETURN_P (next)) > 502 next = NULL; > > where "next" is an rtx_insn *, but the JUMP_LABEL of this_jump_insn is a > RETURN, rather than an insn (several such issues in that commit). > > Patch attached, which fixes the above testcase; bootstrap in progress: > > gcc/ > * resource.h (mark_target_live_regs): Undo erroneous conversion > of second param of r214693, converting it back from rtx_insn * to > rtx, since it could be a RETURN. > > * resource.c (find_dead_or_set_registers): Similarly, convert > param "jump_target" back from an rtx_insn ** to an rtx *, as we > could be writing back a RETURN. Rename local rtx_insn * "next" to > "next_insn", and introduce "lab_or_return" as a local rtx, > handling the case where JUMP_LABEL (this_jump_insn) is a RETURN. > (mark_target_live_regs): Undo erroneous conversion > of second param of r214693, converting it back from rtx_insn * to > rtx, since it could be a RETURN. Rename it from "target" to > "target_maybe_return", reintroducing the name "target" as a local > rtx_insn * with a checked cast, after we've handled the case of > ANY_RETURN_P. ...and this has now been filed as part of PR62304, which found both this and another problem in reorg.c, both with JUMP_LABEL_AS_INSN as the root cause. It may be worth eliminating that; it seems error-prone.
Index: gcc/resource.c =================================================================== --- gcc/resource.c (revision 214719) +++ gcc/resource.c (working copy) @@ -81,7 +81,7 @@ static int find_basic_block (rtx, int); static rtx_insn *next_insn_no_annul (rtx_insn *); static rtx_insn *find_dead_or_set_registers (rtx_insn *, struct resources*, - rtx_insn **, int, struct resources, + rtx *, int, struct resources, struct resources); /* Utility function called from mark_target_live_regs via note_stores. @@ -422,19 +422,20 @@ static rtx_insn * find_dead_or_set_registers (rtx_insn *target, struct resources *res, - rtx_insn **jump_target, int jump_count, + rtx *jump_target, int jump_count, struct resources set, struct resources needed) { HARD_REG_SET scratch; - rtx_insn *insn, *next; + rtx_insn *insn; + rtx_insn *next_insn; rtx_insn *jump_insn = 0; int i; - for (insn = target; insn; insn = next) + for (insn = target; insn; insn = next_insn) { rtx_insn *this_jump_insn = insn; - next = NEXT_INSN (insn); + next_insn = NEXT_INSN (insn); /* If this instruction can throw an exception, then we don't know where we might end up next. That means that we have to @@ -497,14 +498,16 @@ if (any_uncondjump_p (this_jump_insn) || ANY_RETURN_P (PATTERN (this_jump_insn))) { - next = JUMP_LABEL_AS_INSN (this_jump_insn); - if (ANY_RETURN_P (next)) - next = NULL; + rtx lab_or_return = JUMP_LABEL (this_jump_insn); + if (ANY_RETURN_P (lab_or_return)) + next_insn = NULL; + else + next_insn = as_a <rtx_insn *> (lab_or_return); if (jump_insn == 0) { jump_insn = insn; if (jump_target) - *jump_target = JUMP_LABEL_AS_INSN (this_jump_insn); + *jump_target = JUMP_LABEL (this_jump_insn); } } else if (any_condjump_p (this_jump_insn)) @@ -572,7 +575,7 @@ find_dead_or_set_registers (JUMP_LABEL_AS_INSN (this_jump_insn), &target_res, 0, jump_count, target_set, needed); - find_dead_or_set_registers (next, + find_dead_or_set_registers (next_insn, &fallthrough_res, 0, jump_count, set, needed); IOR_HARD_REG_SET (fallthrough_res.regs, target_res.regs); @@ -880,7 +883,7 @@ init_resource_info () was invoked before we are called. */ void -mark_target_live_regs (rtx_insn *insns, rtx_insn *target, struct resources *res) +mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resources *res) { int b = -1; unsigned int i; @@ -887,19 +890,23 @@ struct target_info *tinfo = NULL; rtx_insn *insn; rtx jump_insn = 0; - rtx_insn *jump_target; + rtx jump_target; HARD_REG_SET scratch; struct resources set, needed; /* Handle end of function. */ - if (target == 0 || ANY_RETURN_P (target)) + if (target_maybe_return == 0 || ANY_RETURN_P (target_maybe_return)) { *res = end_of_function_needs; return; } + /* We've handled the case of RETURN/SIMPLE_RETURN; we should now have an + instruction. */ + rtx_insn *target = as_a <rtx_insn *> (target_maybe_return); + /* Handle return insn. */ - else if (return_insn_p (target)) + if (return_insn_p (target)) { *res = end_of_function_needs; mark_referenced_resources (target, res, false); Index: gcc/resource.h =================================================================== --- gcc/resource.h (revision 214719) +++ gcc/resource.h (working copy) @@ -44,7 +44,7 @@ MARK_SRC_DEST_CALL = 1 }; -extern void mark_target_live_regs (rtx_insn *, rtx_insn *, struct resources *); +extern void mark_target_live_regs (rtx_insn *, rtx, struct resources *); extern void mark_set_resources (rtx, struct resources *, int, enum mark_resource_type); extern void mark_referenced_resources (rtx, struct resources *, bool);