This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: VEC_COND_EXPR
On Fri, Oct 12, 2012 at 12:48 AM, Marc Glisse <marc.glisse@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.glisse@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);
>