On Fri, Oct 12, 2012 at 12:48 AM, Marc Glisse <marc.gli...@inria.fr> wrote: > Hello, > > this patch brings VEC_COND_EXPR closer to what the doc now says. The > non-comparison case and gimplification are dead paths currently, but it > seems convenient to introduce them now. Note that by using the generic > ternary gimplification code, it will produce VEC_COND_EXPR with an SSA_NAME > as first argument ;-)
Eh, seems we didn't handle VEC_COND_EXPR in gimplification at all ... > bootstrap+testsuite ok. Ok. Thanks, Richard. > 2012-10-12 Marc Glisse <marc.gli...@inria.fr> > > * optabs.c (vector_compare_rtx): Change prototype. > (expand_vec_cond_expr): Handle VEC_COND_EXPR whose first operand > is not a comparison. > * gimplify.c (gimplify_expr): Handle VEC_COND_EXPR. > > -- > Marc Glisse > Index: gimplify.c > =================================================================== > --- gimplify.c (revision 192378) > +++ gimplify.c (working copy) > @@ -7676,20 +7676,21 @@ gimplify_expr (tree *expr_p, gimple_seq > xop0); > if (!useless_type_conversion_p (new_type, TREE_TYPE (xop1))) > TREE_OPERAND (*expr_p, 1) = fold_convert_loc (input_location, > new_type, > xop1); > /* Continue classified as tcc_binary. */ > goto expr_2; > } > > case FMA_EXPR: > + case VEC_COND_EXPR: > case VEC_PERM_EXPR: > /* Classified as tcc_expression. */ > goto expr_3; > > case POINTER_PLUS_EXPR: > { > enum gimplify_status r0, r1; > r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, > post_p, is_gimple_val, fb_rvalue); > r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, > Index: optabs.c > =================================================================== > --- optabs.c (revision 192378) > +++ optabs.c (working copy) > @@ -6381,34 +6381,28 @@ get_rtx_code (enum tree_code tcode, bool > default: > gcc_unreachable (); > } > return code; > } > > /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or > unsigned operators. Do not generate compare instruction. */ > > static rtx > -vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode) > +vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1, > + bool unsignedp, enum insn_code icode) > { > struct expand_operand ops[2]; > - enum rtx_code rcode; > - tree t_op0, t_op1; > rtx rtx_op0, rtx_op1; > + enum rtx_code rcode = get_rtx_code (tcode, unsignedp); > > - /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer > - ensures that condition is a relational operation. */ > - gcc_assert (COMPARISON_CLASS_P (cond)); > - > - rcode = get_rtx_code (TREE_CODE (cond), unsignedp); > - t_op0 = TREE_OPERAND (cond, 0); > - t_op1 = TREE_OPERAND (cond, 1); > + gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison); > > /* Expand operands. */ > rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), > EXPAND_STACK_PARM); > rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), > EXPAND_STACK_PARM); > > create_input_operand (&ops[0], rtx_op0, GET_MODE (rtx_op0)); > create_input_operand (&ops[1], rtx_op1, GET_MODE (rtx_op1)); > if (!maybe_legitimize_operands (icode, 4, 2, ops)) > @@ -6677,34 +6671,49 @@ expand_vec_cond_expr_p (tree value_type, > rtx > expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2, > rtx target) > { > struct expand_operand ops[6]; > enum insn_code icode; > rtx comparison, rtx_op1, rtx_op2; > enum machine_mode mode = TYPE_MODE (vec_cond_type); > enum machine_mode cmp_op_mode; > bool unsignedp; > + tree op0a, op0b; > + enum tree_code tcode; > > - gcc_assert (COMPARISON_CLASS_P (op0)); > + if (COMPARISON_CLASS_P (op0)) > + { > + op0a = TREE_OPERAND (op0, 0); > + op0b = TREE_OPERAND (op0, 1); > + tcode = TREE_CODE (op0); > + } > + else > + { > + /* Fake op0 < 0. */ > + gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0))); > + op0a = op0; > + op0b = build_zero_cst (TREE_TYPE (op0)); > + tcode = LT_EXPR; > + } > + unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a)); > + cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a)); > > - unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0))); > - cmp_op_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0))); > > gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode) > && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode)); > > icode = get_vcond_icode (mode, cmp_op_mode, unsignedp); > if (icode == CODE_FOR_nothing) > return 0; > > - comparison = vector_compare_rtx (op0, unsignedp, icode); > + comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode); > rtx_op1 = expand_normal (op1); > rtx_op2 = expand_normal (op2); > > create_output_operand (&ops[0], target, mode); > create_input_operand (&ops[1], rtx_op1, mode); > create_input_operand (&ops[2], rtx_op2, mode); > create_fixed_operand (&ops[3], comparison); > create_fixed_operand (&ops[4], XEXP (comparison, 0)); > create_fixed_operand (&ops[5], XEXP (comparison, 1)); > expand_insn (icode, 6, ops); >