On Tue, Sep 22, 2026 at 12:33 PM Dominic P <[email protected]> wrote:
>
> A STRICT_ALIGNMENT target that provides movmisalign<m> is saying only that it
> can perform the access, not that doing so is worth it: alpha's expands to the
> ldq_u/insxh/mskxl sequence, arm's to a single unaligned ldr or str.
> TARGET_SLOW_UNALIGNED_ACCESS cannot express the difference, because it is
> documented to return true whenever STRICT_ALIGNMENT is true and its two dozen
> callers read it as "act as if STRICT_ALIGNMENT".  Add a hook for just that
> question.  Its default is false on every STRICT_ALIGNMENT target, and it has
> no callers yet, so this patch changes no generated code on any target.

I think we should cleanup the two hooks before adding a new one.

>
> Assisted-by: Claude Opus 5 (Anthropic)
> Signed-off-by: Dominic P <[email protected]>
>
> gcc/ChangeLog:
>
>         * target.def (misaligned_access_cheap_p): New hook.
>         * doc/tm.texi.in (TARGET_MISALIGNED_ACCESS_CHEAP_P): Document it.
>         * doc/tm.texi: Regenerate.
>         * targhooks.h (default_misaligned_access_cheap_p): Declare.
>         * targhooks.cc (default_misaligned_access_cheap_p): New function.
> ---
>  gcc/doc/tm.texi    | 19 +++++++++++++++++++
>  gcc/doc/tm.texi.in |  2 ++
>  gcc/target.def     | 21 +++++++++++++++++++++
>  gcc/targhooks.cc   |  9 +++++++++
>  gcc/targhooks.h    |  1 +
>  5 files changed, 52 insertions(+)
>
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index ca68bdc3e61..d3847e739b5 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -7184,6 +7184,25 @@ The hook must return true whenever 
> @code{STRICT_ALIGNMENT} is true.
>  The default implementation returns @code{STRICT_ALIGNMENT}.
>  @end deftypefn
>
> +@deftypefn {Target Hook} bool TARGET_MISALIGNED_ACCESS_CHEAP_P (machine_mode 
> @var{mode}, unsigned int @var{align})
> +This hook returns true if a single memory access of @var{mode} at
> +@var{align} bits of alignment costs no more than the sequence of naturally
> +aligned accesses that would otherwise be needed to cover it, so that a
> +@code{STRICT_ALIGNMENT} target may still be given the wider access.  It is
> +invoked only for unaligned accesses, i.e.@: when
> +@code{@var{align} < GET_MODE_ALIGNMENT (@var{mode})}.
> +
> +Unlike @code{TARGET_SLOW_UNALIGNED_ACCESS}, which must return true whenever
> +@code{STRICT_ALIGNMENT} is true, this hook lets a target that implements
> +@code{movmisalign@var{m}} with a single instruction say so.  A target whose
> +@code{movmisalign@var{m}} is a multi-instruction sequence must leave it
> +false.
> +
> +The default implementation returns true if @code{movmisalign@var{m}} exists
> +for @var{mode} and @code{TARGET_SLOW_UNALIGNED_ACCESS} is false, which is
> +never the case on a @code{STRICT_ALIGNMENT} target.
> +@end deftypefn
> +
>  @defmac MOVE_RATIO (@var{speed})
>  The threshold of number of scalar memory-to-memory move insns, @emph{below}
>  which a sequence of insns should be generated instead of a
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 532e95ef216..039a520ad5b 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -4660,6 +4660,8 @@ other fields in the same word of the structure, but to 
> different bytes.
>
>  @hook TARGET_SLOW_UNALIGNED_ACCESS
>
> +@hook TARGET_MISALIGNED_ACCESS_CHEAP_P
> +
>  @defmac MOVE_RATIO (@var{speed})
>  The threshold of number of scalar memory-to-memory move insns, @emph{below}
>  which a sequence of insns should be generated instead of a
> diff --git a/gcc/target.def b/gcc/target.def
> index 66c20a9c9d2..1e12e0e98b1 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -4008,6 +4008,27 @@ The default implementation returns 
> @code{STRICT_ALIGNMENT}.",
>   bool, (machine_mode mode, unsigned int align),
>   default_slow_unaligned_access)
>
> +DEFHOOK
> +(misaligned_access_cheap_p,
> + "This hook returns true if a single memory access of @var{mode} at\n\
> +@var{align} bits of alignment costs no more than the sequence of naturally\n\
> +aligned accesses that would otherwise be needed to cover it, so that a\n\
> +@code{STRICT_ALIGNMENT} target may still be given the wider access.  It is\n\
> +invoked only for unaligned accesses, i.e.@: when\n\
> +@code{@var{align} < GET_MODE_ALIGNMENT (@var{mode})}.\n\
> +\n\
> +Unlike @code{TARGET_SLOW_UNALIGNED_ACCESS}, which must return true 
> whenever\n\
> +@code{STRICT_ALIGNMENT} is true, this hook lets a target that implements\n\
> +@code{movmisalign@var{m}} with a single instruction say so.  A target 
> whose\n\
> +@code{movmisalign@var{m}} is a multi-instruction sequence must leave it\n\
> +false.\n\
> +\n\
> +The default implementation returns true if @code{movmisalign@var{m}} 
> exists\n\
> +for @var{mode} and @code{TARGET_SLOW_UNALIGNED_ACCESS} is false, which is\n\
> +never the case on a @code{STRICT_ALIGNMENT} target.",
> + bool, (machine_mode mode, unsigned int align),
> + default_misaligned_access_cheap_p)
> +
>  DEFHOOK
>  (optab_supported_p,
>   "Return true if the optimizers should use optab @var{op} with\n\
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index 388f696c8aa..0f5562fba59 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -2156,6 +2156,15 @@ default_slow_unaligned_access (machine_mode, unsigned 
> int)
>    return STRICT_ALIGNMENT;
>  }
>
> +/* The default implementation of TARGET_MISALIGNED_ACCESS_CHEAP_P.  */
> +
> +bool
> +default_misaligned_access_cheap_p (machine_mode mode, unsigned int align)
> +{
> +  return (optab_handler (movmisalign_optab, mode) != CODE_FOR_nothing
> +         && !targetm.slow_unaligned_access (mode, align));
> +}
> +
>  /* The default implementation of TARGET_ESTIMATED_POLY_VALUE.  */
>
>  HOST_WIDE_INT
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index 86de6ef8a69..d9bda73c34a 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -244,6 +244,7 @@ extern int default_callee_save_cost (spill_cost_type, 
> unsigned int,
>  extern int default_frame_allocation_cost (frame_cost_type,
>                                           const HARD_REG_SET &);
>  extern bool default_slow_unaligned_access (machine_mode, unsigned int);
> +extern bool default_misaligned_access_cheap_p (machine_mode, unsigned int);
>  extern HOST_WIDE_INT default_estimated_poly_value (poly_int64,
>                                                    poly_value_estimate_kind);
>
> --
> 2.55.0
>

Reply via email to