aarch64: Treat GNU and Advanced SIMD vectors as distinct [PR92789, PR95726]
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 30 Jun 2020 20:40:30 +0000 (21:40 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Tue, 30 Jun 2020 20:40:30 +0000 (21:40 +0100)
commit31427b974ed7b7dd54e28fec595e731bf6eea8ba
tree4adde506baad9be86d88dcd507a76d03846c6c4e
parent67ef8cfc1c1d440eafa89a26710bced934a485dc
aarch64: Treat GNU and Advanced SIMD vectors as distinct [PR92789, PR95726]

PR95726 is about template look-up for things like:

    foo<float vecf __attribute__((vector_size(16)))>
    foo<float32x4_t>

The immediate cause of the problem is that the hash function usually
returns different hashes for these types, yet the equality function
thinks they are equal.  This then raises the question of how the types
are supposed to be treated.

I think the answer is that the GNU vector type should be treated as
distinct from float32x4_t, not least because the two types mangle
differently.  However, each type should implicitly convert to the other.

This would mean that, as far as the PR is concerned, the hashing
function is right to (sometimes) treat the types differently and
the equality function is wrong to treat them as the same.

The most obvious way to enforce the type difference is to use a
target-specific type attribute.  That on its own is enough to fix
the PR.  The difficulty is deciding whether the knock-on effects
are acceptable.

One obvious effect is that GCC then rejects:

    typedef float vecf __attribute__((vector_size(16)));
    vecf x;
    float32x4_t &z = x;

on the basis that the types are no longer reference-compatible.
I think that's again the correct behaviour, and consistent with
current Clang.

A trickier question is whether:

    vecf x;
    float32x4_t y;
    … c ? x : y …

should be valid, and if so, what its type should be [PR92789].
As explained in the comment in the testcase, GCC and Clang both
accepted this, but GCC chose the “then” type while Clang chose
the “else” type.  This can lead to different mangling for (probably
artificial) corner cases, as seen for “sel1” and “sel2” in the
testcase.

Adding the attribute makes GCC reject the conditional expression
as ambiguous.  I think that too is the correct behaviour, for the
reasons described in the testcase.  However, it does seem to have
the potential to break existing code.

It looks like aarch64_comp_type_attributes is missing cases for
the SVE attributes, but I'll handle that in a separate patch.

2020-06-30  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
PR target/92789
PR target/95726
* config/aarch64/aarch64.c (aarch64_attribute_table): Add
"Advanced SIMD type".
(aarch64_comp_type_attributes): Check that the "Advanced SIMD type"
attributes are equal.
* config/aarch64/aarch64-builtins.c: Include stringpool.h and
attribs.h.
(aarch64_mangle_builtin_vector_type): Use the mangling recorded
in the "Advanced SIMD type" attribute.
(aarch64_init_simd_builtin_types): Add an "Advanced SIMD type"
attribute to each Advanced SIMD type, using the mangled type
as the attribute's single argument.

gcc/testsuite/
PR target/92789
PR target/95726
* g++.target/aarch64/pr95726.C: New test.
gcc/config/aarch64/aarch64-builtins.c
gcc/config/aarch64/aarch64.c
gcc/testsuite/g++.target/aarch64/pr95726.C [new file with mode: 0644]