This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PR 50873: create_fixed_operand and virtual regs
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 09 Dec 2011 16:44:20 +0000
- Subject: PR 50873: create_fixed_operand and virtual regs
ARM's neon_vector_mem_operand does not allow eliminable or virtual registers
to be used as addresses. create_*_operand was supposed to cope with that by
replacing the address with a (non-virtual) pseudo register. The problem is
that I used the wrong function: force_reg rather than copy_to_mode_reg.
I see I also rather lazily used Pmode instead of addr_space.address_mode.
This patch fixes both problems.
Tested on arm-linux-gnueabi, where it prevents an ICE in dilayout.c.
OK to install?
Richard
gcc/
PR middle-end/50873
* optabs.c (maybe_legitimize_operand_same_code): Use copy_to_mode_reg
instead of force_reg. Do nothing if the address is already a
non-virtual pseudo register.
Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c 2011-12-08 11:17:35.319229272 +0000
--- gcc/optabs.c 2011-12-09 16:32:01.781886061 +0000
*************** maybe_legitimize_operand_same_code (enum
*** 8241,8264 ****
return true;
/* If the operand is a memory whose address has no side effects,
! try forcing the address into a register. The check for side
! effects is important because force_reg cannot handle things
! like auto-modified addresses. */
! if (insn_data[(int) icode].operand[opno].allows_mem
! && MEM_P (op->value)
! && !side_effects_p (XEXP (op->value, 0)))
{
! rtx addr, mem, last;
! last = get_last_insn ();
! addr = force_reg (Pmode, XEXP (op->value, 0));
! mem = replace_equiv_address (op->value, addr);
! if (insn_operand_matches (icode, opno, mem))
{
! op->value = mem;
! return true;
}
- delete_insns_since (last);
}
return false;
--- 8241,8271 ----
return true;
/* If the operand is a memory whose address has no side effects,
! try forcing the address into a non-virtual pseudo register.
! The check for side effects is important because copy_to_mode_reg
! cannot handle things like auto-modified addresses. */
! if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
{
! rtx addr, mem;
! mem = op->value;
! addr = XEXP (mem, 0);
! if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
! && !side_effects_p (addr))
{
! rtx last;
! enum machine_mode mode;
!
! last = get_last_insn ();
! mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem));
! mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
! if (insn_operand_matches (icode, opno, mem))
! {
! op->value = mem;
! return true;
! }
! delete_insns_since (last);
}
}
return false;