On Fri, Jun 29, 2012 at 11:33:39AM -0700, H.J. Lu wrote: > On Fri, Jun 29, 2012 at 9:50 AM, Richard Henderson <r...@redhat.com> wrote: > > We use it everywhere else, but it got forgotten here. Saves two shuffles > > on Altivec. > > > > Although with all of this duplication it makes me wonder if we shouldn't > > just give up > > on the idea of auto-generating MULT_HIGHPART from other operations > > (particularly given > > the extra type frobbing involved). In some sense it'd be easier to just > > add a couple > > of lines to the backends to implement the operation and be done with it. > > Thoughts?
Perhaps, and the backends could even try to generate better sequences. I'd say we should keep the generic expansion bits around until all targets that provide one or the other way of widening multiply are converted to provide the *_highpart expanders as well. > > That said, tested on ppc64-linux. Committed. > > It caused: > > > FAIL: gcc.c-torture/execute/pr53645.c execution, -O1 This should fix it, at least the testcase now passes on i?86 both as is and with the decl_e stuff disabled. Ok for trunk? 2012-06-29 Jakub Jelinek <ja...@redhat.com> * tree-vect-generic.c (expand_vector_divmod): For even/odd widening multiply, put even always as first argument to VEC_PERM_EXPR. --- gcc/tree-vect-generic.c.jj 2012-06-29 21:22:05.000000000 +0200 +++ gcc/tree-vect-generic.c 2012-06-29 21:39:32.020485781 +0200 @@ -457,7 +457,7 @@ expand_vector_divmod (gimple_stmt_iterat optab op; tree *vec; unsigned char *sel = NULL; - tree cur_op, mhi, mlo, mulcst, perm_mask, wider_type, tem, decl_e, decl_o; + tree cur_op, m1, m2, mulcst, perm_mask, wider_type, tem, decl_e, decl_o; if (prec > HOST_BITS_PER_WIDE_INT) return NULL_TREE; @@ -843,35 +843,32 @@ expand_vector_divmod (gimple_stmt_iterat gimple call; call = gimple_build_call (decl_e, 2, cur_op, mulcst); - mhi = create_tmp_reg (wider_type, NULL); - add_referenced_var (mhi); - mhi = make_ssa_name (mhi, call); - gimple_call_set_lhs (call, mhi); + m1 = create_tmp_reg (wider_type, NULL); + add_referenced_var (m1); + m1 = make_ssa_name (m1, call); + gimple_call_set_lhs (call, m1); gsi_insert_seq_before (gsi, call, GSI_SAME_STMT); call = gimple_build_call (decl_o, 2, cur_op, mulcst); - mlo = create_tmp_reg (wider_type, NULL); - add_referenced_var (mlo); - mlo = make_ssa_name (mlo, call); - gimple_call_set_lhs (call, mlo); + m2 = create_tmp_reg (wider_type, NULL); + add_referenced_var (m2); + m2 = make_ssa_name (m2, call); + gimple_call_set_lhs (call, m2); gsi_insert_seq_before (gsi, call, GSI_SAME_STMT); } else { - mhi = gimplify_build2 (gsi, VEC_WIDEN_MULT_HI_EXPR, wider_type, - cur_op, mulcst); - mlo = gimplify_build2 (gsi, VEC_WIDEN_MULT_LO_EXPR, wider_type, - cur_op, mulcst); + m1 = gimplify_build2 (gsi, BYTES_BIG_ENDIAN ? VEC_WIDEN_MULT_HI_EXPR + : VEC_WIDEN_MULT_LO_EXPR, + wider_type, cur_op, mulcst); + m2 = gimplify_build2 (gsi, BYTES_BIG_ENDIAN ? VEC_WIDEN_MULT_LO_EXPR + : VEC_WIDEN_MULT_HI_EXPR, + wider_type, cur_op, mulcst); } - mhi = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, mhi); - mlo = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, mlo); - if (BYTES_BIG_ENDIAN) - cur_op = gimplify_build3 (gsi, VEC_PERM_EXPR, type, mhi, mlo, - perm_mask); - else - cur_op = gimplify_build3 (gsi, VEC_PERM_EXPR, type, mlo, mhi, - perm_mask); + m1 = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, m1); + m2 = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, m2); + cur_op = gimplify_build3 (gsi, VEC_PERM_EXPR, type, m1, m2, perm_mask); } switch (mode) Jakub