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 >
