https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101876

--- Comment #5 from Marius Hillenbrand <mhillen at linux dot ibm.com> ---
The root cause is not the difference in alignment between vector types in
itself, but the resulting "confusion" in the type system when the #pragma GCC
target switches the default vector alignment.

It looks like we generally assume that the default vector alignment should be
invariant during a compile run. Failing that will break two other invariants
that then result in the s390-specific vector builtins to resolve or the C++
frontend to ICE.

Vector types with the same structure yet different alignments would usually end
up as type variants that link to the same TYPE_MAIN_VARIANT and TYPE_CANONICAL
because of how they are constructed by make_vector_type: (1) construct a
default variant of the vector type, (2) try to find the canonical object for
that type in the hash table or add the new type as such, (3) if required attach
the to-be-constructed type as a type variant to the canonical object. The hash
table lookup compares alignment. Thus, retrieving a previously created
canonical object in that process only works if the "default variant" in step
(1) has the same alignment as before.

When #pragma GCC target switches between non-VX and VX-enabled targets, we
break that invariant. pre-VX, vector alignment defaults to natural alignment.
with -mvx, vectors align to 8 Bytes. Consequently, make_vector_type will fail
to identify any existing "canonical objects" for vector types and add new ones
to the hash table -- possibly resulting in multiple clusters that represent the
same vector types.

For example, in 
typedef int v4si_raw __attribute__((vector_size(16))); // aligned to 16 B
typedef int v4si_raw_aligned8 __attribute__((vector_size(16), aligned(8)));

#pragma GCC target("arch=z13") // implies -mvx

typedef int v4si_z13 __attribute__((vector_size(16))); // aligned to 8 B
typedef int v4si_z13_aligned16 __attribute__((vector_size(16), aligned(16)));

The types v4si_z13 and v4si_z13_aligned16 will fail to be associated to v4si as
their main variant. Instead, these two will link to v4si_z13 as their main
variant.

The s390-specific vector builtins fail to resolve, because the code assumes
that structurally equivalant vector types would have the same
TYPE_MAIN_VARIANT. Similarly, the C++ frontend may hit the failing assertion
that structurally equivalent types should have the same TYPE_CANONICAL (for
vector types, that would point to the shared TYPE_MAIN_VARIANT).

Reply via email to