On Tue, 6 Mar 2007, Roman Zippel wrote:
> Reload has now to match (reg %d0) and (reg 38) above in insn 32 and after > pseudo register replacement it looks like this: > > (insn 32 10 30 2 (parallel [ > (set (strict_low_part (reg:SI 1 %d1 [orig:38+4 ] [38])) > (mult:SI (reg/v:SI 0 %d0 [ a ]) > (reg/v:SI 1 %d1 [ b ]))) > (set (strict_low_part (reg:SI 0 %d0 [37])) > (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (reg/v:SI > 0 %d0 [ a ])) > (zero_extend:DI (reg/v:SI 1 %d1 [ b ]))) > (const_int 32 [0x20])))) > ]) 181 {*umulsidi3_subreg} (nil) > (expr_list:REG_DEAD (reg/v:SI 0 %d0 [ a ]) > (expr_list:REG_DEAD (reg/v:SI 1 %d1 [ b ]) > (nil)))) > > Notice that the REG_DEAD notes are not correct anymore, > [..] > > %d0 is used in both set destinations and postreload dies because of it. > The question is now, who is responsible for telling reload that %d0/%d1 > are not really dead anymore after register allocation? Below is possible approach, I hijacked mark_not_eliminable to scan all register stores and remove the obsolete REG_DEAD notes. With this reload produces the correct reload. bye, Roman Index: gcc/reload1.c =================================================================== --- gcc/reload1.c (revision 122519) +++ gcc/reload1.c (working copy) @@ -842,7 +842,7 @@ cannot be done. */ for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn)) if (INSN_P (insn)) - note_stores (PATTERN (insn), mark_not_eliminable, NULL); + note_stores (PATTERN (insn), mark_not_eliminable, insn); maybe_fix_stack_asms (); @@ -3398,8 +3398,9 @@ the insns of the function. */ static void -mark_not_eliminable (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED) +mark_not_eliminable (rtx dest, rtx x, void *data) { + rtx note, insn = data; unsigned int i; /* A SUBREG of a hard register here is just changing its mode. We should @@ -3408,6 +3409,9 @@ if (GET_CODE (dest) == SUBREG) dest = SUBREG_REG (dest); + if (REG_P (dest) && (note = find_regno_note (insn, REG_DEAD, REGNO (dest)))) + remove_note (insn, note); + if (dest == hard_frame_pointer_rtx) return;