[Bug target/68729] ../Xbae/Methods.c:1772:1: ICE: in extract_insn, at recog.c:2343

danglin at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Dec 5 21:24:00 GMT 2015


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68729

John David Anglin <danglin at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu.org

--- Comment #1 from John David Anglin <danglin at gcc dot gnu.org> ---
The problem occurs trying to do an HImode reload to a floating point register. 
pa_emit_move_sequence is called as follows:

(gdb) p debug_rtx (operands[1])
(subreg:SI (reg:HI 3488 [ *_720 ]) 0)
$26 = void
(gdb) p debug_rtx (operands[0])
(reg:SI 68 %fr22)
$27 = void
(gdb) p debug_rtx (operands[1])
(subreg:SI (reg:HI 3488 [ *_720 ]) 0)
$28 = void
(gdb) p mode
$29 = HImode
(gdb) p debug_rtx (scratch_reg)
(reg:HI 20 %r20)

operand1, which is operand[1], is altered here:

  else if (scratch_reg
           && reload_in_progress && GET_CODE (operand1) == SUBREG
           && GET_CODE (SUBREG_REG (operand1)) == REG
           && REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
    {
     /* We must not alter SUBREG_BYTE (operand0) since that would confuse
        the code which tracks sets/uses for delete_output_reload.  */
      rtx temp = gen_rtx_SUBREG (GET_MODE (operand1),
                                 reg_equiv_mem (REGNO (SUBREG_REG (operand1))),
                                 SUBREG_BYTE (operand1));
      operand1 = alter_subreg (&temp, true);
    }

yielding

(gdb) p debug_rtx (operand1)
(mem/c:SI (plus:SI (reg/f:SI 30 %r30)
        (const_int -256 [0xffffffffffffff00])) [38 %sfp+64 S4 A16])
$31 = void

Have to wonder if the above is truly equivalent given the high portion
might be nonzero and we can only load 32 and 64-bit floating point values
from memory.

The subsequent code that normally would handle reloads to a floating

  /* Handle secondary reloads for loads/stores of FP registers from
     REG+D addresses where D does not fit in 5 or 14 bits, including
     (subreg (mem (addr))) cases.  */
  if (scratch_reg
      && fp_reg_operand (operand0, mode)
      && (MEM_P (operand1)
          || (GET_CODE (operand1) == SUBREG
              && MEM_P (XEXP (operand1, 0))))
      && !floating_point_store_memory_operand (operand1, mode))
    {

is not invoked since we operand0 is SImode and mode is HImode.

Jeff, do you have a comment on how this should be handled?


More information about the Gcc-bugs mailing list