This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the EGCS project.
regclass/jump problems
- To: gcc-bugs@gcc.gnu.org
- Subject: regclass/jump problems
- From: Philip Blundell <pb@nexus.co.uk>
- Date: Thu, 29 Jul 1999 11:53:12 +0100
The attached testcase (from Rod Stewart) makes gcc blow up in
jump_optimize_1 when compiling with -O2 on an arm-linux target. The crash
occurs at about line 800, in the test:
/* Finally, handle the case where two insns are used to
compute EXP but a temporary register is used. Here we must
ensure that the temporary register is not used anywhere else. */
if (! reload_completed
[...]
&& (temp1 = single_set (temp)) != 0
&& (temp5 = SET_DEST (temp1),
(GET_CODE (temp5) == REG
|| (GET_CODE (temp5) == SUBREG
&& (temp5 = SUBREG_REG (temp5),
GET_CODE (temp5) == REG))))
&& REGNO (temp5) >= FIRST_PSEUDO_REGISTER
&& REGNO_FIRST_UID (REGNO (temp5)) == INSN_UID (temp)
&& REGNO_LAST_UID (REGNO (temp5)) == INSN_UID (temp3)
&& ! side_effects_p (SET_SRC (temp1))
[...]
At this point, temp5 refers to a register which is off the end of the
reg_n_info varray. From what I can tell, this is because
duplicate_loop_exit_test has created new regs since regscan was last run. The
patch below just arranges to have it call reg_scan_update after potentially
generating new registers; is that the right thing to do?
Thanks
p.
Thu Jul 29 11:46:38 1999 Philip Blundell <pb@nexus.co.uk>
* jump.c (duplicate_loop_exit_test): New parameter after_regscan.
If true, call reg_scan_update when new registers might have been
created.
(jump_optimize_1): Pass after_regscan to above function.
Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.59.4.2
diff -u -r1.59.4.2 jump.c
--- jump.c 1999/05/31 13:30:06 1.59.4.2
+++ jump.c 1999/07/29 10:32:33
@@ -115,7 +115,7 @@
static rtx delete_unreferenced_labels PROTO((rtx));
static void delete_noop_moves PROTO((rtx));
static int calculate_can_reach_end PROTO((rtx, int, int));
-static int duplicate_loop_exit_test PROTO((rtx));
+static int duplicate_loop_exit_test PROTO((rtx, int));
static void find_cross_jump PROTO((rtx, rtx, int, rtx *, rtx *));
static void do_cross_jump PROTO((rtx, rtx, rtx));
static int jump_back_p PROTO((rtx, rtx));
@@ -338,7 +338,7 @@
&& simplejump_p (temp1))
{
temp = PREV_INSN (insn);
- if (duplicate_loop_exit_test (insn))
+ if (duplicate_loop_exit_test (insn, after_regscan))
{
changed = 1;
next = NEXT_INSN (temp);
@@ -2544,8 +2544,9 @@
values of regno_first_uid and regno_last_uid. */
static int
-duplicate_loop_exit_test (loop_start)
+duplicate_loop_exit_test (loop_start, after_regscan)
rtx loop_start;
+ int after_regscan;
{
rtx insn, set, reg, p, link;
rtx copy = 0;
@@ -2658,6 +2659,9 @@
reg_map[REGNO (reg)] = gen_reg_rtx (GET_MODE (reg));
}
}
+
+ if (after_regscan)
+ reg_scan_update (exitcode, lastexit, max_reg);
/* Now copy each insn. */
for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn))
seexec.i.gz