Comment 15 for bug 809768

Revision history for this message
Ulrich Weigand (uweigand) wrote :

The (reg:SI 95 d16 [orig:149 lx ] [149]) is generated by the cprop_hardreg pass substituting d16 for r2 inside a var_location debug insn.

Of course, the regcprop.c code does perform the usual back-end checks:

static bool
mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode,
                unsigned int regno ATTRIBUTE_UNUSED)
{
  if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
    return false;

#ifdef CANNOT_CHANGE_MODE_CLASS
  return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode);
#endif

  return true;
}

However, in Linaro GCC 4.6, the REG_CANNOT_CHANGE_MODE_P check does not prohibit the change from DFmode to SImode in register 95 (d16), even though HARD_REGNO_MODE_OK would reject SImode in d16.

This seems an inconsistency in the back-end. This looks to have been introduced via a backport from mainline of the following patch:

http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01631.html

2011-05-05 Richard Sandiford <email address hidden>

       gcc/
       Backport from mainline:

       2011-03-25 Richard Sandiford <email address hidden>

       * config/arm/arm.h (CANNOT_CHANGE_MODE_CLASS): Restrict FPA_REGS
       case to VFPv1.

Richard, any thoughts? Should CANNOT_CHANGE_MODE_CLASS accept modes in registers that are not accepted by HARD_REGNO_MODE_OK? If not, should regcprop.c check both macros?