1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify=expected,both %s
// RUN: %clang_cc1 -verify=ref,both %s
typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 A = {1,2,3,4};
static_assert(A[0] == 1, "");
static_assert(A[1] == 2, "");
static_assert(A[2] == 3, "");
static_assert(A[3] == 4, "");
/// FIXME: It would be nice if the note said 'vector' instead of 'array'.
static_assert(A[12] == 4, ""); // both-error {{not an integral constant expression}} \
// both-note {{cannot refer to element 12 of array of 4 elements in a constant expression}}
/// VectorSplat casts
typedef __attribute__(( ext_vector_type(4) )) float float4;
constexpr float4 vec4_0 = (float4)0.5f;
static_assert(vec4_0[0] == 0.5, "");
static_assert(vec4_0[1] == 0.5, "");
static_assert(vec4_0[2] == 0.5, "");
static_assert(vec4_0[3] == 0.5, "");
constexpr int vec4_0_discarded = ((float4)12.0f, 0);
/// ImplicitValueInitExpr of vector type
constexpr float4 arr4[2] = {
{1,2,3,4},
};
static_assert(arr4[0][0] == 1, "");
static_assert(arr4[0][1] == 2, "");
static_assert(arr4[0][2] == 3, "");
static_assert(arr4[0][3] == 4, "");
static_assert(arr4[1][0] == 0, "");
static_assert(arr4[1][0] == 0, "");
static_assert(arr4[1][0] == 0, "");
static_assert(arr4[1][0] == 0, "");
constexpr VI4 B = __extension__(A);
/// From constant-expression-cxx11.cpp
namespace Vector {
typedef int __attribute__((vector_size(16))) VI4;
constexpr VI4 f(int n) {
return VI4 { n * 3, n + 4, n - 5, n / 6 };
}
constexpr auto v1 = f(10);
static_assert(__builtin_vectorelements(v1) == (16 / sizeof(int)), "");
typedef double __attribute__((vector_size(32))) VD4;
constexpr VD4 g(int n) {
return (VD4) { n / 2.0, n + 1.5, n - 5.4, n * 0.9 };
}
constexpr auto v2 = g(4);
static_assert(__builtin_vectorelements(v2) == (32 / sizeof(double)), "");
}
namespace {
typedef float __attribute__((vector_size(16))) VI42;
constexpr VI42 A2 = A;
}
namespace BoolToSignedIntegralCast{
typedef __attribute__((__ext_vector_type__(4))) unsigned int int4;
constexpr int4 intsT = (int4)true;
static_assert(intsT[0] == -1, "");
static_assert(intsT[1] == -1, "");
static_assert(intsT[2] == -1, "");
static_assert(intsT[3] == -1, "");
}
namespace VectorElementExpr {
typedef int int2 __attribute__((ext_vector_type(2)));
typedef int int4 __attribute__((ext_vector_type(4)));
constexpr int oneElt = int4(3).x;
static_assert(oneElt == 3);
constexpr int2 twoElts = ((int4){11, 22, 33, 44}).yz;
static_assert(twoElts.x == 22, "");
static_assert(twoElts.y == 33, "");
}
namespace Temporaries {
typedef __attribute__((vector_size(16))) int vi4a;
typedef __attribute__((ext_vector_type(4))) int vi4b;
struct S {
vi4a v;
vi4b w;
};
int &&s = S().w[1];
}
#ifdef __SIZEOF_INT128__
namespace bigint {
typedef __attribute__((__ext_vector_type__(4))) __int128 bigint4;
constexpr bigint4 A = (bigint4)true;
static_assert(A[0] == -1, "");
static_assert(A[1] == -1, "");
static_assert(A[2] == -1, "");
static_assert(A[3] == -1, "");
}
#endif
using VI __attribute__((ext_vector_type(4))) = int;
constexpr int a1() {
VI a = {0, 0, 0, 0};
VI b = {1,1,1,1};
VI C = (a += b);
return 0;
}
static_assert(a1() == 0);
constexpr int a2() {
VI a = {0, 0, 0, 0};
VI b = {1,1,1,1};
VI C = (a + b);
return 0;
}
static_assert(a2() == 0);
namespace {
/// convertvector expr with a per-element floating-point cast
typedef float __m128 __attribute__((__vector_size__(16), __aligned__(16)));
typedef double __m128d __attribute__((__vector_size__(16), __aligned__(16)));
typedef float __v4sf __attribute__((__vector_size__(16)));
typedef double __v2df __attribute__((__vector_size__(16)));
static inline constexpr __m128d
_mm_cvtps_pd(__m128 __a) {
return __builtin_convertvector(__builtin_shufflevector(__a, __a, 0, 1), __v2df);
}
constexpr __m128 kf1 {-1.0f,+2.0f,-3.0f,+4.0f};
constexpr __m128d v_mm_cvtps_pd = _mm_cvtps_pd(kf1);
static_assert(v_mm_cvtps_pd[0] == -1.0 && v_mm_cvtps_pd[1] == +2.0);
}
|