re PR target/52199 (V2DI vec_duplicate ICE on valid code)

[gcc]
2012-02-15  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/52199
	* config/rs6000/rs6000.c (rs6000_expand_vector_init): Use
	force_reg instead of copy_to_reg for better optimization.  Force
	non-register or memory operands into a register.

[gcc/testsuite]
2012-02-15  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/52199
	* gcc.target/powerpc/pr52199.c: New file.

From-SVN: r184287
This commit is contained in:
Michael Meissner 2012-02-15 21:42:00 +00:00 committed by Michael Meissner
parent b87bc3aa06
commit a0367cc1ac
4 changed files with 53 additions and 20 deletions

View File

@ -1,3 +1,10 @@
2012-02-15 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/52199
* config/rs6000/rs6000.c (rs6000_expand_vector_init): Use
force_reg instead of copy_to_reg for better optimization. Force
non-register or memory operands into a register.
2012-02-15 Andrew MacLeod <amacleod@redhat.com>
* extend.texi: Reserve upper bits of memory model for future use.

View File

@ -4701,28 +4701,25 @@ rs6000_expand_vector_init (rtx target, rtx vals)
/* Double word values on VSX can use xxpermdi or lxvdsx. */
if (VECTOR_MEM_VSX_P (mode) && (mode == V2DFmode || mode == V2DImode))
{
rtx op0 = XVECEXP (vals, 0, 0);
rtx op1 = XVECEXP (vals, 0, 1);
if (all_same)
{
rtx element = XVECEXP (vals, 0, 0);
if (!MEM_P (op0) && !REG_P (op0))
op0 = force_reg (inner_mode, op0);
if (mode == V2DFmode)
emit_insn (gen_vsx_splat_v2df (target, element));
emit_insn (gen_vsx_splat_v2df (target, op0));
else
emit_insn (gen_vsx_splat_v2di (target, element));
emit_insn (gen_vsx_splat_v2di (target, op0));
}
else
{
op0 = force_reg (inner_mode, op0);
op1 = force_reg (inner_mode, op1);
if (mode == V2DFmode)
{
rtx op0 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 0));
rtx op1 = copy_to_mode_reg (DFmode, XVECEXP (vals, 0, 1));
emit_insn (gen_vsx_concat_v2df (target, op0, op1));
}
emit_insn (gen_vsx_concat_v2df (target, op0, op1));
else
{
rtx op0 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 0));
rtx op1 = copy_to_mode_reg (DImode, XVECEXP (vals, 0, 1));
emit_insn (gen_vsx_concat_v2di (target, op0, op1));
}
emit_insn (gen_vsx_concat_v2di (target, op0, op1));
}
return;
}
@ -4736,7 +4733,7 @@ rs6000_expand_vector_init (rtx target, rtx vals)
if (all_same)
{
rtx freg = gen_reg_rtx (V4SFmode);
rtx sreg = copy_to_reg (XVECEXP (vals, 0, 0));
rtx sreg = force_reg (SFmode, XVECEXP (vals, 0, 0));
emit_insn (gen_vsx_xscvdpsp_scalar (freg, sreg));
emit_insn (gen_vsx_xxspltw_v4sf (target, freg, const0_rtx));
@ -4747,13 +4744,13 @@ rs6000_expand_vector_init (rtx target, rtx vals)
rtx dbl_odd = gen_reg_rtx (V2DFmode);
rtx flt_even = gen_reg_rtx (V4SFmode);
rtx flt_odd = gen_reg_rtx (V4SFmode);
rtx op0 = force_reg (SFmode, XVECEXP (vals, 0, 0));
rtx op1 = force_reg (SFmode, XVECEXP (vals, 0, 1));
rtx op2 = force_reg (SFmode, XVECEXP (vals, 0, 2));
rtx op3 = force_reg (SFmode, XVECEXP (vals, 0, 3));
emit_insn (gen_vsx_concat_v2sf (dbl_even,
copy_to_reg (XVECEXP (vals, 0, 0)),
copy_to_reg (XVECEXP (vals, 0, 1))));
emit_insn (gen_vsx_concat_v2sf (dbl_odd,
copy_to_reg (XVECEXP (vals, 0, 2)),
copy_to_reg (XVECEXP (vals, 0, 3))));
emit_insn (gen_vsx_concat_v2sf (dbl_even, op0, op1));
emit_insn (gen_vsx_concat_v2sf (dbl_odd, op2, op3));
emit_insn (gen_vsx_xvcvdpsp (flt_even, dbl_even));
emit_insn (gen_vsx_xvcvdpsp (flt_odd, dbl_odd));
rs6000_expand_extract_even (target, flt_even, flt_odd);

View File

@ -1,3 +1,8 @@
2012-02-15 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/52199
* gcc.target/powerpc/pr52199.c: New file.
2012-02-15 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR target/52152

View File

@ -0,0 +1,24 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-options "-O3 -mcpu=power7 -fmerge-all-constants" } */
struct locale_time_t
{
const char *abday[7];
const unsigned int *wabday[7];
};
static const unsigned int empty_wstr[1] = { 0 };
void
time_read (struct locale_time_t *time)
{
int cnt;
for (cnt=0; cnt < 7; cnt++)
{
time->abday[cnt] = "";
time->wabday[cnt] = empty_wstr;
}
}