This is the mail archive of the 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]

fix reload failures on alpha and ppc64

Last night's runs failed with

/home/rth/work/gcc/src-cron/gcc/fortran/intrinsic.c:2044: error: insn does not
+satisfy its constraints:
(insn 7653 3246 8065 0 /home/rth/work/gcc/src-cron/gcc/fortran/intrinsic.c:1410
+(set (reg/f:SI 1429)
        (high:SI (symbol_ref/f:SI ("*.LC24") [flags 0x2] <string_cst
+0xf7abbd40>))) 373 {elf_high} (nil)
    (expr_list:REG_EQUIV (high:SI (symbol_ref/f:SI ("*.LC24") [flags 0x2]
+<string_cst 0xf7abbd40>))


/home/rth/work/gcc/src-cron/libjava/gnu/gcj/io/ error: insn does not
+satisfy its constraints:
(insn 4254 3812 4257 2 /home/rth/work/gcc/src-cron/libjava/gnu/gcj/io/ (reg:SI 860)
        (const_int 1518469120 [0x5a820000])) 239 {*movsi} (nil)
    (expr_list:REG_EQUIV (const_int 1518469120 [0x5a820000])

Note in both cases we have a pseudo register present after reload.

The problem appears to be that (1) we lose track of the initialization
insn of these REG_EQUIVs, and (2) there's a mismatch between the place
that decides when we're going to skip reloading an insn, and the place
that decides when we're going to delete an insn.  The former, at

          /* Skip insns that only set an equivalence.  */
          if (set && REG_P (SET_DEST (set))
              && reg_renumber[REGNO (SET_DEST (set))] < 0
              && reg_equiv_constant[REGNO (SET_DEST (set))])

in calculate_needs_all_insns, and the later at 

  /* If a pseudo has no hard reg, delete the insns that made the equivalence.
     If that insn didn't set the register (i.e., it copied the register to
     memory), just delete that insn instead of the equivalencing insn plus
     anything now dead.  If we call delete_dead_insn on that insn, we may
     delete the insn that actually sets the register if the register dies
     there and that is incorrect.  */

  for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
      if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0)
          rtx list;
          for (list = reg_equiv_init[i]; list; list = XEXP (list, 1))

in reload.

This only tries to address point 1 -- losing track of the initialization
insn.  Which should be enough to suppress the observable failure; I'll 
let Bernd figure out what he wants to do about the mismatch when he gets
back next week.

The problem appears to be a cut-and-paste error from the asm case just
above, which does delete the equivalence insn.  In this case we're moving
it, so we should move the initialization insn too.

This has been spot-checked against the test case on alpha.  I'm
running full tests on alpha and ppc64 overnight.


	* local-alloc.c (update_equiv_regs): Update reg_equiv_init
	properly when moving an initialization insn.

Index: local-alloc.c
RCS file: /cvsroot/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.150
diff -u -p -d -r1.150 local-alloc.c
--- local-alloc.c	16 Jun 2005 10:33:14 -0000	1.150
+++ local-alloc.c	17 Jun 2005 08:44:21 -0000
@@ -1177,7 +1177,8 @@ update_equiv_regs (void)
 			 info.  */
 		      SET_REGNO_REG_SET (&cleared_regs, regno);
-		      reg_equiv_init[regno] = NULL_RTX;
+		      reg_equiv_init[regno]
+			= gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);

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