On 4/3/19 11:40 PM, Richard Biener wrote:
On April 3, 2019 7:59:47 PM GMT+02:00, Martin Sebor <mse...@gmail.com> wrote:
On 4/3/19 5:13 AM, Richard Biener wrote:
On Tue, Apr 2, 2019 at 6:20 PM Martin Sebor <mse...@gmail.com> wrote:

GCC tries to align a vector on its natural boundary, i.e., that
given by its size, up to MAX_OBJECT_ALIGNMENT.  Vectors that are
bigger than that are either silently [mis]aligned on that same
maximum boundary (PR 89798), silently truncated (and misaligned),
or cause an ICE (PR 89797).  Compiling the following:

     __attribute__ ((vector_size (N))) char v;

     _Static_assert (sizeof (v) == N, "size");
     _Static_assert (__alignof__ (v) == N, "alignment");

with N set to 1LLU << I shows these failures:

     I < 29   succeeds
     I < 31   fails alignment
     I < 32   ICE
     I >= 32  fails alignment and size

Attribute aligned doesn't seem to have any effect on types or
variables declared with attribute vector_size.  The alignment
set by the latter prevails.

This happens no matter what scope the vector is defined in (i.e.,
file or local).

I have some questions:

1) Is there some reason to align vectors on the same boundary
      as their size no matter how big it is?  I can't find such
      a requirement in the ABIs I looked at.  Or would it be more
      appropriate to align the big ones on the preferred boundary
      for the target?  For instance, does it make more sense to
      align a 64KB vector on a 64KB boundary than on, say,
      a 64-byte boundary (or some other boundary less than 64K?)

I don't think there's a good reason.  Instead I think that
BIGGEST_ALIGNMENT is what we should go for as upper limit,
anything bigger doesn't make sense (unless the user explicitely
requests it).

Sounds good.  Changing the alignment will impact object layout.

Do we really apply the alignment there? How do other compilers lay out here?

Unfortunately, yes.  The struct below is 2048 in size.

  struct S {
    char c;
    __attribute__ ((vector_size (1024))) char a;
  };

Clang and ICC do the same thing.  The biggest vector Clang allows
is 1024 bytes.  ICC tops out at 1<<21.  GCC ICEs for sizes over
1LLU << 32 but with my patch for bug 89797 it accepts any size
up to 1/2 the address space.

With types other than char the aligned attribute can be used in
conjunction with packed to reduce the size to just 1088:

  struct S {
    char c;
    __attribute__ ((aligned (64), packed, vector_size (1024))) int a;
  };

All three compilers require the packed attribute to reduce
the alignment.  Clang and GCC silently ignore the aligned
attribute without it but ICC issues warning #1366: a reduction
in alignment without the "packed" attribute is ignored.  That
would be a helpful enhancement to add to GCC.

I think ignoring the packed attribute for char vectors is a bug
so I opened PR 89968 for it.

How do you suggest to deal with it? (Presumably for GCC 10.)
Issuing an ABI warning and adding an option to override
the new setting come to mind as possible mitigating solutions.

We could reject these vector types in aggregates in favor of arrays. Of course 
that ship has sailed...

We could still issue a warning for vectors that are excessively
overaligned and suggest to use attributes aligned and packed to
reduce the alignment.

Martin

Reply via email to