1 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -ffreestanding -fsyntax-only -verify -mvscale-min=1 -mvscale-max=1 -fallow-half-arguments-and-returns %s
2 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -ffreestanding -fsyntax-only -verify -mvscale-min=2 -mvscale-max=2 -fallow-half-arguments-and-returns %s
3 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -ffreestanding -fsyntax-only -verify -mvscale-min=4 -mvscale-max=4 -fallow-half-arguments-and-returns %s
4 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -ffreestanding -fsyntax-only -verify -mvscale-min=8 -mvscale-max=8 -fallow-half-arguments-and-returns %s
5 // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -ffreestanding -fsyntax-only -verify -mvscale-min=16 -mvscale-max=16 -fallow-half-arguments-and-returns %s
9 #define N __ARM_FEATURE_SVE_BITS
11 typedef __fp16 float16_t
;
12 typedef float float32_t
;
13 typedef double float64_t
;
14 typedef __SVInt8_t svint8_t
;
15 typedef __SVInt16_t svint16_t
;
16 typedef __SVInt32_t svint32_t
;
17 typedef __SVInt64_t svint64_t
;
18 typedef __SVUint8_t svuint8_t
;
19 typedef __SVUint16_t svuint16_t
;
20 typedef __SVUint32_t svuint32_t
;
21 typedef __SVUint64_t svuint64_t
;
22 typedef __SVFloat16_t svfloat16_t
;
23 typedef __SVFloat32_t svfloat32_t
;
24 typedef __SVFloat64_t svfloat64_t
;
26 #if defined(__ARM_FEATURE_SVE_BF16)
27 typedef __bf16 bfloat16_t
;
28 typedef __SVBFloat16_t svbfloat16_t
;
31 typedef __SVBool_t svbool_t
;
33 // Define valid fixed-width SVE types
34 typedef svint8_t fixed_int8_t
__attribute__((arm_sve_vector_bits(N
)));
35 typedef svint16_t fixed_int16_t
__attribute__((arm_sve_vector_bits(N
)));
36 typedef svint32_t fixed_int32_t
__attribute__((arm_sve_vector_bits(N
)));
37 typedef svint64_t fixed_int64_t
__attribute__((arm_sve_vector_bits(N
)));
39 typedef svuint8_t fixed_uint8_t
__attribute__((arm_sve_vector_bits(N
)));
40 typedef svuint16_t fixed_uint16_t
__attribute__((arm_sve_vector_bits(N
)));
41 typedef svuint32_t fixed_uint32_t
__attribute__((arm_sve_vector_bits(N
)));
42 typedef svuint64_t fixed_uint64_t
__attribute__((arm_sve_vector_bits(N
)));
44 typedef svfloat16_t fixed_float16_t
__attribute__((arm_sve_vector_bits(N
)));
45 typedef svfloat32_t fixed_float32_t
__attribute__((arm_sve_vector_bits(N
)));
46 typedef svfloat64_t fixed_float64_t
__attribute__((arm_sve_vector_bits(N
)));
48 typedef svbfloat16_t fixed_bfloat16_t
__attribute__((arm_sve_vector_bits(N
)));
50 typedef svbool_t fixed_bool_t
__attribute__((arm_sve_vector_bits(N
)));
53 typedef int8_t gnu_int8_t
__attribute__((vector_size(N
/ 8)));
54 typedef int16_t gnu_int16_t
__attribute__((vector_size(N
/ 8)));
55 typedef int32_t gnu_int32_t
__attribute__((vector_size(N
/ 8)));
56 typedef int64_t gnu_int64_t
__attribute__((vector_size(N
/ 8)));
58 typedef uint8_t gnu_uint8_t
__attribute__((vector_size(N
/ 8)));
59 typedef uint16_t gnu_uint16_t
__attribute__((vector_size(N
/ 8)));
60 typedef uint32_t gnu_uint32_t
__attribute__((vector_size(N
/ 8)));
61 typedef uint64_t gnu_uint64_t
__attribute__((vector_size(N
/ 8)));
63 typedef float16_t gnu_float16_t
__attribute__((vector_size(N
/ 8)));
64 typedef float32_t gnu_float32_t
__attribute__((vector_size(N
/ 8)));
65 typedef float64_t gnu_float64_t
__attribute__((vector_size(N
/ 8)));
67 typedef bfloat16_t gnu_bfloat16_t
__attribute__((vector_size(N
/ 8)));
69 // Attribute must have a single argument
70 typedef svint8_t no_argument
__attribute__((arm_sve_vector_bits
)); // expected-error {{'arm_sve_vector_bits' attribute takes one argument}}
71 typedef svint8_t two_arguments
__attribute__((arm_sve_vector_bits(2, 4))); // expected-error {{'arm_sve_vector_bits' attribute takes one argument}}
73 // The number of SVE vector bits must be an integer constant expression
74 typedef svint8_t non_int_size1
__attribute__((arm_sve_vector_bits(2.0))); // expected-error {{'arm_sve_vector_bits' attribute requires an integer constant}}
75 typedef svint8_t non_int_size2
__attribute__((arm_sve_vector_bits("256"))); // expected-error {{'arm_sve_vector_bits' attribute requires an integer constant}}
77 typedef __clang_svint8x2_t svint8x2_t
;
78 typedef __clang_svfloat32x3_t svfloat32x3_t
;
80 // Attribute must be attached to a single SVE vector or predicate type.
81 typedef void *badtype1
__attribute__((arm_sve_vector_bits(N
))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'void *'}}
82 typedef int badtype2
__attribute__((arm_sve_vector_bits(N
))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'int'}}
83 typedef float badtype3
__attribute__((arm_sve_vector_bits(N
))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'float'}}
84 typedef svint8x2_t badtype4
__attribute__((arm_sve_vector_bits(N
))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'svint8x2_t' (aka '__clang_svint8x2_t')}}
85 typedef svfloat32x3_t badtype5
__attribute__((arm_sve_vector_bits(N
))); // expected-error {{'arm_sve_vector_bits' attribute applied to non-SVE type 'svfloat32x3_t' (aka '__clang_svfloat32x3_t')}}
87 // Attribute only applies to typedefs.
88 svint8_t non_typedef_type
__attribute__((arm_sve_vector_bits(N
))); // expected-error {{'arm_sve_vector_bits' attribute only applies to typedefs}}
90 // Test that we can define non-local fixed-length SVE types (unsupported for
92 fixed_int8_t global_int8
;
93 fixed_bfloat16_t global_bfloat16
;
94 fixed_bool_t global_bool
;
96 extern fixed_int8_t extern_int8
;
97 extern fixed_bfloat16_t extern_bfloat16
;
98 extern fixed_bool_t extern_bool
;
100 static fixed_int8_t static_int8
;
101 static fixed_bfloat16_t static_bfloat16
;
102 static fixed_bool_t static_bool
;
104 fixed_int8_t
*global_int8_ptr
;
105 extern fixed_int8_t
*extern_int8_ptr
;
106 static fixed_int8_t
*static_int8_ptr
;
107 __thread fixed_int8_t thread_int8
;
109 typedef fixed_int8_t int8_typedef
;
110 typedef fixed_int8_t
*int8_ptr_typedef
;
112 // Test sized expressions
113 int sizeof_int8
= sizeof(global_int8
);
114 int sizeof_int8_var
= sizeof(*global_int8_ptr
);
115 int sizeof_int8_var_ptr
= sizeof(global_int8_ptr
);
117 extern fixed_int8_t
*extern_int8_ptr
;
119 int alignof_int8
= __alignof__(extern_int8
);
120 int alignof_int8_var
= __alignof__(*extern_int8_ptr
);
121 int alignof_int8_var_ptr
= __alignof__(extern_int8_ptr
);
128 // Check conditional expressions where the result is ambiguous are
130 void *sel
__attribute__((unused
));
131 sel
= c
? ss8
: fs8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
132 sel
= c
? fs8
: ss8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
134 sel
= c
? gs8
: ss8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
135 sel
= c
? ss8
: gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
137 sel
= c
? gs8
: fs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
138 sel
= c
? fs8
: gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
140 // Check binary expressions where the result is ambiguous are ill-formed.
141 ss8
= ss8
+ fs8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
142 ss8
= ss8
+ gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
144 fs8
= fs8
+ ss8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
145 fs8
= fs8
+ gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
147 gs8
= gs8
+ ss8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
148 gs8
= gs8
+ fs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
150 ss8
+= fs8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
151 ss8
+= gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
153 fs8
+= ss8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
154 fs8
+= gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
156 gs8
+= ss8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
157 gs8
+= fs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
159 ss8
= ss8
== fs8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
160 ss8
= ss8
== gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
162 fs8
= fs8
== ss8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
163 fs8
= fs8
== gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
165 gs8
= gs8
== ss8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
166 gs8
= gs8
== fs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
168 ss8
= ss8
& fs8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
169 ss8
= ss8
& gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
171 fs8
= fs8
& ss8
; // expected-error {{cannot combine fixed-length and sizeless SVE vectors in expression, result is ambiguous}}
172 fs8
= fs8
& gs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
174 gs8
= gs8
& ss8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
175 gs8
= gs8
& fs8
; // expected-error {{cannot combine GNU and SVE vectors in expression, result is ambiguous}}
178 // --------------------------------------------------------------------------//
181 #define VECTOR_SIZE ((N / 8))
182 #define PRED_SIZE ((N / 64))
184 _Static_assert(sizeof(fixed_int8_t
) == VECTOR_SIZE
, "");
186 _Static_assert(sizeof(fixed_int16_t
) == VECTOR_SIZE
, "");
187 _Static_assert(sizeof(fixed_int32_t
) == VECTOR_SIZE
, "");
188 _Static_assert(sizeof(fixed_int64_t
) == VECTOR_SIZE
, "");
190 _Static_assert(sizeof(fixed_uint8_t
) == VECTOR_SIZE
, "");
191 _Static_assert(sizeof(fixed_uint16_t
) == VECTOR_SIZE
, "");
192 _Static_assert(sizeof(fixed_uint32_t
) == VECTOR_SIZE
, "");
193 _Static_assert(sizeof(fixed_uint64_t
) == VECTOR_SIZE
, "");
195 _Static_assert(sizeof(fixed_float16_t
) == VECTOR_SIZE
, "");
196 _Static_assert(sizeof(fixed_float32_t
) == VECTOR_SIZE
, "");
197 _Static_assert(sizeof(fixed_float64_t
) == VECTOR_SIZE
, "");
199 _Static_assert(sizeof(fixed_bfloat16_t
) == VECTOR_SIZE
, "");
201 _Static_assert(sizeof(fixed_bool_t
) == PRED_SIZE
, "");
203 // --------------------------------------------------------------------------//
206 #define VECTOR_ALIGN 16
209 _Static_assert(__alignof__(fixed_int8_t
) == VECTOR_ALIGN
, "");
210 _Static_assert(__alignof__(fixed_int16_t
) == VECTOR_ALIGN
, "");
211 _Static_assert(__alignof__(fixed_int32_t
) == VECTOR_ALIGN
, "");
212 _Static_assert(__alignof__(fixed_int64_t
) == VECTOR_ALIGN
, "");
214 _Static_assert(__alignof__(fixed_uint8_t
) == VECTOR_ALIGN
, "");
215 _Static_assert(__alignof__(fixed_uint16_t
) == VECTOR_ALIGN
, "");
216 _Static_assert(__alignof__(fixed_uint32_t
) == VECTOR_ALIGN
, "");
217 _Static_assert(__alignof__(fixed_uint64_t
) == VECTOR_ALIGN
, "");
219 _Static_assert(__alignof__(fixed_float16_t
) == VECTOR_ALIGN
, "");
220 _Static_assert(__alignof__(fixed_float32_t
) == VECTOR_ALIGN
, "");
221 _Static_assert(__alignof__(fixed_float64_t
) == VECTOR_ALIGN
, "");
223 _Static_assert(__alignof__(fixed_bfloat16_t
) == VECTOR_ALIGN
, "");
225 _Static_assert(__alignof__(fixed_bool_t
) == PRED_ALIGN
, "");
227 // --------------------------------------------------------------------------//
230 struct struct_int64
{ fixed_int64_t x
, y
[5]; };
231 struct struct_float64
{ fixed_float64_t x
, y
[5]; };
232 struct struct_bfloat16
{ fixed_bfloat16_t x
, y
[5]; };
233 struct struct_bool
{ fixed_bool_t x
, y
[5]; };
235 // --------------------------------------------------------------------------//
237 union union_int64
{ fixed_int64_t x
, y
[5]; };
238 union union_float64
{ fixed_float64_t x
, y
[5]; };
239 union union_bfloat16
{ fixed_bfloat16_t x
, y
[5]; };
240 union union_bool
{ fixed_bool_t x
, y
[5]; };
242 // --------------------------------------------------------------------------//
245 #define TEST_CAST_COMMON(TYPE) \
246 sv##TYPE##_t to_sv##TYPE##_t_from_fixed(fixed_##TYPE##_t x) { return x; } \
247 fixed_##TYPE##_t from_sv##TYPE##_t_to_fixed(sv##TYPE##_t x) { return x; }
249 #define TEST_CAST_GNU(PREFIX, TYPE) \
250 gnu_##TYPE##_t to_gnu_##TYPE##_t_from_##PREFIX##TYPE##_t(PREFIX##TYPE##_t x) { return x; } \
251 PREFIX##TYPE##_t from_gnu_##TYPE##_t_to_##PREFIX##TYPE##_t(gnu_##TYPE##_t x) { return x; }
253 #define TEST_CAST_VECTOR(TYPE) \
254 TEST_CAST_COMMON(TYPE) \
255 TEST_CAST_GNU(sv, TYPE) \
256 TEST_CAST_GNU(fixed_, TYPE)
258 TEST_CAST_VECTOR(int8
)
259 TEST_CAST_VECTOR(int16
)
260 TEST_CAST_VECTOR(int32
)
261 TEST_CAST_VECTOR(int64
)
262 TEST_CAST_VECTOR(uint8
)
263 TEST_CAST_VECTOR(uint16
)
264 TEST_CAST_VECTOR(uint32
)
265 TEST_CAST_VECTOR(uint64
)
266 TEST_CAST_VECTOR(float16
)
267 TEST_CAST_VECTOR(float32
)
268 TEST_CAST_VECTOR(float64
)
269 TEST_CAST_VECTOR(bfloat16
)
270 TEST_CAST_COMMON(bool)
272 // Test the implicit conversion only applies to valid types
273 fixed_bool_t
to_fixed_bool_t__from_svint32_t(svint32_t x
) { return x
; } // expected-error-re {{returning 'svint32_t' (aka '__SVInt32_t') from a function with incompatible result type 'fixed_bool_t' (vector of {{[0-9]+}} 'unsigned char' values)}}
275 // Test implicit conversion between SVE and GNU vector is invalid when
276 // __ARM_FEATURE_SVE_BITS != N
277 #if defined(__ARM_FEATURE_SVE_BITS) && __ARM_FEATURE_SVE_BITS == 512
278 typedef int32_t int4
__attribute__((vector_size(16)));
279 svint32_t
badcast(int4 x
) { return x
; } // expected-error {{returning 'int4' (vector of 4 'int32_t' values) from a function with incompatible result type 'svint32_t' (aka '__SVInt32_t')}}
282 // Test conversion between predicate and uint8 is invalid, both have the same
283 // memory representation.
284 fixed_bool_t
to_fixed_bool_t__from_svuint8_t(svuint8_t x
) { return x
; } // expected-error-re {{returning 'svuint8_t' (aka '__SVUint8_t') from a function with incompatible result type 'fixed_bool_t' (vector of {{[0-9]+}} 'unsigned char' values)}}
286 // --------------------------------------------------------------------------//
287 // Test the scalable and fixed-length types can be used interchangeably
289 svint32_t
__attribute__((overloadable
)) svfunc(svint32_t op1
, svint32_t op2
);
290 svfloat64_t
__attribute__((overloadable
)) svfunc(svfloat64_t op1
, svfloat64_t op2
);
291 svbool_t
__attribute__((overloadable
)) svfunc(svbool_t op1
, svbool_t op2
);
293 #define TEST_CALL(TYPE) \
295 call_##TYPE##_ff(fixed_##TYPE##_t op1, fixed_##TYPE##_t op2) { \
296 return svfunc(op1, op2); \
299 call_##TYPE##_fs(fixed_##TYPE##_t op1, sv##TYPE##_t op2) { \
300 return svfunc(op1, op2); \
303 call_##TYPE##_sf(sv##TYPE##_t op1, fixed_##TYPE##_t op2) { \
304 return svfunc(op1, op2); \
311 // --------------------------------------------------------------------------//
312 // Vector initialization
314 #if __ARM_FEATURE_SVE_BITS == 256
316 typedef svint32_t int32x8
__attribute__((arm_sve_vector_bits(N
)));
317 typedef svfloat64_t float64x4
__attribute__((arm_sve_vector_bits(N
)));
319 int32x8 foo
= {1, 2, 3, 4, 5, 6, 7, 8};
320 int32x8 foo2
= {1, 2, 3, 4, 5, 6, 7, 8, 9}; // expected-warning{{excess elements in vector initializer}}
322 float64x4 bar
= {1.0, 2.0, 3.0, 4.0};
323 float64x4 bar2
= {1.0, 2.0, 3.0, 4.0, 5.0}; // expected-warning{{excess elements in vector initializer}}
327 // --------------------------------------------------------------------------//
330 #define TEST_BINARY(TYPE, NAME, OP) \
331 TYPE NAME##_##TYPE(TYPE op1, TYPE op2) { \
334 TYPE compound##NAME##_##TYPE(TYPE op1, TYPE op2) { \
339 #define TEST_COMPARISON(TYPE, NAME, OP) \
340 TYPE NAME##_##TYPE(TYPE op1, TYPE op2) { \
344 #define TEST_UNARY(TYPE, NAME, OP) \
345 TYPE NAME##_##TYPE(TYPE op1) { \
349 #define TEST_OPS(TYPE) \
350 TEST_BINARY(TYPE, add, +) \
351 TEST_BINARY(TYPE, sub, -) \
352 TEST_BINARY(TYPE, mul, *) \
353 TEST_BINARY(TYPE, div, /) \
354 TEST_COMPARISON(TYPE, eq, ==) \
355 TEST_COMPARISON(TYPE, ne, !=) \
356 TEST_COMPARISON(TYPE, lt, <) \
357 TEST_COMPARISON(TYPE, gt, >) \
358 TEST_COMPARISON(TYPE, lte, <=) \
359 TEST_COMPARISON(TYPE, gte, >=) \
360 TEST_UNARY(TYPE, nop, +) \
361 TEST_UNARY(TYPE, neg, -)
363 #define TEST_INT_OPS(TYPE) \
365 TEST_BINARY(TYPE, mod, %) \
366 TEST_BINARY(TYPE, and, &) \
367 TEST_BINARY(TYPE, or, |) \
368 TEST_BINARY(TYPE, xor, ^) \
369 TEST_BINARY(TYPE, shl, <<) \
370 TEST_BINARY(TYPE, shr, <<) \
371 TEST_UNARY(TYPE, not, ~)
373 TEST_INT_OPS(fixed_int8_t
)
374 TEST_INT_OPS(fixed_int16_t
)
375 TEST_INT_OPS(fixed_int32_t
)
376 TEST_INT_OPS(fixed_int64_t
)
377 TEST_INT_OPS(fixed_uint8_t
)
378 TEST_INT_OPS(fixed_uint16_t
)
379 TEST_INT_OPS(fixed_uint32_t
)
380 TEST_INT_OPS(fixed_uint64_t
)
382 TEST_OPS(fixed_float16_t
)
383 TEST_OPS(fixed_float32_t
)
384 TEST_OPS(fixed_float64_t
)