Hans-Peter Nilsson wrote:
> > From: Richard Earnshaw <rearn...@arm.com>
> > Date: Mon, 11 Jun 2012 15:16:50 +0200
> 
> > The ARM ABI states that vectors larger than 64 bits in size still have
> > 64-bit alignment; never-the-less, the HW supports alignment hints of up
> > to 128-bits in some cases and will trap in a vector has an alignment
> > that less than the hint.  GCC currently hard-codes larger vectors to be
> > aligned by the size of the vector, which means that 128-bit vectors are
> > marked as being 128-bit aligned.
> > 
> > The ARM ABI unfortunately does not support generating such alignment for
> > parameters passed by value and this can lead to traps at run time.  It
> > seems that the best way to solve this problem is to allow the back-end
> > to set an upper limit on the alignment permitted for a vector.
> 
> Don't you mean lowering the limit on the alignment required and
> guaranteed for a vector?  (Or else it sounds like you want to
> force attribute-aligned to refuse higher values.)
> 
> Wouldn't it be better to make the */*modes.def ADJUST_ALIGNMENT
> macro actually work?  Does it work for you?  The epiphany port
> tries to do it that way (optionally, not the default AFAICT),
> but I bet it's actually unsuccessful.

I've started looking into that as well now.  Actually, there's two
different issues: the alignment of vector *modes*, and the alignment
of vector *types*.

As to vector modes, they default to natural alignment, which can be
overridden via ADJUST_ALIGNMENT.  In either case, it is then capped
by BIGGEST_ALIGNMENT.  (Note that this means e.g. on ARM, 16-byte
vector *modes* are already effectively not naturally aligned, since
BIGGEST_ALIGNMENT is set to 64.)

A different issue is the alignment of vector *types*.  While usually
scalar types inherit their alignment from the underlying machine mode
used to implement the type, this is deliberately not done for vector
types (see layout_type).  The reason for that is sometimes, there may
be an underlying machine mode to represent a vector types, and at
other times (maybe just because of a different -march setting), there
may *not* be such an underlying machine mode.  Since it would be a
bad idea to have vector type alignment (an ABI property!) depend on
-march flags, layout_type instead hard-codes natural alignment for
all vector types.

> > I've implemented this as a separate hook, rather than using the existing
> > hooks because there's a strong likelihood of breaking some existing ABIs
> > if I did it another way.
> > 
> > There are a couple of tests that will need some re-working before this
> > can be committed to deal with the fall-out of making this change; I'll
> > prepare those changes if this patch is deemed generally acceptable.

That hook changes the alignment requirement for vector types.  However,
those will still be *increased* in finalize_type_size to the alignment
of an underlying vector mode (if any), if that is greater.

Fortunately, this does not occur in the ARM case since vector mode
alignment is bounded by BIGGEST_ALIGNMENT, and the ARM implementation
of the new hook never returns anything smaller.  However, for the
general case this would re-introduce the possibility that vector
type alignment differs based on the presence or absence of vector
modes.

Maybe we need to -in addition- refuse to use a vector mode if it has
a bigger alignment requirement than the vector type alignment
determined by the hook?  Something along the lines of what is done
in compute_record_mode:

  /* If structure's known alignment is less than what the scalar
     mode would need, and it matters, then stick with BLKmode.  */
  if (TYPE_MODE (type) != BLKmode
      && STRICT_ALIGNMENT
      && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
            || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (TYPE_MODE (type))))
    {
      /* If this is the only reason this type is BLKmode, then
         don't force containing types to be BLKmode.  */
      TYPE_NO_FORCE_BLK (type) = 1;
      SET_TYPE_MODE (type, BLKmode);
    }

[ If a target still wants vector modes to be used, it needs to *also*
reduce their alignment requirements via ADJUST_ALIGNMENT. ]


> It'd be nice to have non-naturally-aligned vectors working in
> general.
> 
> I have a MIPS COP2 128-bit-SIMD implementation for 32-bit MIPS,
> which means 64-bit stack-alignment and memory loads and stores
> are in 64-bit parts.  So, I've chosen to not require any larger
> alignment to keep ABI compatibility (vectors aren't passed in
> registers; core use is intra-function anyway).  This mostly
> works, but there's pushback from gcc (at least in 4.3): trying
> to adjust vector-type-alignment by e.g. "ADJUST_ALIGNMENT (V4SI,
> 8);" in mips-modes.def has no effect; I had to do it in
> mips_builtin_vector_type, which might be brittle or just working
> by chance.

See above as to why ADJUST_ALIGNMENT it itself doesn't change the
alignment of vector types.  mips_builtin_vector_type affects only
the types created by the back-end, not generic vector types e.g.
the ones generated by the vectorizer on the fly ...

> Then there's the tree-vectorizer, which for some
> optimizations wants to assume natural alignment when doing
> "floor alignment".  I couldn't define a usable
> "vec_realign_load_<mode>" (undocumented) as it assumes that the
> low vector-size bits of an address will exactly correspond to
> misalignment when masking off and applying to a vector.  And,
> you may have to conditionalize some vectorizer tests with the
> effective-target unaligned_stack.

I *think* this ought to work out OK, since the realignment scheme
consults the type alignment:

      new_stmt = gimple_build_assign_with_ops
                   (BIT_AND_EXPR, NULL_TREE, ptr,
                    build_int_cst (TREE_TYPE (ptr),
                                   -(HOST_WIDE_INT)TYPE_ALIGN_UNIT (vectype)));

So once TYPE_ALIGN is actually set up correctly, this hopefully
will just work as expected ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  ulrich.weig...@de.ibm.com

Reply via email to