[Bug c++/92789] Non-obvious ?: behaviour with structurally equivalent types
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jul 10 18:07:21 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92789
--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Sandiford <rsandifo@gcc.gnu.org>:
https://gcc.gnu.org/g:efe99cca78215e339ba79f0a900a896b4c0a3d36
commit r11-2022-gefe99cca78215e339ba79f0a900a896b4c0a3d36
Author: Richard Sandiford <richard.sandiford@arm.com>
Date: Fri Jul 10 19:06:45 2020 +0100
arm: Treat GNU and Advanced SIMD vectors as distinct [PR92789, PR95726]
This is an arm version of aarch64 patch r11-1741. The approach
is essentially identical, not much more than s/aarch64/arm/.
To recap, 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.
The answer we chose for AArch64 was that the GNU vector type should
be treated as distinct from float32x4_t, but that 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.
For AArch64 we took the approach that this was the correct behaviour.
It is also 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. For AArch64 we took the approach that this too is
the correct behaviour, for the reasons described in the testcase.
However, it does seem to have the potential to break existing code.
gcc/
PR target/92789
PR target/95726
* config/arm/arm.c (arm_attribute_table): Add
"Advanced SIMD type".
(arm_comp_type_attributes): Check that the "Advanced SIMD type"
attributes are equal.
* config/arm/arm-builtins.c: Include stringpool.h and
attribs.h.
(arm_mangle_builtin_vector_type): Use the mangling recorded
in the "Advanced SIMD type" attribute.
(arm_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/arm/pr95726.C: New test.
More information about the Gcc-bugs
mailing list