On Tue, 22 Sep 2026, Andrea Pinski wrote: > 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.
Agreed. 'STRICT_ALIGNMENT' should go away as it is not mode specific. TARGET_SLOW_UNALIGNED_ACCESS, when true, says move patterns only accept aligned operands. When movmisalign is present for a mode that means it can be used to more efficiently move to/from such slots than using standard bitfield extractions. So the target hook is misnamed IMO, it should be a mode/alignment specific TARGET_STRICT_ALIGNMENT. Targets should not provide a "very slow" movmisalign IMO, but for all else, like for the purpose of store merging, a general "movmisalign is slow" is probably not the best tool but a specific query for the transform at hand. Richard. > > > > 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 > > > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Stefan Gaiser, Jochen Jaser, Abhinav Puri; (HRB 36809, AG Nuernberg)
