On Thu, Oct 30, 2025 at 9:14 PM Robin Dapp <[email protected]> wrote:
>
> Hi,
>
> this is more of an RFC I suppose. In RVV we don't have any hi/low,
> even/odd variants of widening instructions but n->n ("SLP style") ones.
> When trying to implement widening shift I noticed that the optab is
> not even there and figured when touching it I could as well
> make the entire thing an internal function just like other, newer
> widening functions. The plan after that would be adding IFN support
> to supportable_half_widening_operation and calling that in
> addition to supportable_widening_operation (or add it there as
> a second option so callers won't need to bother).
>
> In preparation for riscv support, this patch converts the widen_lshift
> tree code to an internal function, keeping the name and the optab.
> This helps unify widening-op handling in the vectorizer and elsewhere.
>
> I started with widen_lshift as we don't have dedicated folding
> optimizations related to it, that others like WIDEN_MULT_EXPR or
> WIDEN_MULT_PLUS_EXPR do have. Before converting them we would need
> to recreate the optimizations in match.pd (or related).
>
> The patch removes WIDEN_LSHIFT_EXPR, as well as
> VEC_WIDEN_LSHIFT_(LO/HI)_EXPR and adds the obligatory direct,
> as well as even/odd optabs. By converting to an IFN we lose a tad of
> type safety by not checking that the input operand is smaller than
> the output any more. Also, internal functions aren't systematically
> (and publicly) documented as opposed to tree codes. With the
> ever-growing number of internal functions we might want to change that?
Yes, we should IMO document those. A good place is difficult to choose,
in principle generic.texi and md.texi (for the direct ones) might be a
good place.
As for IL verification I'd like to see a
internal-fn.cc:verify_types_in_internal_fn_call ()
or so that we can call from the GIMPLE IL verification.
> Bootstrapped and regtested on x86 and power10. Regtested on rv64gcv_zvl512b
> and aarch64. I wasn't able to setup an arm qemu testing environment and
> arm is the only target that actually defines a widen_lshift instruction so a
> bit of coverage would be appreciated.
OK.
Thanks,
Richard.
> Regards
> Robin
>
>
> contrib/ChangeLog:
>
> * vim-gcc-dev/syntax/gcc-match.vim: Add n->n and even/odd
> variants.
>
> gcc/analyzer/ChangeLog:
>
> * region-model.cc (region_model::get_gassign_result): Remove
> VEC_WIDEN_LSHIFT_*.
>
> gcc/ChangeLog:
>
> * cfgexpand.cc (vars_ssa_cache::operator): Remove
> VEC_WIDEN_LSHIFT*.
> (expand_debug_expr): Ditto.
> * doc/md.texi: Document n->n and even/odd variants.
> * expr.cc (expand_expr_real_2): Ditto.
> * gimple-pretty-print.cc (dump_binary_rhs): Ditto.
> * internal-fn.def (VEC_WIDEN_LSHIFT): New IFN.
> * optabs-tree.cc (optab_for_tree_code): Remove
> VEC_WIDEN_LSHIFT*.
> * optabs.def (OPTAB_D): Add missing even/odd and direct
> widen lshift optabs.
> * tree-cfg.cc (verify_gimple_assign_binary): Remove
> VEC_WIDEN_LSHIFT*.
> * tree-inline.cc (estimate_operator_cost): Ditto.
> * tree-pretty-print.cc (dump_generic_node): Ditto.
> (op_code_prio): Ditto.
> (op_symbol_code): Ditto
> * tree-ssa-loop-im.cc (stmt_cost): Remvoe WIDEN_LSHIFT_EXPR.
> * tree-vect-data-refs.cc (vect_get_smallest_scalar_type): Ditto.
> * tree-vect-slp.cc (vect_build_slp_tree_1): Ditto.
> * tree-vect-generic.cc (expand_vector_operations_1): Ditto.
> * tree-vect-patterns.cc (vect_recog_widen_shift_pattern):
> Replace with IFN_VEC_WIDEN_LSHIFT.
> * tree-vect-stmts.cc (supportable_widening_operation):
> Remove VEC_WIDEN_LSHIFT*.
> * tree.def (VEC_WIDEN_LSHIFT_HI_EXPR): Remove.
> (VEC_WIDEN_LSHIFT_LO_EXPR): Ditto.
> ---
> contrib/vim-gcc-dev/syntax/gcc-match.vim | 4 ++-
> gcc/analyzer/region-model.cc | 2 --
> gcc/cfgexpand.cc | 16 ++--------
> gcc/doc/md.texi | 12 ++++++--
> gcc/expr.cc | 2 --
> gcc/gimple-pretty-print.cc | 2 --
> gcc/internal-fn.def | 5 ++++
> gcc/optabs-tree.cc | 12 --------
> gcc/optabs.def | 6 ++++
> gcc/tree-cfg.cc | 38 ------------------------
> gcc/tree-inline.cc | 3 --
> gcc/tree-pretty-print.cc | 18 -----------
> gcc/tree-ssa-loop-im.cc | 1 -
> gcc/tree-vect-data-refs.cc | 1 -
> gcc/tree-vect-generic.cc | 4 +--
> gcc/tree-vect-patterns.cc | 4 +--
> gcc/tree-vect-slp.cc | 5 ----
> gcc/tree-vect-stmts.cc | 19 ++----------
> gcc/tree.def | 23 --------------
> 19 files changed, 31 insertions(+), 146 deletions(-)
>
> diff --git a/contrib/vim-gcc-dev/syntax/gcc-match.vim
> b/contrib/vim-gcc-dev/syntax/gcc-match.vim
> index 22fb68091ac..a2f25644e5f 100644
> --- a/contrib/vim-gcc-dev/syntax/gcc-match.vim
> +++ b/contrib/vim-gcc-dev/syntax/gcc-match.vim
> @@ -42,13 +42,15 @@ syn keyword pdOp view_convert view_convert?
> \ bit_insert complex conj
> \ reduc_max reduc_min reduc_plus
> \ dot_prod widen_sum sad fma
> - \ widen_mult widen_mult_plus widen_mult_minus widen_lshift
> + \ widen_mult widen_mult_plus widen_mult_minus
> \ vec_widen_mult_hi vec_widen_mult_lo
> \ vec_widen_mult_even vec_widen_mult_odd
> \ vec_unpack_hi vec_unpack_lo
> \ vec_unpack_float_hi vec_unpack_float_lo
> \ vec_pack_trunc vec_pack_sat vec_pack_fix_trunc
> + \ vec_widen_lshift_even vec_widen_lshift_odd
> \ vec_widen_lshift_hi vec_widen_lshift_lo
> + \ vec_widen_lshift
>
> " Match commutative/single-use specifiers: :C, :c, :s, :cs, etc.
> syn match pdOpSpec ":[CcSs]\+\>"
> diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
> index ceb5064007c..311c0ea2d99 100644
> --- a/gcc/analyzer/region-model.cc
> +++ b/gcc/analyzer/region-model.cc
> @@ -1386,8 +1386,6 @@ region_model::get_gassign_result (const gassign *assign,
> case VEC_PACK_SAT_EXPR:
> case VEC_PACK_FIX_TRUNC_EXPR:
> case VEC_PACK_FLOAT_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> return m_mgr->get_or_create_unknown_svalue (TREE_TYPE (lhs));
> }
> }
> diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc
> index 5c3ba50862e..41e2481f5dc 100644
> --- a/gcc/cfgexpand.cc
> +++ b/gcc/cfgexpand.cc
> @@ -780,7 +780,7 @@ vars_ssa_cache::operator() (tree name)
> create (use);
>
> gimple *g = SSA_NAME_DEF_STMT (use);
> -
> +
> /* CONSTRUCTOR here is always a vector initialization,
> walk each element too. */
> if (gimple_assign_single_p (g)
> @@ -4861,14 +4861,6 @@ expand_debug_expr (tree exp)
> case RSHIFT_EXPR:
> case LROTATE_EXPR:
> case RROTATE_EXPR:
> - case WIDEN_LSHIFT_EXPR:
> - /* Ensure second operand isn't wider than the first one. */
> - inner_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)));
> - if (is_a <scalar_int_mode> (inner_mode, &op1_mode)
> - && (GET_MODE_UNIT_PRECISION (mode)
> - < GET_MODE_PRECISION (op1_mode)))
> - op1 = lowpart_subreg (GET_MODE_INNER (mode), op1, op1_mode);
> - break;
> default:
> break;
> }
> @@ -5768,8 +5760,6 @@ expand_debug_expr (tree exp)
> case VEC_WIDEN_MULT_LO_EXPR:
> case VEC_WIDEN_MULT_EVEN_EXPR:
> case VEC_WIDEN_MULT_ODD_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> case VEC_PERM_EXPR:
> case VEC_DUPLICATE_EXPR:
> case VEC_SERIES_EXPR:
> @@ -5833,7 +5823,6 @@ expand_debug_expr (tree exp)
> return NULL;
>
> case WIDEN_SUM_EXPR:
> - case WIDEN_LSHIFT_EXPR:
> if (SCALAR_INT_MODE_P (GET_MODE (op0))
> && SCALAR_INT_MODE_P (mode))
> {
> @@ -5842,8 +5831,7 @@ expand_debug_expr (tree exp)
> 0)))
> ? ZERO_EXTEND : SIGN_EXTEND, mode, op0,
> inner_mode);
> - return simplify_gen_binary (TREE_CODE (exp) == WIDEN_LSHIFT_EXPR
> - ? ASHIFT : PLUS, mode, op0, op1);
> + return simplify_gen_binary (PLUS, mode, op0, op1);
> }
> return NULL;
>
> diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
> index ae5d709bd47..72cadc6bf2d 100644
> --- a/gcc/doc/md.texi
> +++ b/gcc/doc/md.texi
> @@ -6050,16 +6050,24 @@ or even/odd elements of the two vectors, and put the
> N/2 products of size 2*S
> in the output vector (operand 0). A target shouldn't implement even/odd
> pattern
> pair if it is less efficient than lo/hi one.
>
> +@cindex @code{vec_widen_ushiftl@var{m}} instruction pattern
> +@cindex @code{vec_widen_sshiftl@var{m}} instruction pattern
> @cindex @code{vec_widen_ushiftl_hi_@var{m}} instruction pattern
> @cindex @code{vec_widen_ushiftl_lo_@var{m}} instruction pattern
> @cindex @code{vec_widen_sshiftl_hi_@var{m}} instruction pattern
> @cindex @code{vec_widen_sshiftl_lo_@var{m}} instruction pattern
> +@item @samp{vec_widen_ushiftl_@var{m}}
> +@item @samp{vec_widen_sshiftl_@var{m}}
> @item @samp{vec_widen_ushiftl_hi_@var{m}},
> @samp{vec_widen_ushiftl_lo_@var{m}}
> @itemx @samp{vec_widen_sshiftl_hi_@var{m}},
> @samp{vec_widen_sshiftl_lo_@var{m}}
> +@item @samp{vec_widen_ushiftl_even_@var{m}},
> @samp{vec_widen_ushiftl_off_@var{m}}
> +@itemx @samp{vec_widen_sshiftl_even_@var{m}},
> @samp{vec_widen_sshiftl_off_@var{m}}
> Signed/Unsigned widening shift left. The first input (operand 1) is a vector
> with N signed/unsigned elements of size S@. Operand 2 is a constant. Shift
> -the high/low elements of operand 1, and put the N/2 results of size 2*S in
> the
> -output vector (operand 0).
> +the high/low or even/odd elements of operand 1, and put the N/2 (or N in
> +case of the non hi/lo, even/odd variants) results of size 2*S in the output
> +vector (operand 0). A target shouldn't implement the even/odd pattern pair
> if
> +it is less efficient than the lo/hi one.
>
> @cindex @code{vec_widen_saddl_hi_@var{m}} instruction pattern
> @cindex @code{vec_widen_saddl_lo_@var{m}} instruction pattern
> diff --git a/gcc/expr.cc b/gcc/expr.cc
> index 7d84ad9e6fc..cd280ba3923 100644
> --- a/gcc/expr.cc
> +++ b/gcc/expr.cc
> @@ -11055,8 +11055,6 @@ expand_expr_real_2 (const_sepops ops, rtx target,
> machine_mode tmode,
> case VEC_WIDEN_MULT_LO_EXPR:
> case VEC_WIDEN_MULT_EVEN_EXPR:
> case VEC_WIDEN_MULT_ODD_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
> EXPAND_NORMAL);
> target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
> target, unsignedp);
> diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
> index 6929cd0bca1..ef03026f6ef 100644
> --- a/gcc/gimple-pretty-print.cc
> +++ b/gcc/gimple-pretty-print.cc
> @@ -457,8 +457,6 @@ dump_binary_rhs (pretty_printer *pp, const gassign *gs,
> int spc,
> case VEC_PACK_SAT_EXPR:
> case VEC_PACK_FIX_TRUNC_EXPR:
> case VEC_PACK_FLOAT_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> case VEC_SERIES_EXPR:
> for (p = get_tree_code_name (code); *p; p++)
> pp_character (pp, TOUPPER (*p));
> diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
> index 7874fcfb3df..cd76f9b0d37 100644
> --- a/gcc/internal-fn.def
> +++ b/gcc/internal-fn.def
> @@ -446,6 +446,11 @@ DEF_INTERNAL_WIDENING_OPTAB_FN (VEC_WIDEN_ABD,
> first,
> vec_widen_sabd, vec_widen_uabd,
> binary)
> +DEF_INTERNAL_WIDENING_OPTAB_FN (VEC_WIDEN_LSHIFT,
> + ECF_CONST | ECF_NOTHROW,
> + first,
> + vec_widen_sshiftl, vec_widen_ushiftl,
> + binary)
> DEF_INTERNAL_OPTAB_FN (VEC_FMADDSUB, ECF_CONST, vec_fmaddsub, ternary)
> DEF_INTERNAL_OPTAB_FN (VEC_FMSUBADD, ECF_CONST, vec_fmsubadd, ternary)
>
> diff --git a/gcc/optabs-tree.cc b/gcc/optabs-tree.cc
> index 0de74c7966a..f75d3780138 100644
> --- a/gcc/optabs-tree.cc
> +++ b/gcc/optabs-tree.cc
> @@ -192,14 +192,6 @@ optab_for_tree_code (enum tree_code code, const_tree
> type,
> return (TYPE_UNSIGNED (type)
> ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab);
>
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - return (TYPE_UNSIGNED (type)
> - ? vec_widen_ushiftl_hi_optab : vec_widen_sshiftl_hi_optab);
> -
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> - return (TYPE_UNSIGNED (type)
> - ? vec_widen_ushiftl_lo_optab : vec_widen_sshiftl_lo_optab);
> -
> case VEC_UNPACK_HI_EXPR:
> return (TYPE_UNSIGNED (type)
> ? vec_unpacku_hi_optab : vec_unpacks_hi_optab);
> @@ -305,7 +297,6 @@ optab_for_tree_code (enum tree_code code, const_tree type,
>
> Supported widening operations:
> WIDEN_MULT_EXPR
> - WIDEN_LSHIFT_EXPR
>
> Output:
> - CODE1 - The non-widened code, which will be used after the inputs are
> @@ -332,9 +323,6 @@ supportable_half_widening_operation (enum tree_code code,
> tree vectype_out,
>
> switch (code)
> {
> - case WIDEN_LSHIFT_EXPR:
> - *code1 = LSHIFT_EXPR;
> - break;
> case WIDEN_MULT_EXPR:
> *code1 = MULT_EXPR;
> break;
> diff --git a/gcc/optabs.def b/gcc/optabs.def
> index b6f290a9513..3547425ae53 100644
> --- a/gcc/optabs.def
> +++ b/gcc/optabs.def
> @@ -473,14 +473,20 @@ OPTAB_D (vec_widen_sabd_hi_optab,
> "vec_widen_sabd_hi_$a")
> OPTAB_D (vec_widen_sabd_lo_optab, "vec_widen_sabd_lo_$a")
> OPTAB_D (vec_widen_sabd_odd_optab, "vec_widen_sabd_odd_$a")
> OPTAB_D (vec_widen_sabd_even_optab, "vec_widen_sabd_even_$a")
> +OPTAB_D (vec_widen_sshiftl_optab, "vec_widen_sshiftl_$a")
> OPTAB_D (vec_widen_sshiftl_hi_optab, "vec_widen_sshiftl_hi_$a")
> OPTAB_D (vec_widen_sshiftl_lo_optab, "vec_widen_sshiftl_lo_$a")
> +OPTAB_D (vec_widen_sshiftl_even_optab, "vec_widen_sshiftl_even_$a")
> +OPTAB_D (vec_widen_sshiftl_odd_optab, "vec_widen_sshiftl_odd_$a")
> OPTAB_D (vec_widen_umult_even_optab, "vec_widen_umult_even_$a")
> OPTAB_D (vec_widen_umult_hi_optab, "vec_widen_umult_hi_$a")
> OPTAB_D (vec_widen_umult_lo_optab, "vec_widen_umult_lo_$a")
> OPTAB_D (vec_widen_umult_odd_optab, "vec_widen_umult_odd_$a")
> +OPTAB_D (vec_widen_ushiftl_optab, "vec_widen_ushiftl_$a")
> OPTAB_D (vec_widen_ushiftl_hi_optab, "vec_widen_ushiftl_hi_$a")
> OPTAB_D (vec_widen_ushiftl_lo_optab, "vec_widen_ushiftl_lo_$a")
> +OPTAB_D (vec_widen_ushiftl_even_optab, "vec_widen_ushiftl_even_$a")
> +OPTAB_D (vec_widen_ushiftl_odd_optab, "vec_widen_ushiftl_odd_$a")
> OPTAB_D (vec_widen_usub_optab, "vec_widen_usub_$a")
> OPTAB_D (vec_widen_usub_hi_optab, "vec_widen_usub_hi_$a")
> OPTAB_D (vec_widen_usub_lo_optab, "vec_widen_usub_lo_$a")
> diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
> index 62513045c6f..fc1680f3215 100644
> --- a/gcc/tree-cfg.cc
> +++ b/gcc/tree-cfg.cc
> @@ -3898,44 +3898,6 @@ verify_gimple_assign_binary (gassign *stmt)
> return false;
> }
>
> - case WIDEN_LSHIFT_EXPR:
> - {
> - if (!INTEGRAL_TYPE_P (lhs_type)
> - || !INTEGRAL_TYPE_P (rhs1_type)
> - || TREE_CODE (rhs2) != INTEGER_CST
> - || (2 * TYPE_PRECISION (rhs1_type) > TYPE_PRECISION (lhs_type)))
> - {
> - error ("type mismatch in %qs", code_name);
> - debug_generic_expr (lhs_type);
> - debug_generic_expr (rhs1_type);
> - debug_generic_expr (rhs2_type);
> - return true;
> - }
> -
> - return false;
> - }
> -
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> - {
> - if (TREE_CODE (rhs1_type) != VECTOR_TYPE
> - || TREE_CODE (lhs_type) != VECTOR_TYPE
> - || !INTEGRAL_TYPE_P (TREE_TYPE (rhs1_type))
> - || !INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))
> - || TREE_CODE (rhs2) != INTEGER_CST
> - || (2 * TYPE_PRECISION (TREE_TYPE (rhs1_type))
> - > TYPE_PRECISION (TREE_TYPE (lhs_type))))
> - {
> - error ("type mismatch in %qs", code_name);
> - debug_generic_expr (lhs_type);
> - debug_generic_expr (rhs1_type);
> - debug_generic_expr (rhs2_type);
> - return true;
> - }
> -
> - return false;
> - }
> -
> case PLUS_EXPR:
> case MINUS_EXPR:
> {
> diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
> index 7fecf487af7..2c8057537bc 100644
> --- a/gcc/tree-inline.cc
> +++ b/gcc/tree-inline.cc
> @@ -4382,7 +4382,6 @@ estimate_operator_cost (enum tree_code code,
> eni_weights *weights,
> case SAD_EXPR:
> case WIDEN_MULT_PLUS_EXPR:
> case WIDEN_MULT_MINUS_EXPR:
> - case WIDEN_LSHIFT_EXPR:
>
> case VEC_WIDEN_MULT_HI_EXPR:
> case VEC_WIDEN_MULT_LO_EXPR:
> @@ -4398,8 +4397,6 @@ estimate_operator_cost (enum tree_code code,
> eni_weights *weights,
> case VEC_PACK_SAT_EXPR:
> case VEC_PACK_FIX_TRUNC_EXPR:
> case VEC_PACK_FLOAT_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> case VEC_DUPLICATE_EXPR:
> case VEC_SERIES_EXPR:
>
> diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
> index c19babadead..edaab2ba132 100644
> --- a/gcc/tree-pretty-print.cc
> +++ b/gcc/tree-pretty-print.cc
> @@ -3290,7 +3290,6 @@ dump_generic_node (pretty_printer *pp, tree node, int
> spc, dump_flags_t flags,
> case RSHIFT_EXPR:
> case LROTATE_EXPR:
> case RROTATE_EXPR:
> - case WIDEN_LSHIFT_EXPR:
> case BIT_IOR_EXPR:
> case BIT_XOR_EXPR:
> case BIT_AND_EXPR:
> @@ -4349,17 +4348,6 @@ dump_generic_node (pretty_printer *pp, tree node, int
> spc, dump_flags_t flags,
> case VEC_WIDEN_MULT_LO_EXPR:
> case VEC_WIDEN_MULT_EVEN_EXPR:
> case VEC_WIDEN_MULT_ODD_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> - pp_space (pp);
> - for (str = get_tree_code_name (code); *str; str++)
> - pp_character (pp, TOUPPER (*str));
> - pp_string (pp, " < ");
> - dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
> - pp_string (pp, ", ");
> - dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
> - pp_string (pp, " > ");
> - break;
>
> case VEC_DUPLICATE_EXPR:
> pp_space (pp);
> @@ -4691,9 +4679,6 @@ op_code_prio (enum tree_code code)
> case RSHIFT_EXPR:
> case LROTATE_EXPR:
> case RROTATE_EXPR:
> - case VEC_WIDEN_LSHIFT_HI_EXPR:
> - case VEC_WIDEN_LSHIFT_LO_EXPR:
> - case WIDEN_LSHIFT_EXPR:
> return 11;
>
> case WIDEN_SUM_EXPR:
> @@ -4861,9 +4846,6 @@ op_symbol_code (enum tree_code code, dump_flags_t flags)
> case RROTATE_EXPR:
> return (flags & TDF_GIMPLE) ? "__ROTATE_RIGHT" : "r>>";
>
> - case WIDEN_LSHIFT_EXPR:
> - return "w<<";
> -
> case POINTER_PLUS_EXPR:
> return "+";
>
> diff --git a/gcc/tree-ssa-loop-im.cc b/gcc/tree-ssa-loop-im.cc
> index 0340857058b..0d2c5763e3c 100644
> --- a/gcc/tree-ssa-loop-im.cc
> +++ b/gcc/tree-ssa-loop-im.cc
> @@ -662,7 +662,6 @@ stmt_cost (gimple *stmt)
>
> case LSHIFT_EXPR:
> case RSHIFT_EXPR:
> - case WIDEN_LSHIFT_EXPR:
> case LROTATE_EXPR:
> case RROTATE_EXPR:
> /* Shifts and rotates are usually expensive. */
> diff --git a/gcc/tree-vect-data-refs.cc b/gcc/tree-vect-data-refs.cc
> index c7941108887..e3b5a077dc4 100644
> --- a/gcc/tree-vect-data-refs.cc
> +++ b/gcc/tree-vect-data-refs.cc
> @@ -180,7 +180,6 @@ vect_get_smallest_scalar_type (stmt_vec_info stmt_info,
> tree scalar_type)
> || gimple_assign_rhs_code (assign) == WIDEN_MULT_EXPR
> || gimple_assign_rhs_code (assign) == WIDEN_MULT_PLUS_EXPR
> || gimple_assign_rhs_code (assign) == WIDEN_MULT_MINUS_EXPR
> - || gimple_assign_rhs_code (assign) == WIDEN_LSHIFT_EXPR
> || gimple_assign_rhs_code (assign) == FLOAT_EXPR)
> {
> tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (assign));
> diff --git a/gcc/tree-vect-generic.cc b/gcc/tree-vect-generic.cc
> index b8e6a7168ff..0e867293bd0 100644
> --- a/gcc/tree-vect-generic.cc
> +++ b/gcc/tree-vect-generic.cc
> @@ -2159,9 +2159,7 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
> || code == VEC_UNPACK_FIX_TRUNC_LO_EXPR
> || code == VEC_PACK_TRUNC_EXPR
> || code == VEC_PACK_SAT_EXPR
> - || code == VEC_PACK_FIX_TRUNC_EXPR
> - || code == VEC_WIDEN_LSHIFT_HI_EXPR
> - || code == VEC_WIDEN_LSHIFT_LO_EXPR)
> + || code == VEC_PACK_FIX_TRUNC_EXPR)
> {
> /* We do not know how to scalarize those. */
> return;
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index 878a045c436..9efb6e8f954 100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -3671,14 +3671,14 @@ vect_recog_cast_forwprop_pattern (vec_info *vinfo,
> }
>
> /* Try to detect a shift left of a widened input, converting LSHIFT_EXPR
> - to WIDEN_LSHIFT_EXPR. See vect_recog_widen_op_pattern for details. */
> + to IFN_VEC_WIDEN_LSHIFT. See vect_recog_widen_op_pattern for details. */
>
> static gimple *
> vect_recog_widen_shift_pattern (vec_info *vinfo,
> stmt_vec_info last_stmt_info, tree *type_out)
> {
> return vect_recog_widen_op_pattern (vinfo, last_stmt_info, type_out,
> - LSHIFT_EXPR, WIDEN_LSHIFT_EXPR, true,
> + LSHIFT_EXPR, IFN_VEC_WIDEN_LSHIFT, true,
> "vect_recog_widen_shift_pattern");
> }
>
> diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc
> index aa6c3e2e041..a7e1d63b586 100644
> --- a/gcc/tree-vect-slp.cc
> +++ b/gcc/tree-vect-slp.cc
> @@ -1307,11 +1307,6 @@ vect_build_slp_tree_1 (vec_info *vinfo, unsigned char
> *swap,
> first_op1 = gimple_assign_rhs2 (stmt);
> }
> }
> - else if (rhs_code == WIDEN_LSHIFT_EXPR)
> - {
> - need_same_oprnds = true;
> - first_op1 = gimple_assign_rhs2 (stmt);
> - }
> else if (!ldst_p
> && rhs_code == BIT_FIELD_REF)
> {
> diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
> index 83acbb3ff67..29817fa4bbd 100644
> --- a/gcc/tree-vect-stmts.cc
> +++ b/gcc/tree-vect-stmts.cc
> @@ -5248,8 +5248,7 @@ vectorizable_conversion (vec_info *vinfo,
> return false;
>
> bool widen_arith = (code == WIDEN_MULT_EXPR
> - || code == WIDEN_LSHIFT_EXPR
> - || widening_fn_p (code));
> + || widening_fn_p (code));
>
> if (!widen_arith
> && !CONVERT_EXPR_CODE_P (code)
> @@ -5297,7 +5296,6 @@ vectorizable_conversion (vec_info *vinfo,
> if (op_type == binary_op)
> {
> gcc_assert (code == WIDEN_MULT_EXPR
> - || code == WIDEN_LSHIFT_EXPR
> || widening_fn_p (code));
>
> op1 = is_gimple_assign (stmt) ? gimple_assign_rhs2 (stmt) :
> @@ -5685,15 +5683,7 @@ vectorizable_conversion (vec_info *vinfo,
> generate more than one vector stmt - i.e - we need to "unroll"
> the vector stmt by a factor VF/nunits. */
> vect_get_vec_defs (vinfo, slp_node, op0, &vec_oprnds0,
> - code == WIDEN_LSHIFT_EXPR ? NULL_TREE : op1,
> - &vec_oprnds1);
> - if (code == WIDEN_LSHIFT_EXPR)
> - {
> - int oprnds_size = vec_oprnds0.length ();
> - vec_oprnds1.create (oprnds_size);
> - for (i = 0; i < oprnds_size; ++i)
> - vec_oprnds1.quick_push (op1);
> - }
> + op1, &vec_oprnds1);
> /* Arguments are ready. Create the new vector stmts. */
> for (i = multi_step_cvt; i >= 0; i--)
> {
> @@ -13685,11 +13675,6 @@ supportable_widening_operation (vec_info *vinfo,
> c2 = VEC_WIDEN_MULT_ODD_EXPR;
> break;
>
> - case WIDEN_LSHIFT_EXPR:
> - c1 = VEC_WIDEN_LSHIFT_LO_EXPR;
> - c2 = VEC_WIDEN_LSHIFT_HI_EXPR;
> - break;
> -
> CASE_CONVERT:
> c1 = VEC_UNPACK_LO_EXPR;
> c2 = VEC_UNPACK_HI_EXPR;
> diff --git a/gcc/tree.def b/gcc/tree.def
> index 0cd39f95b0b..f9433a2d8b5 100644
> --- a/gcc/tree.def
> +++ b/gcc/tree.def
> @@ -1514,19 +1514,6 @@ DEFTREECODE (WIDEN_MULT_PLUS_EXPR,
> "widen_mult_plus_expr", tcc_expression, 3)
> is subtracted from t3. */
> DEFTREECODE (WIDEN_MULT_MINUS_EXPR, "widen_mult_minus_expr", tcc_expression,
> 3)
>
> -/* Widening shift left.
> - The first operand is of type t1.
> - The second operand is the number of bits to shift by; it need not be the
> - same type as the first operand and result.
> - Note that the result is undefined if the second operand is larger
> - than or equal to the first operand's type size.
> - The type of the entire expression is t2, such that t2 is at least twice
> - the size of t1.
> - WIDEN_LSHIFT_EXPR is equivalent to first widening (promoting)
> - the first argument from type t1 to type t2, and then shifting it
> - by the second argument. */
> -DEFTREECODE (WIDEN_LSHIFT_EXPR, "widen_lshift_expr", tcc_binary, 2)
> -
> /* Widening vector multiplication.
> The two operands are vectors with N elements of size S. Multiplying the
> elements of the two vectors will result in N products of size 2*S.
> @@ -1581,16 +1568,6 @@ DEFTREECODE (VEC_PACK_FIX_TRUNC_EXPR,
> "vec_pack_fix_trunc_expr", tcc_binary, 2)
> the output vector. */
> DEFTREECODE (VEC_PACK_FLOAT_EXPR, "vec_pack_float_expr", tcc_binary, 2)
>
> -/* Widening vector shift left in bits.
> - Operand 0 is a vector to be shifted with N elements of size S.
> - Operand 1 is an integer shift amount in bits.
> - The result of the operation is N elements of size 2*S.
> - VEC_WIDEN_LSHIFT_HI_EXPR computes the N/2 high results.
> - VEC_WIDEN_LSHIFT_LO_EXPR computes the N/2 low results.
> - */
> -DEFTREECODE (VEC_WIDEN_LSHIFT_HI_EXPR, "widen_lshift_hi_expr", tcc_binary, 2)
> -DEFTREECODE (VEC_WIDEN_LSHIFT_LO_EXPR, "widen_lshift_lo_expr", tcc_binary, 2)
> -
> /* PREDICT_EXPR. Specify hint for branch prediction. The
> PREDICT_EXPR_PREDICTOR specify predictor and PREDICT_EXPR_OUTCOME the
> outcome (0 for not taken and 1 for taken). Once the profile is guessed
> --
> 2.51.0
>
>