Message ID | 20210605151844.470344-2-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | Allow vec_duplicate_optab to fail | expand |
"H.J. Lu" <hjl.tools@gmail.com> writes: > Update vec_duplicate to allow to fail so that backend can only allow > broadcasting an integer constant to a vector when broadcast instruction > is available. I'm not sure why we need this to fail though. Once the optab is defined for target X, the optab should handle all duplicates for target X, even if there are different strategies it can use. AIUI the case you want to make conditional is the constant case. I guess the first question is: why don't we simplify those CONSTRUCTORs to VECTOR_CSTs in gimple? I'm surprised we still see the constant case as a constructor here. If we can't rely on that happening, then would it work to change: /* Try using vec_duplicate_optab for uniform vectors. */ if (!TREE_SIDE_EFFECTS (exp) && VECTOR_MODE_P (mode) && eltmode == GET_MODE_INNER (mode) && ((icode = optab_handler (vec_duplicate_optab, mode)) != CODE_FOR_nothing) && (elt = uniform_vector_p (exp))) to something like: /* Try using vec_duplicate_optab for uniform vectors. */ if (!TREE_SIDE_EFFECTS (exp) && VECTOR_MODE_P (mode) && eltmode == GET_MODE_INNER (mode) && (elt = uniform_vector_p (exp))) { if (TREE_CODE (elt) == INTEGER_CST || TREE_CODE (elt) == POLY_INT_CST || TREE_CODE (elt) == REAL_CST || TREE_CODE (elt) == FIXED_CST) { rtx src = gen_const_vec_duplicate (mode, expand_normal (node)); emit_move_insn (target, src); break; } … } Thanks, Richard
On Mon, Jun 7, 2021 at 12:12 AM Richard Sandiford <richard.sandiford@arm.com> wrote: > > "H.J. Lu" <hjl.tools@gmail.com> writes: > > Update vec_duplicate to allow to fail so that backend can only allow > > broadcasting an integer constant to a vector when broadcast instruction > > is available. > > I'm not sure why we need this to fail though. Once the optab is defined > for target X, the optab should handle all duplicates for target X, > even if there are different strategies it can use. > > AIUI the case you want to make conditional is the constant case. > I guess the first question is: why don't we simplify those CONSTRUCTORs > to VECTOR_CSTs in gimple? I'm surprised we still see the constant case > as a constructor here. The particular testcase for vec_duplicate is gcc.dg/pr100239.c. > If we can't rely on that happening, then would it work to change: > > /* Try using vec_duplicate_optab for uniform vectors. */ > if (!TREE_SIDE_EFFECTS (exp) > && VECTOR_MODE_P (mode) > && eltmode == GET_MODE_INNER (mode) > && ((icode = optab_handler (vec_duplicate_optab, mode)) > != CODE_FOR_nothing) > && (elt = uniform_vector_p (exp))) > > to something like: > > /* Try using vec_duplicate_optab for uniform vectors. */ > if (!TREE_SIDE_EFFECTS (exp) > && VECTOR_MODE_P (mode) > && eltmode == GET_MODE_INNER (mode) > && (elt = uniform_vector_p (exp))) > { > if (TREE_CODE (elt) == INTEGER_CST > || TREE_CODE (elt) == POLY_INT_CST > || TREE_CODE (elt) == REAL_CST > || TREE_CODE (elt) == FIXED_CST) > { > rtx src = gen_const_vec_duplicate (mode, expand_normal (node)); > emit_move_insn (target, src); > break; > } > … > } I will give it a try. Thanks.
On Mon, Jun 7, 2021 at 4:19 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Mon, Jun 7, 2021 at 12:12 AM Richard Sandiford > <richard.sandiford@arm.com> wrote: > > > > "H.J. Lu" <hjl.tools@gmail.com> writes: > > > Update vec_duplicate to allow to fail so that backend can only allow > > > broadcasting an integer constant to a vector when broadcast instruction > > > is available. > > > > I'm not sure why we need this to fail though. Once the optab is defined > > for target X, the optab should handle all duplicates for target X, > > even if there are different strategies it can use. > > > > AIUI the case you want to make conditional is the constant case. > > I guess the first question is: why don't we simplify those CONSTRUCTORs > > to VECTOR_CSTs in gimple? I'm surprised we still see the constant case > > as a constructor here. > > The particular testcase for vec_duplicate is gcc.dg/pr100239.c. > > > If we can't rely on that happening, then would it work to change: > > > > /* Try using vec_duplicate_optab for uniform vectors. */ > > if (!TREE_SIDE_EFFECTS (exp) > > && VECTOR_MODE_P (mode) > > && eltmode == GET_MODE_INNER (mode) > > && ((icode = optab_handler (vec_duplicate_optab, mode)) > > != CODE_FOR_nothing) > > && (elt = uniform_vector_p (exp))) > > > > to something like: > > > > /* Try using vec_duplicate_optab for uniform vectors. */ > > if (!TREE_SIDE_EFFECTS (exp) > > && VECTOR_MODE_P (mode) > > && eltmode == GET_MODE_INNER (mode) > > && (elt = uniform_vector_p (exp))) > > { > > if (TREE_CODE (elt) == INTEGER_CST > > || TREE_CODE (elt) == POLY_INT_CST > > || TREE_CODE (elt) == REAL_CST > > || TREE_CODE (elt) == FIXED_CST) > > { > > rtx src = gen_const_vec_duplicate (mode, expand_normal (node)); > > emit_move_insn (target, src); > > break; > > } > > … > > } > > I will give it a try. I can confirm that veclower leaves us with an unfolded constant CTOR. If you file a PR to remind me I'll fix that. Richard. > Thanks. > > -- > H.J.
On Mon, Jun 7, 2021 at 7:59 PM Richard Biener <richard.guenther@gmail.com> wrote: > > On Mon, Jun 7, 2021 at 4:19 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > On Mon, Jun 7, 2021 at 12:12 AM Richard Sandiford > > <richard.sandiford@arm.com> wrote: > > > > > > "H.J. Lu" <hjl.tools@gmail.com> writes: > > > > Update vec_duplicate to allow to fail so that backend can only allow > > > > broadcasting an integer constant to a vector when broadcast instruction > > > > is available. > > > > > > I'm not sure why we need this to fail though. Once the optab is defined > > > for target X, the optab should handle all duplicates for target X, > > > even if there are different strategies it can use. > > > > > > AIUI the case you want to make conditional is the constant case. > > > I guess the first question is: why don't we simplify those CONSTRUCTORs > > > to VECTOR_CSTs in gimple? I'm surprised we still see the constant case > > > as a constructor here. > > > > The particular testcase for vec_duplicate is gcc.dg/pr100239.c. > > > > > If we can't rely on that happening, then would it work to change: > > > > > > /* Try using vec_duplicate_optab for uniform vectors. */ > > > if (!TREE_SIDE_EFFECTS (exp) > > > && VECTOR_MODE_P (mode) > > > && eltmode == GET_MODE_INNER (mode) > > > && ((icode = optab_handler (vec_duplicate_optab, mode)) > > > != CODE_FOR_nothing) > > > && (elt = uniform_vector_p (exp))) > > > > > > to something like: > > > > > > /* Try using vec_duplicate_optab for uniform vectors. */ > > > if (!TREE_SIDE_EFFECTS (exp) > > > && VECTOR_MODE_P (mode) > > > && eltmode == GET_MODE_INNER (mode) > > > && (elt = uniform_vector_p (exp))) > > > { > > > if (TREE_CODE (elt) == INTEGER_CST > > > || TREE_CODE (elt) == POLY_INT_CST > > > || TREE_CODE (elt) == REAL_CST > > > || TREE_CODE (elt) == FIXED_CST) > > > { > > > rtx src = gen_const_vec_duplicate (mode, expand_normal (node)); > > > emit_move_insn (target, src); > > > break; > > > } > > > … > > > } > > > > I will give it a try. > > I can confirm that veclower leaves us with an unfolded constant CTOR. > If you file a PR to remind me I'll fix that. The attached untested patch fixes this for the testcase. Richard. > Richard. > > > Thanks. > > > > -- > > H.J.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index 00caf3844cc..e66c41c4779 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -5077,8 +5077,6 @@ the mode appropriate for one element of @var{m}. This pattern only handles duplicates of non-constant inputs. Constant vectors go through the @code{mov@var{m}} pattern instead. -This pattern is not allowed to @code{FAIL}. - @cindex @code{vec_series@var{m}} instruction pattern @item @samp{vec_series@var{m}} Initialize vector output operand 0 so that element @var{i} is equal to diff --git a/gcc/expr.c b/gcc/expr.c index e4660f0e90a..3107c32f259 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7075,10 +7075,12 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size, class expand_operand ops[2]; create_output_operand (&ops[0], target, mode); create_input_operand (&ops[1], expand_normal (elt), eltmode); - expand_insn (icode, 2, ops); - if (!rtx_equal_p (target, ops[0].value)) - emit_move_insn (target, ops[0].value); - break; + if (maybe_expand_insn (icode, 2, ops)) + { + if (!rtx_equal_p (target, ops[0].value)) + emit_move_insn (target, ops[0].value); + break; + } } n_elts = TYPE_VECTOR_SUBPARTS (type);