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

--- Comment #36 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Furthermore, nothing really guarantees you it must match,
gen_operands_ldrd_strd doesn't call plus_constant, it calls
mem_ok_for_ldrd_strd on each mem and subtracts the offsets.  So, probably a
helper that does exactly that should be used in the condition of the
define_insns.  That already calls arm_legitimate_address_p too. 
mem_ok_for_lrdr_strd is broken too:
  else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
    {
      *base = XEXP (addr, 0);
      *offset = XEXP (addr, 1);
      return (REG_P (*base) && CONST_INT_P (*offset));
    }
The handling of MINUS that way makes no sense.  If it wants to handle MINUS,
offset should be HOST_WIDE_INT rather than rtx and it should do:
  else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) && CONST_INT_P
(XEXP (addr, 1)))
    {
      *base = XEXP (addr, 0);
      *offset = INTVAL (XEXP (addr, 1));
      return true;
    }
  else if (GET_CODE (addr) == MINUS && REG_P (XEXP (addr, 0)) && CONST_INT_P
(XEXP (addr, 1)))
    {
      *base = XEXP (addr, 0);
      *offset = -UINTVAL (XEXP (addr, 1));
      return true;
    }
or just don't try to handle MINUS at all, MINUS with CONST_INT as op2 is not
canonical with the exception of HOST_WIDE_INT_MIN, but that is not possible for
SImode.

Reply via email to