xref: /aosp_15_r20/external/clang/test/Sema/vector-cast.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only %s -verify -Wvector-conversion
2*67e74705SXin Li 
3*67e74705SXin Li typedef long long t1 __attribute__ ((vector_size (8)));
4*67e74705SXin Li typedef char t2 __attribute__ ((vector_size (16)));
5*67e74705SXin Li typedef float t3 __attribute__ ((vector_size (16)));
6*67e74705SXin Li typedef short s2 __attribute__ ((vector_size(4)));
7*67e74705SXin Li 
8*67e74705SXin Li typedef enum { Evalue = 0x10000 } E;
9*67e74705SXin Li 
f()10*67e74705SXin Li void f()
11*67e74705SXin Li {
12*67e74705SXin Li   t1 v1;
13*67e74705SXin Li   t2 v2;
14*67e74705SXin Li   t3 v3;
15*67e74705SXin Li   s2 v4;
16*67e74705SXin Li   E e;
17*67e74705SXin Li 
18*67e74705SXin Li   e = (E)v4;
19*67e74705SXin Li   v4 = (s2)e;
20*67e74705SXin Li 
21*67e74705SXin Li   v2 = (t2)v1; // expected-error {{invalid conversion between vector type \
22*67e74705SXin Li 't2' (vector of 16 'char' values) and 't1' (vector of 1 'long long' value) of different size}}
23*67e74705SXin Li   v1 = (t1)v2; // expected-error {{invalid conversion between vector type \
24*67e74705SXin Li 't1' (vector of 1 'long long' value) and 't2' (vector of 16 'char' values) of different size}}
25*67e74705SXin Li   v3 = (t3)v2;
26*67e74705SXin Li 
27*67e74705SXin Li   v1 = (t1)(char *)10; // expected-error {{invalid conversion between vector \
28*67e74705SXin Li type 't1' (vector of 1 'long long' value) and scalar type 'char *'}}
29*67e74705SXin Li   v1 = (t1)(long long)10;
30*67e74705SXin Li   v1 = (t1)(short)10; // expected-error {{invalid conversion between vector \
31*67e74705SXin Li type 't1' (vector of 1 'long long' value) and integer type 'short' of different size}}
32*67e74705SXin Li 
33*67e74705SXin Li   long long r1 = (long long)v1;
34*67e74705SXin Li   short r2 = (short)v1; // expected-error {{invalid conversion between vector \
35*67e74705SXin Li type 't1' (vector of 1 'long long' value) and integer type 'short' of different size}}
36*67e74705SXin Li   char *r3 = (char *)v1; // expected-error {{invalid conversion between vector\
37*67e74705SXin Li  type 't1' (vector of 1 'long long' value) and scalar type 'char *'}}
38*67e74705SXin Li }
39*67e74705SXin Li 
40*67e74705SXin Li 
41*67e74705SXin Li void f2(t2 X); // expected-note{{passing argument to parameter 'X' here}}
42*67e74705SXin Li 
f3(t3 Y)43*67e74705SXin Li void f3(t3 Y) {
44*67e74705SXin Li   f2(Y);  // expected-warning {{incompatible vector types passing 't3' (vector of 4 'float' values) to parameter of type 't2' (vector of 16 'char' values)}}
45*67e74705SXin Li }
46*67e74705SXin Li 
47*67e74705SXin Li typedef float float2 __attribute__ ((vector_size (8)));
48*67e74705SXin Li typedef __attribute__((vector_size(8))) double float64x1_t;
49*67e74705SXin Li typedef __attribute__((vector_size(16))) double float64x2_t;
50*67e74705SXin Li float64x1_t vget_low_f64(float64x2_t __p0);
51*67e74705SXin Li 
f4()52*67e74705SXin Li void f4() {
53*67e74705SXin Li   float2 f2;
54*67e74705SXin Li   double d, a, b, c;
55*67e74705SXin Li   float64x2_t v = {0.0, 1.0};
56*67e74705SXin Li   f2 += d;
57*67e74705SXin Li   a = 3.0 + vget_low_f64(v);
58*67e74705SXin Li   b = vget_low_f64(v) + 3.0;
59*67e74705SXin Li   c = vget_low_f64(v);
60*67e74705SXin Li   // LAX conversions within compound assignments are not supported.
61*67e74705SXin Li   // FIXME: This diagnostic is inaccurate.
62*67e74705SXin Li   d += f2; // expected-error {{cannot convert between vector values of different size}}
63*67e74705SXin Li   c -= vget_low_f64(v); // expected-error {{cannot convert between vector values of different size}}
64*67e74705SXin Li   // LAX conversions between scalar and vector types require same size and one element sized vectors.
65*67e74705SXin Li   d = f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
66*67e74705SXin Li   d = d + f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
67*67e74705SXin Li }
68*67e74705SXin Li 
69*67e74705SXin Li // rdar://15931426
70*67e74705SXin Li // Don't permit a lax conversion to and from a pointer type.
71*67e74705SXin Li typedef short short_sizeof_pointer __attribute__((vector_size(sizeof(void*))));
f5()72*67e74705SXin Li void f5() {
73*67e74705SXin Li   short_sizeof_pointer v;
74*67e74705SXin Li   void *ptr;
75*67e74705SXin Li   v = ptr; // expected-error-re {{assigning to 'short_sizeof_pointer' (vector of {{[0-9]+}} 'short' values) from incompatible type 'void *'}}
76*67e74705SXin Li   ptr = v; // expected-error {{assigning to 'void *' from incompatible type 'short_sizeof_pointer'}}
77*67e74705SXin Li }
78