On Thu, 20 Nov 2025, Tamar Christina wrote:
> This adds a new target hook to gimple-sel to allow targets to
> do target specific massaging of the gimple IL to prepare for
> expand.
>
> Tejas will be sending up part 2 of this soon to help convert
> SVE packed boolean VEC_COND_EXPR into something that we can
> handle more efficiently if expanded in a different order.
>
> We also want to use this to e.g. for Adv. SIMD prefer avoiding
> != vector compare expressions because the ISA doesn't have
> this instruction and so we expand to == + ~ but changing the
> expression from a MIN to MAX only for VECTOR_BOOLEAN_TYPE_P
> and flipping the operands we can expand more efficient.
>
> These are the kind of things we want to use the hook for,
> not generic changes that apply to all target.
>
> Bootstrapped Regtested on aarch64-none-linux-gnu and no issues.
>
> Ok for master pending submission of Tejas' patch?
OK.
> Thanks,
> Tamar
>
> gcc/ChangeLog:
>
> * target.def (instruction_selection): New.
> * doc/tm.texi.in: Document it.
> * doc/tm.texi: Regenerate
> * gimple-isel.cc (pass_gimple_isel::execute): Use it.
> * targhooks.cc (default_instruction_selection): New.
> * targhooks.h (default_instruction_selection): New.
>
> ---
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index
> fd208f53844a157721dd8a0282f283da64cf5d93..25aad2eb74b6c3bedb5d527c6bfe216347d48a01
> 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -6628,6 +6628,20 @@ like @code{cond_add@var{m}}. The default
> implementation returns a zero
> constant of type @var{type}.
> @end deftypefn
>
> +@deftypefn {Target Hook} bool TARGET_INSTRUCTION_SELECTION (function
> *@var{fun}, gimple_stmt_iterator *@var{gsi})
> +This hook allows a target to perform custom instruction selection for an
> +instruction or sequence of instructions before expand to allow expansion to
> +generate more efficient code.
> +
> +@var{fun} is the current function being considered and @var{gsi} is the
> +iterator pointing to the current instruction being optimized. The default
> +implementation does not do any rewriting and returns false. The result of
> +the function should be whether any changes were made to the CFG or not. If a
> +change was made then the @var{gsi} should be left at the same position as at
> +the function start. The caller is allowed to change the CFG at any point
> +before the current statement @var{gsi} is pointing to but not afterwards.
> +@end deftypefn
> +
> @deftypefn {Target Hook} tree TARGET_GOACC_ADJUST_PRIVATE_DECL (location_t
> @var{loc}, tree @var{var}, int @var{level})
> This hook, if defined, is used by accelerator target back-ends to adjust
> OpenACC variable declarations that should be made private to the given
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index
> 14315dd508051037b7936c89638c05f07b6d3d6f..24d47b19e5f13e15f9d0b0e9c0b343825ce6e761
> 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -4352,6 +4352,8 @@ address; but often a machine-dependent strategy can
> generate better code.
>
> @hook TARGET_PREFERRED_ELSE_VALUE
>
> +@hook TARGET_INSTRUCTION_SELECTION
> +
> @hook TARGET_GOACC_ADJUST_PRIVATE_DECL
>
> @hook TARGET_GOACC_EXPAND_VAR_DECL
> diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
> index
> e745608904e3db77a88d861bc6512afe67a82480..269151ac21dd05bfb0dc16529e54521d32703a9f
> 100644
> --- a/gcc/gimple-isel.cc
> +++ b/gcc/gimple-isel.cc
> @@ -1357,6 +1357,9 @@ pass_gimple_isel::execute (struct function *fun)
> {
> for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
> {
> + /* Give the target first try at replacing the instruction. */
> + cfg_changed |= targetm.instruction_selection (fun, &gsi);
> +
> /* Pre-expand VEC_COND_EXPRs to .VCOND* internal function
> calls mapping to supported optabs. */
> gimple *g = gimple_expand_vec_cond_expr (&gsi);
> diff --git a/gcc/target.def b/gcc/target.def
> index
> f288329ffcab81e2773c2066e60a470611f29e23..61931278fd936eae8ae16aee772ace409144d22f
> 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -2137,6 +2137,23 @@ constant of type @var{type}.",
> (unsigned ifn, tree type, unsigned nops, tree *ops),
> default_preferred_else_value)
>
> +DEFHOOK
> +(instruction_selection,
> + "This hook allows a target to perform custom instruction selection for an\n\
> +instruction or sequence of instructions before expand to allow expansion
> to\n\
> +generate more efficient code.\n\
> +\n\
> +@var{fun} is the current function being considered and @var{gsi} is the\n\
> +iterator pointing to the current instruction being optimized. The default\n\
> +implementation does not do any rewriting and returns false. The result of\n\
> +the function should be whether any changes were made to the CFG or not. If
> a\n\
> +change was made then the @var{gsi} should be left at the same position as
> at\n\
> +the function start. The caller is allowed to change the CFG at any point\n\
> +before the current statement @var{gsi} is pointing to but not afterwards.",
> + bool,
> + (function *fun, gimple_stmt_iterator *gsi),
> + default_instruction_selection)
> +
> DEFHOOK
> (record_offload_symbol,
> "Used when offloaded functions are seen in the compilation unit and no
> named\n\
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index
> 1873d572ba3fb59c4713e10b5c5b14afb029b953..ab398673b4763e9d062f565d73732f38e60619c0
> 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -2764,6 +2764,14 @@ default_preferred_else_value (unsigned, tree type,
> unsigned, tree *)
> return build_zero_cst (type);
> }
>
> +/* The default implementation of TARGET_INSTRUCTION_SELECTION. */
> +
> +bool
> +default_instruction_selection (function *, gimple_stmt_iterator *)
> +{
> + return false;
> +}
> +
> /* Default implementation of TARGET_HAVE_SPECULATION_SAFE_VALUE. */
> bool
> default_have_speculation_safe_value (bool active ATTRIBUTE_UNUSED)
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index
> 92e7a4cb10f109978301d8c10f69b4c5a3952f56..01d4fc7a4508da2fa138bd135406656bd72ab2cf
> 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -305,7 +305,7 @@ extern machine_mode default_mode_for_floating_type (enum
> tree_index);
> extern HOST_WIDE_INT default_stack_clash_protection_alloca_probe_range
> (void);
> extern void default_select_early_remat_modes (sbitmap);
> extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *);
> -
> +extern bool default_instruction_selection (function *, gimple_stmt_iterator
> *);
> extern bool default_have_speculation_safe_value (bool);
> extern bool speculation_safe_value_not_needed (bool);
> extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx);
>
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)