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.
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);