GCC reload problem

Eric Botcazou ebotcazou@libertysurf.fr
Fri Apr 11 09:18:00 GMT 2003


> The problem here is that with SUBREG_BYTE, the word-based tests in
> this if statement are no longer valid.  Which parts of the comparison
> are actually passing?

The same part that triggers in reload.c:reload_inner_reg_of_subreg()

  /* If the outer part is a word or smaller, INNER larger than a
     word and the number of regs for INNER is not the same as the
     number of words in INNER, then INNER will need reloading.  */
  return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
	  && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD
	  && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD)
	      != HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));

reload_inner_reg_of_subreg() is the function that detects invalid subregs, 
but only if a reload has already been scheduled by find_reloads().

> My initial guess is that the part that's valid is the
>
> HARD_REGNO_MODE_OK check.  And thus we'd end up with something like:
> 		  || (GET_CODE (operand) == REG
>
> 		      && REGNO (operand) < FIRST_PSEUDO_REGISTER
> 		      && ! HARD_REGNO_MODE_OK (REGNO (operand) + offset,
> 					       operand_mode[i]))

No, offset == 0 here because it comes from

		  offset += subreg_regno_offset (REGNO (SUBREG_REG (operand)),
						 GET_MODE (SUBREG_REG (operand)),
						 SUBREG_BYTE (operand),
						 GET_MODE (operand));

The invalid subreg is

	(subreg:SI (reg/v:DI 29 rmm0 [67]) 4)

MMX registers are 8-byte wide so a SUBREG_BYTE of 4 is not sufficient to bump 
the REGNO. But MMX registers do support SImode, that is

	(subreg:SI (reg/v:DI 29 rmm0 [67]) 0)

is allowed. Hence

	HARD_REGNO_MODE_OK (REGNO (operand) + offset, operand_mode[i]) == 1

-- 
Eric Botcazou



More information about the Gcc mailing list