On Mon, 26 Jan 2026, Richard Biener wrote:

> On Mon, 26 Jan 2026, Pengfei Li wrote:
> 
> > PR123447 reports an ICE on AArch64 with "-O2 -mstrict-align" in subreg
> > lowering when decomposing the following multiword store RTL:
> > 
> > (insn 12 11 13 2 (set (mem/c:XI (plus:DI (reg/f:DI 64 sfp)
> >                 (const_int -96 [0xffffffffffffffa0])) [0  S64 A8])
> >         (reg:XI 103)) "a.c":14:6 4861 {*aarch64_movxi}
> > 
> > This RTL originates from expanding the following GIMPLE statement:
> > 
> > _1 = BIT_FIELD_REF <{ 9, -64497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
> > }, 256, 0>;
> > 
> > The operand is a constant _Decimal64 vector with BLKmode, so expand has
> > to materialize it in memory. The stack slot alignment is chosen via
> > get_object_alignment(), which historically only treated STRING_CST as a
> > possible unwrapped constant object (i.e. not under a CONST_DECL). As a
> > result, a VECTOR_CST falls back to 1-byte alignment, as indicated by A8
> > in the RTL dump above.
> > 
> > Later, subreg lowering attempts to decompose the RTL into DImode pieces.
> > With "-mstrict-align" enabled, simplify_gen_subreg() fails to construct
> > a valid subreg RTX for the pieces because the alignment is too small.
> > This eventually triggers an assertion failure.
> > 
> > This patch handles VECTOR_CST like STRING_CST in get_object_alignment(),
> > so that a reasonable alignment is derived from the vector constant's
> > type or its explicit alignment attribute.
> > 
> > Bootstrapped and tested on aarch64-linux-gnu and x86_64-linux-gnu.
> 
> I don't think this is correct.  Instead the use in the expander
> should be adjusted as I wrote in the bugreport.  At least I do not see
> that there's a guaranteee that the VECTOR_CST ends up in type aligned
> memory if it is not asscoiated with an actual data object (STRING_CST
> is indeed special here).

That said, get_object_alignment will return the maximum _guaranteed_
alignment of an access.  The RTL expansion case needs to honor that,
but as 1 byte is always a correct answer here, for STRICT_ALIGNMENT
targets we probably need to to a MAX (GET_MODE_ALIGNMENT, ...) on it,
or if BLKmode we might want to do MAX (TYPE_ALIGN, ...) on it.  Possibly
that optional alignment need to be capped by max-stack alignment that
can be used.

Richard.


> Richard.
> 
> > gcc/ChangeLog:
> > 
> >     PR middle-end/123447
> >     * builtins.cc (get_object_alignment_2): Handle VECTOR_CST like
> >     STRING_CST.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     PR middle-end/123447
> >     * gcc.dg/pr123447.c: New test.
> > ---
> >  gcc/builtins.cc                 |  8 +++++---
> >  gcc/testsuite/gcc.dg/pr123447.c | 19 +++++++++++++++++++
> >  2 files changed, 24 insertions(+), 3 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/pr123447.c
> > 
> > diff --git a/gcc/builtins.cc b/gcc/builtins.cc
> > index 28454c53777..9c39d0c5ee4 100644
> > --- a/gcc/builtins.cc
> > +++ b/gcc/builtins.cc
> > @@ -340,10 +340,12 @@ get_object_alignment_2 (tree exp, unsigned int 
> > *alignp,
> >         bitpos += mem_ref_offset (exp).force_shwi () * BITS_PER_UNIT;
> >     }
> >      }
> > -  else if (TREE_CODE (exp) == STRING_CST)
> > +  else if (TREE_CODE (exp) == STRING_CST
> > +      || TREE_CODE (exp) == VECTOR_CST)
> >      {
> > -      /* STRING_CST are the only constant objects we allow to be not
> > -         wrapped inside a CONST_DECL.  */
> > +      /* STRING_CST is a common constant object that appears unwrapped (not
> > +    under a CONST_DECL).  VECTOR_CST can appear unwrapped in some cases
> > +    (see PR123447).  */
> >        align = TYPE_ALIGN (TREE_TYPE (exp));
> >        if (CONSTANT_CLASS_P (exp))
> >     align = targetm.constant_alignment (exp, align);
> > diff --git a/gcc/testsuite/gcc.dg/pr123447.c 
> > b/gcc/testsuite/gcc.dg/pr123447.c
> > new file mode 100644
> > index 00000000000..b2ee1473758
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr123447.c
> > @@ -0,0 +1,19 @@
> > +/* PR middle-end/123447 */
> > +/* { dg-do compile { target aarch64*-*-* } } */
> > +/* { dg-options "-O2 -mstrict-align" } */
> > +
> > +typedef __attribute__((__vector_size__(32))) _Decimal64 D;
> > +typedef __attribute__((__vector_size__(64))) int V;
> > +typedef __attribute__((__vector_size__(64))) _Decimal64 D64;
> > +
> > +D d;
> > +
> > +void foo1 () {
> > +  D _4;
> > +  D64 _5;
> > +  V _1;
> > +  _1 = (V) { 9, -64497, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
> > +  _5 = (D64) _1;
> > +  _4 = __builtin_shufflevector (_5, _5, 0, 1, 2, 3);
> > +  d = _4;
> > +}
> > 
> 
> 

-- 
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)

Reply via email to