This is the mail archive of the gcc-bugs@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]

[Bug target/14927] [ia64] ICE in gen_movxf


------- Additional Comments From wilson at specifixinc dot com  2004-04-23 06:17 -------
Subject: Re:  New: [ia64] ICE in gen_movxf

schwab at suse dot de wrote:
> scalar-by-value-3_x.i: In function `testitcld': 
> scalar-by-value-3_x.i:6: internal compiler error: in gen_movxf, at 

This is a long latent SUBREG problem, going back at least 4 years to 
when some of the long double code was originally added.

The movxf pattern fails to handle the case where operands[0] is a SUBREG 
of a GR reg.  While looking at the code, I noticed a second latent 
problem.  There is one place where we are accidentally applying 
SUBREG_REG to a GR reg.  I tried to fix that too, though I don't have a 
testcase for it.

The following patch works for this testcase, but is as yet untested.
2004-04-22  James E Wilson  <wilson@specifixinc.com>

	* config/ia64/ia64.md (movxf): New local op0.  Handle case where
	operands[0] is a SUBREG.  Handle case where operands[1] is a GR reg.

Index: ia64.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v
retrieving revision 1.128
diff -p -r1.128 ia64.md
*** ia64.md	21 Apr 2004 01:39:17 -0000	1.128
--- ia64.md	23 Apr 2004 06:12:47 -0000
***************
*** 677,688 ****
  	(match_operand:XF 1 "general_operand" ""))]
    ""
  {
    /* We must support XFmode loads into general registers for stdarg/vararg
       and unprototyped calls.  We split them into DImode loads for convenience.
       We don't need XFmode stores from general regs, because a stdarg/vararg
       routine does a block store to memory of unnamed arguments.  */
!   if (GET_CODE (operands[0]) == REG
!       && GR_REGNO_P (REGNO (operands[0])))
      {
        /* We're hoping to transform everything that deals with XFmode
  	 quantities and GR registers early in the compiler.  */
--- 677,693 ----
  	(match_operand:XF 1 "general_operand" ""))]
    ""
  {
+   rtx op0 = operands[0];
+ 
+   if (GET_CODE (op0) == SUBREG)
+     op0 = SUBREG_REG (op0);
+ 
    /* We must support XFmode loads into general registers for stdarg/vararg
       and unprototyped calls.  We split them into DImode loads for convenience.
       We don't need XFmode stores from general regs, because a stdarg/vararg
       routine does a block store to memory of unnamed arguments.  */
! 
!   if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0)))
      {
        /* We're hoping to transform everything that deals with XFmode
  	 quantities and GR registers early in the compiler.  */
***************
*** 695,710 ****
  	  || (GET_CODE (operands[1]) == REG
  	      && GR_REGNO_P (REGNO (operands[1]))))
  	{
! 	  emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])),
! 			  SUBREG_REG (operands[1]));
  	  DONE;
  	}
  
        if (GET_CODE (operands[1]) == CONST_DOUBLE)
  	{
! 	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
  			  operand_subword (operands[1], 0, 0, XFmode));
! 	  emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
  			  operand_subword (operands[1], 1, 0, XFmode));
  	  DONE;
  	}
--- 700,722 ----
  	  || (GET_CODE (operands[1]) == REG
  	      && GR_REGNO_P (REGNO (operands[1]))))
  	{
! 	  rtx op1 = operands[1];
! 
! 	  if (GET_CODE (op1) == SUBREG)
! 	    op1 = SUBREG_REG (op1);
! 	  else
! 	    /* ??? Maybe we should make a SUBREG here?  */
! 	    op1 = gen_rtx_REG (TImode, REGNO (op1));
! 
! 	  emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1);
  	  DONE;
  	}
  
        if (GET_CODE (operands[1]) == CONST_DOUBLE)
  	{
! 	  emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)),
  			  operand_subword (operands[1], 0, 0, XFmode));
! 	  emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1),
  			  operand_subword (operands[1], 1, 0, XFmode));
  	  DONE;
  	}
***************
*** 717,724 ****
  	{
  	  rtx out[2];
  
! 	  out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0]));
! 	  out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1);
  
  	  emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
  	  emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));
--- 729,736 ----
  	{
  	  rtx out[2];
  
! 	  out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0));
! 	  out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1);
  
  	  emit_move_insn (out[0], adjust_address (operands[1], DImode, 0));
  	  emit_move_insn (out[1], adjust_address (operands[1], DImode, 8));


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14927


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