brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.7 KiB · c60b940 Raw
179 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-linux-pc -fsyntax-only -verify -fexceptions -fcxx-exceptions %s -std=c++172// Note that this test depends on the size of long-long to be different from3// int, so it specifies a triple.4 5using FourShorts = short __attribute__((__vector_size__(8)));6using TwoInts = int __attribute__((__vector_size__(8)));7using TwoUInts = unsigned __attribute__((__vector_size__(8)));8using FourInts = int __attribute__((__vector_size__(16)));9using FourUInts = unsigned __attribute__((__vector_size__(16)));10using TwoLongLong = long long __attribute__((__vector_size__(16)));11using FourLongLong = long long __attribute__((__vector_size__(32)));12using TwoFloats = float __attribute__((__vector_size__(8)));13using FourFloats = float __attribute__((__vector_size__(16)));14using TwoDoubles = double __attribute__((__vector_size__(16)));15using FourDoubles = double __attribute__((__vector_size__(32)));16using EightBools = bool __attribute__((ext_vector_type(8)));17 18FourShorts four_shorts;19TwoInts two_ints;20TwoUInts two_uints;21FourInts four_ints;22FourUInts four_uints;23TwoLongLong two_ll;24FourLongLong four_ll;25TwoFloats two_floats;26FourFloats four_floats;27TwoDoubles two_doubles;28FourDoubles four_doubles;29EightBools eight_bools;30EightBools other_eight_bools;31 32enum E {};33enum class SE {};34E e;35SE se;36 37// Check the rules of the condition of the conditional operator.38void Condition() {39  // Only int types are allowed here, the rest should fail to convert to bool.40  (void)(four_floats ? 1 : 1); // expected-error {{is not contextually convertible to 'bool'}}}41  (void)(two_doubles ? 1 : 1); // expected-error {{is not contextually convertible to 'bool'}}}42}43 44// Check the rules of the LHS/RHS of the conditional operator.45void Operands() {46  (void)(four_ints ? four_ints : throw 1); // expected-error {{GNU vector conditional operand cannot be a throw expression}}47  (void)(four_ints ? throw 1 : four_ints); // expected-error {{GNU vector conditional operand cannot be a throw expression}}48  (void)(four_ints ?: throw 1);            // expected-error {{GNU vector conditional operand cannot be a throw expression}}49  (void)(four_ints ? (void)1 : four_ints); // expected-error {{GNU vector conditional operand cannot be void}}50  (void)(four_ints ?: (void)1);            // expected-error {{GNU vector conditional operand cannot be void}}51 52  // Vector types must be the same element size as the condition.53  (void)(four_ints ? two_ll : two_ll);             // expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type 'TwoLongLong' (vector of 2 'long long' values) do not have the same number of elements}}54  (void)(four_ints ? four_ll : four_ll);           // expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type 'FourLongLong' (vector of 4 'long long' values) do not have elements of the same size}}55  (void)(four_ints ? two_doubles : two_doubles);   // expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type 'TwoDoubles' (vector of 2 'double' values) do not have the same number of elements}}56  (void)(four_ints ? four_doubles : four_doubles); // expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type 'FourDoubles' (vector of 4 'double' values) do not have elements of the same size}}57  (void)(four_ints ?: two_ints);                   // expected-error {{vector operands to the vector conditional must be the same type ('FourInts' (vector of 4 'int' values) and 'TwoInts' (vector of 2 'int' values)}}58  (void)(four_ints ?: four_doubles);               // expected-error {{vector operands to the vector conditional must be the same type ('FourInts' (vector of 4 'int' values) and 'FourDoubles' (vector of 4 'double' values)}}59 60  // Scalars are promoted, but must be the same element size.61  (void)(four_ints ? 3.0f : 3.0); // expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type '__attribute__((__vector_size__(4 * sizeof(double)))) double' (vector of 4 'double' values) do not have elements of the same size}}62  (void)(four_ints ? 5ll : 5);    // expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type '__attribute__((__vector_size__(4 * sizeof(long long)))) long long' (vector of 4 'long long' values) do not have elements of the same size}}63  (void)(four_ints ?: 3.0);       // expected-error {{cannot convert between scalar type 'double' and vector type 'FourInts' (vector of 4 'int' values) as implicit conversion would cause truncation}}64  (void)(four_ints ?: 5ll);       // We allow this despite GCc not allowing this since we support integral->vector-integral conversions despite integer rank.65 66  // This one would be allowed in GCC, but we don't allow vectors of enum. Also,67  // the error message isn't perfect, since it is only going to be a problem68  // when both sides are an enum, otherwise it'll be promoted to whatever type69  // the other side causes.70  (void)(four_ints ? e : e);                          // expected-error {{enumeration type 'E' is not allowed in a vector conditional}}71  (void)(four_ints ? se : se);                        // expected-error {{enumeration type 'SE' is not allowed in a vector conditional}}72  (void)(four_shorts ? (short)5 : (unsigned short)5); // expected-error {{vector condition type 'FourShorts' (vector of 4 'short' values) and result type '__attribute__((__vector_size__(4 * sizeof(int)))) int' (vector of 4 'int' values) do not have elements of the same size}}73 74  // They must also be convertible.75  (void)(four_ints ? 3.0f : 5u);76  (void)(four_ints ? 3.0f : 5);77  unsigned us = 5u;78  int sint = 5;79  short shrt = 5;80  unsigned short uss = 5u;81  // The following 2 error in GCC for truncation errors, but it seems82  // unimportant and inconsistent to enforce that rule.83  (void)(four_ints ? 3.0f : us);84  (void)(four_ints ? 3.0f : sint);85 86  // Test promotion:87  (void)(four_shorts ? uss : shrt);  // expected-error {{vector condition type 'FourShorts' (vector of 4 'short' values) and result type '__attribute__((__vector_size__(4 * sizeof(int)))) int' (vector of 4 'int' values) do not have elements of the same size}}88  (void)(four_shorts ? shrt : shrt); // should be fine.89  (void)(four_ints ? uss : shrt);    // should be fine, since they get promoted to int.90  (void)(four_ints ? shrt : shrt);   //expected-error {{vector condition type 'FourInts' (vector of 4 'int' values) and result type '__attribute__((__vector_size__(4 * sizeof(short)))) short' (vector of 4 'short' values) do not have elements of the same size}}91 92  // Vectors must be the same type as each other.93  (void)(four_ints ? four_uints : four_floats); // expected-error {{vector operands to the vector conditional must be the same type ('FourUInts' (vector of 4 'unsigned int' values) and 'FourFloats' (vector of 4 'float' values))}}94  (void)(four_ints ? four_uints : four_ints);   // expected-error {{vector operands to the vector conditional must be the same type ('FourUInts' (vector of 4 'unsigned int' values) and 'FourInts' (vector of 4 'int' values))}}95  (void)(four_ints ? four_ints : four_uints);   // expected-error {{vector operands to the vector conditional must be the same type ('FourInts' (vector of 4 'int' values) and 'FourUInts' (vector of 4 'unsigned int' values))}}96 97  // GCC rejects these, but our lax vector conversions don't seem to have a problem with them. Allow conversion of the float to an int as an extension.98  (void)(four_ints ? four_uints : 3.0f);99  (void)(four_ints ? four_ints : 3.0f);100 101  // Allow conditional select on bool vectors.102  (void)(eight_bools ? eight_bools : other_eight_bools);103 104  // When there is a vector and a scalar, conversions must be legal.105  (void)(four_ints ? four_floats : 3); // should work, ints can convert to floats.106  (void)(four_ints ? four_uints : e);  // expected-error {{cannot convert between scalar type 'E' and vector type 'FourUInts'}}107  (void)(four_ints ? four_uints : se); // expected-error {{cannot convert between vector and non-scalar values ('FourUInts' (vector of 4 'unsigned int' values) and 'SE'}}108  // GCC permits this, but our conversion rules reject this for truncation.109  (void)(two_ints ? two_ints : us);        // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'TwoInts'}}110  (void)(four_shorts ? four_shorts : uss); // expected-error {{cannot convert between scalar type 'unsigned short' and vector type 'FourShorts'}}111  (void)(four_ints ? four_floats : us);    // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'FourFloats'}}112  (void)(four_ints ? four_floats : sint);  // expected-error {{cannot convert between scalar type 'int' and vector type 'FourFloats'}}113}114 115template <typename T1, typename T2>116struct is_same {117  static constexpr bool value = false;118};119template <typename T>120struct is_same<T, T> {121  static constexpr bool value = true;122};123template <typename T1, typename T2>124constexpr bool is_same_v = is_same<T1, T2>::value;125template <typename T>126T &&declval();127 128// Check the result types when given two vector types.129void ResultTypes() {130  // Vectors must be the same, but result is the type of the LHS/RHS.131  static_assert(is_same_v<TwoInts, decltype(declval<TwoInts>() ? declval<TwoInts>() : declval<TwoInts>())>);132  static_assert(is_same_v<TwoFloats, decltype(declval<TwoInts>() ? declval<TwoFloats>() : declval<TwoFloats>())>);133 134  // When both are scalars, converts to vectors of common type.135  static_assert(is_same_v<TwoUInts, decltype(declval<TwoInts>() ? declval<int>() : declval<unsigned int>())>);136 137  // Constant is allowed since it doesn't truncate, and should promote to float.138  static_assert(is_same_v<TwoFloats, decltype(declval<TwoInts>() ? declval<float>() : 5u)>);139  static_assert(is_same_v<TwoFloats, decltype(declval<TwoInts>() ? 5 : declval<float>())>);140 141  // when only 1 is a scalar, it should convert to a compatible type.142  static_assert(is_same_v<TwoFloats, decltype(declval<TwoInts>() ? declval<TwoFloats>() : declval<float>())>);143  static_assert(is_same_v<TwoInts, decltype(declval<TwoInts>() ? declval<TwoInts>() : declval<int>())>);144  static_assert(is_same_v<TwoFloats, decltype(declval<TwoInts>() ? declval<TwoFloats>() : 5)>);145 146  // For the Binary conditional operator, the result type is either the vector on the RHS (that fits the rules on size/count), or the scalar extended to the correct count.147  static_assert(is_same_v<TwoInts, decltype(declval<TwoInts>() ?: declval<TwoInts>())>);148  static_assert(is_same_v<TwoInts, decltype(declval<TwoInts>() ?: declval<int>())>);149}150 151template <typename Cond>152void dependent_cond(Cond C) {153  (void)(C ? 1 : 2);154}155 156template <typename Operand>157void dependent_operand(Operand C) {158  (void)(two_ints ? 1 : C);159  (void)(two_ints ? C : 1);160  (void)(two_ints ? C : C);161}162 163template <typename Cond, typename LHS, typename RHS>164void all_dependent(Cond C, LHS L, RHS R) {165  (void)(C ? L : R);166}167 168// Check dependent cases.169void Templates() {170  dependent_cond(two_ints);171  dependent_operand(two_floats);172  // expected-error@165 {{vector operands to the vector conditional must be the same type ('__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int' (vector of 4 'unsigned int' values) and '__attribute__((__vector_size__(4 * sizeof(double)))) double' (vector of 4 'double' values))}}}173  all_dependent(four_ints, four_uints, four_doubles); // expected-note {{in instantiation of}}174 175  // expected-error@165 {{vector operands to the vector conditional must be the same type ('__attribute__((__vector_size__(4 * sizeof(unsigned int)))) unsigned int' (vector of 4 'unsigned int' values) and '__attribute__((__vector_size__(2 * sizeof(unsigned int)))) unsigned int' (vector of 2 'unsigned int' values))}}}176  all_dependent(four_ints, four_uints, two_uints); // expected-note {{in instantiation of}}177  all_dependent(four_ints, four_uints, four_uints);178}179