This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix g++.dg/other/complex1.C
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 25 Dec 2004 20:02:22 -0800
- Subject: 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;