blob: 5f7dbf11ddc23572c7f0897ab50d8171b6a1d6d0 [file] [log] [blame]
// { dg-require-effective-target arm_neon_ok }
// { dg-add-options arm_neon }
#include <arm_neon.h>
typedef float vecf __attribute__((vector_size(16)));
// This assertion must hold: vecf and float32x4_t have distinct identities
// and mangle differently, so they are not interchangeable.
template<typename T> struct bar;
template<> struct bar<vecf> { static const int x = 1; };
template<> struct bar<float32x4_t> { static const int x = 2; };
static_assert(bar<vecf>::x + bar<float32x4_t>::x == 3, "boo");
// GCC 10.1 and earlier accepted this. However, the rule should be
// that GNU vectors and Advanced SIMD vectors are distinct types but
// that each one implicitly converts to the other. The types are not
// reference-compatible.
//
// The behavior tested below is consistent with Clang.
vecf x;
float32x4_t y;
float32x4_t &z = x; // { dg-error {cannot bind non-const lvalue reference} }
// These assignment must be valid even in the strictest mode: vecf must
// implicitly convert to float32x4_t and vice versa.
void foo() { x = y; y = x; }
// Previously GCC accepted this and took the type of "d" from the "then" arm.
// It therefore mangled the functions as:
//
// _Z4sel1bRDv4_f
// _Z4sel2bR19__simd128_float32_t
//
// Clang currently also accepts it and takes the type of "d" from the
// "else" arm. It therefore mangles the functions as follows, which is
// inconsistent with the old GCC behavior:
//
// _Z4sel1b19__simd128_float32_t
// _Z4sel2bDv4_f
//
// Given that the types have distinct identities and that each one
// implicitly converts to the other (see above), the expression ought
// to be rejected as invalid. This is consistent (by analogy) with the
// standard C++ handling of conditional expressions involving class types,
// in cases where the "then" value implicitly converts to the "else" type
// and the "else" value implicitly converts to the "then" type.
auto sel1(bool c, decltype(c ? x : y) d) { return d; } // { dg-error {operands to '\?:' have different types} }
auto sel2(bool c, decltype(c ? y : x) d) { return d; } // { dg-error {operands to '\?:' have different types} }