This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]