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]

fix g++.dg/other/complex1.C


This test includes an empty CONSTRUCTOR for a complex number.  RTL
doesn't have a representation for complex zeros, so emit_move_insn
received a null.  Special casing complex numbers is sufficient, but
the rearrangement ensures that we sanely fallthrough to memset in
the event nothing else pans out.

Tested on alphaev67-linux.


r~


        * expr.c (clear_storage): Validate CONST0_RTX extant.  Special case
        complex modes.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.766
diff -c -p -d -r1.766 expr.c
*** expr.c	23 Dec 2004 13:02:25 -0000	1.766
--- expr.c	26 Dec 2004 03:58:07 -0000
*************** static void emit_single_push_insn (enum 
*** 159,164 ****
--- 159,165 ----
  #endif
  static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
  static rtx const_vector_from_tree (tree);
+ static void write_complex_part (rtx, rtx, bool);
  
  /* Record for each mode whether we can move a register directly to or
     from an object of that mode in memory.  If we can't, we won't try
*************** store_by_pieces_2 (rtx (*genfun) (rtx, .
*** 2405,2434 ****
  rtx
  clear_storage (rtx object, rtx size)
  {
!   rtx retval = 0;
!   unsigned int align = (MEM_P (object) ? MEM_ALIGN (object)
! 			: GET_MODE_ALIGNMENT (GET_MODE (object)));
  
    /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
       just move a zero.  Otherwise, do this a piece at a time.  */
!   if (GET_MODE (object) != BLKmode
        && GET_CODE (size) == CONST_INT
!       && INTVAL (size) == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (object)))
!     emit_move_insn (object, CONST0_RTX (GET_MODE (object)));
!   else
      {
!       if (size == const0_rtx)
! 	;
!       else if (GET_CODE (size) == CONST_INT
! 	  && CLEAR_BY_PIECES_P (INTVAL (size), align))
! 	clear_by_pieces (object, INTVAL (size), align);
!       else if (clear_storage_via_clrmem (object, size, align))
! 	;
!       else
! 	retval = clear_storage_via_libcall (object, size);
      }
  
!   return retval;
  }
  
  /* A subroutine of clear_storage.  Expand a clrmem pattern;
--- 2406,2453 ----
  rtx
  clear_storage (rtx object, rtx size)
  {
!   enum machine_mode mode = GET_MODE (object);
!   unsigned int align;
  
    /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
       just move a zero.  Otherwise, do this a piece at a time.  */
!   if (mode != BLKmode
        && GET_CODE (size) == CONST_INT
!       && INTVAL (size) == (HOST_WIDE_INT) GET_MODE_SIZE (mode))
      {
!       rtx zero = CONST0_RTX (mode);
!       if (zero != NULL)
! 	{
! 	  emit_move_insn (object, zero);
! 	  return NULL;
! 	}
! 
!       if (COMPLEX_MODE_P (mode))
! 	{
! 	  zero = CONST0_RTX (GET_MODE_INNER (mode));
! 	  if (zero != NULL)
! 	    {
! 	      write_complex_part (object, zero, 0);
! 	      write_complex_part (object, zero, 1);
! 	      return NULL;
! 	    }
! 	}
      }
  
!   if (size == const0_rtx)
!     return NULL;
! 
!   align = MEM_ALIGN (object);
! 
!   if (GET_CODE (size) == CONST_INT
!       && CLEAR_BY_PIECES_P (INTVAL (size), align))
!     clear_by_pieces (object, INTVAL (size), align);
!   else if (clear_storage_via_clrmem (object, size, align))
!     ;
!   else
!     return clear_storage_via_libcall (object, size);
! 
!   return NULL;
  }
  
  /* A subroutine of clear_storage.  Expand a clrmem pattern;


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