diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d860de0124..003f8cdadaa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-02-15 Michael Meissner + + 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 * extend.texi: Reserve upper bits of memory model for future use. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 97a3b81b08d..3ffc48c7e31 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 870867f84e9..cba5c940c3c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-02-15 Michael Meissner + + PR target/52199 + * gcc.target/powerpc/pr52199.c: New file. + 2012-02-15 Rainer Orth PR target/52152 diff --git a/gcc/testsuite/gcc.target/powerpc/pr52199.c b/gcc/testsuite/gcc.target/powerpc/pr52199.c new file mode 100644 index 00000000000..e2231938839 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr52199.c @@ -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; + } +}