1 // RUN: %clang_cc1 %s -triple x86_64-linux-gnu -Wno-unused -std=c++11 -emit-llvm -o - | FileCheck %s
2 
3 using FourShorts = short __attribute__((__vector_size__(8)));
4 using TwoInts = int __attribute__((__vector_size__(8)));
5 using TwoUInts = unsigned __attribute__((__vector_size__(8)));
6 using FourInts = int __attribute__((__vector_size__(16)));
7 using FourUInts = unsigned __attribute__((__vector_size__(16)));
8 using TwoLongLong = long long __attribute__((__vector_size__(16)));
9 using FourLongLong = long long __attribute__((__vector_size__(32)));
10 using TwoFloats = float __attribute__((__vector_size__(8)));
11 using FourFloats = float __attribute__((__vector_size__(16)));
12 using TwoDoubles = double __attribute__((__vector_size__(16)));
13 using FourDoubles = double __attribute__((__vector_size__(32)));
14 
15 FourShorts four_shorts;
16 TwoInts two_ints;
17 TwoUInts two_uints;
18 FourInts four_ints;
19 FourUInts four_uints;
20 TwoLongLong two_ll;
21 FourLongLong four_ll;
22 TwoFloats two_floats;
23 FourFloats four_floats;
24 TwoDoubles two_doubles;
25 FourDoubles four_doubles;
26 
27 short some_short;
28 unsigned short some_ushort;
29 int some_int;
30 float some_float;
31 unsigned int some_uint;
32 long long some_ll;
33 unsigned long long some_ull;
34 double some_double;
35 
36 // CHECK: TwoVectorOps
TwoVectorOps()37 void TwoVectorOps() {
38   two_ints ? two_ints : two_ints;
39   // CHECK: %[[COND:.+]] = load <2 x i32>
40   // CHECK: %[[LHS:.+]] = load <2 x i32>
41   // CHECK: %[[RHS:.+]] = load <2 x i32>
42   // CHECK: %[[NEZERO:.+]] = icmp ne <2 x i32> %[[COND]], zeroinitializer
43   // CHECK: %[[SELECT:.+]] = select <2 x i1> %[[NEZERO]], <2 x i32> %[[LHS]], <2 x i32> %[[RHS]]
44 
45   two_ints ? two_floats : two_floats;
46   // CHECK: %[[COND:.+]] = load <2 x i32>
47   // CHECK: %[[LHS:.+]] = load <2 x float>
48   // CHECK: %[[RHS:.+]] = load <2 x float>
49   // CHECK: %[[NEZERO:.+]] = icmp ne <2 x i32> %[[COND]], zeroinitializer
50   // CHECK: %[[SELECT:.+]] = select <2 x i1> %[[NEZERO]], <2 x float> %[[LHS]], <2 x float> %[[RHS]]
51 
52   two_ll ? two_doubles : two_doubles;
53   // CHECK: %[[COND:.+]] = load <2 x i64>
54   // CHECK: %[[LHS:.+]] = load <2 x double>
55   // CHECK: %[[RHS:.+]] = load <2 x double>
56   // CHECK: %[[NEZERO:.+]] = icmp ne <2 x i64> %[[COND]], zeroinitializer
57   // CHECK: %[[SELECT:.+]] = select <2 x i1> %[[NEZERO]], <2 x double> %[[LHS]], <2 x double> %[[RHS]]
58 }
59 
60 // CHECK: TwoScalarOps
TwoScalarOps()61 void TwoScalarOps() {
62   four_shorts ? some_short : some_short;
63   // CHECK: %[[COND:.+]] = load <4 x i16>
64   // CHECK: %[[LHS:.+]] = load i16
65   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[LHS]], i32 0
66   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i16> %[[LHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer
67   // CHECK: %[[RHS:.+]] = load i16
68   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[RHS]], i32 0
69   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i16> %[[RHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer
70   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i16> %[[COND]], zeroinitializer
71   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i16> %[[LHS_SPLAT]], <4 x i16> %[[RHS_SPLAT]]
72 
73   four_shorts ? some_ushort : some_ushort;
74   // CHECK: %[[COND:.+]] = load <4 x i16>
75   // CHECK: %[[LHS:.+]] = load i16
76   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[LHS]], i32 0
77   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i16> %[[LHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer
78   // CHECK: %[[RHS:.+]] = load i16
79   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i16> poison, i16 %[[RHS]], i32 0
80   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i16> %[[RHS_SPLAT_INSERT]], <4 x i16> poison, <4 x i32> zeroinitializer
81   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i16> %[[COND]], zeroinitializer
82   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i16> %[[LHS_SPLAT]], <4 x i16> %[[RHS_SPLAT]]
83 
84   four_ints ? some_ushort : some_short;
85   // CHECK: %[[COND:.+]] = load <4 x i32>
86   // CHECK: %[[LHS:.+]] = load i16
87   // CHECK: %[[LHS_ZEXT:.+]] = zext i16 %[[LHS]] to i32
88   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[LHS_ZEXT]], i32 0
89   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i32> %[[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
90   // CHECK: %[[RHS:.+]] = load i16
91   // CHECK: %[[RHS_SEXT:.+]] = sext i16 %[[RHS]] to i32
92   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS_SEXT]], i32 0
93   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
94   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
95   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS_SPLAT]], <4 x i32> %[[RHS_SPLAT]]
96 
97   four_ints ? some_int : some_float;
98   // CHECK: %[[COND:.+]] = load <4 x i32>
99   // CHECK: %[[LHS:.+]] = load i32
100   // CHECK: %[[LHS_CONV:.+]] = sitofp i32 %[[LHS]] to float
101   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x float> poison, float %[[LHS_CONV]], i32 0
102   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x float> %[[LHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer
103   // CHECK: %[[RHS:.+]] = load float
104   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x float> poison, float %[[RHS]], i32 0
105   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x float> %[[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer
106   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
107   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x float> %[[LHS_SPLAT]], <4 x float> %[[RHS_SPLAT]]
108 
109   four_ll ? some_double : some_ll;
110   // CHECK: %[[COND:.+]] = load <4 x i64>
111   // CHECK: %[[LHS:.+]] = load double
112   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x double> poison, double %[[LHS]], i32 0
113   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x double> %[[LHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer
114   // CHECK: %[[RHS:.+]] = load i64
115   // CHECK: %[[RHS_CONV:.+]] = sitofp i64 %[[RHS]] to double
116   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x double> poison, double %[[RHS_CONV]], i32 0
117   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x double> %[[RHS_SPLAT_INSERT]], <4 x double> poison, <4 x i32> zeroinitializer
118   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
119   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x double> %[[LHS_SPLAT]], <4 x double> %[[RHS_SPLAT]]
120 
121   four_ints ? some_int : some_short;
122   // CHECK: %[[COND:.+]] = load <4 x i32>
123   // CHECK: %[[LHS:.+]] = load i32
124   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[LHS]], i32 0
125   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i32> %[[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
126   // CHECK: %[[RHS:.+]] = load i16
127   // CHECK: %[[RHS_SEXT:.+]] = sext i16 %[[RHS]] to i32
128   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS_SEXT]], i32 0
129   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
130   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
131   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS_SPLAT]], <4 x i32> %[[RHS_SPLAT]]
132 }
133 
134 // CHECK: OneScalarOp
OneScalarOp()135 void OneScalarOp() {
136   four_ints ? four_ints : some_int;
137   // CHECK: %[[COND:.+]] = load <4 x i32>
138   // CHECK: %[[LHS:.+]] = load <4 x i32>
139   // CHECK: %[[RHS:.+]] = load i32
140   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS]], i32 0
141   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
142   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
143   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS]], <4 x i32> %[[RHS_SPLAT]]
144 
145   four_ints ? four_ints : 5;
146   // CHECK: %[[COND:.+]] = load <4 x i32>
147   // CHECK: %[[LHS:.+]] = load <4 x i32>
148   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
149   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS]], <4 x i32> <i32 5, i32 5, i32 5, i32 5>
150 
151   four_ints ?: some_float;
152   // CHECK: %[[COND:.+]] = load <4 x i32>
153   // CHECK: %[[RHS:.+]] = load float
154   // CHECK: %[[RHS_CONV:.+]] = fptosi float %[[RHS]] to i32
155   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[RHS_CONV]], i32 0
156   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i32> %[[RHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
157   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
158   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[COND]], <4 x i32> %[[RHS_SPLAT]]
159 
160   four_ints ? four_ints : 5.0f;
161   // CHECK: %[[COND:.+]] = load <4 x i32>
162   // CHECK: %[[LHS:.+]] = load <4 x i32>
163   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
164   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS]], <4 x i32> <i32 5, i32 5, i32 5, i32 5>
165 
166   four_ints ? some_float : four_ints;
167   // CHECK: %[[COND:.+]] = load <4 x i32>
168   // CHECK: %[[LHS:.+]] = load float
169   // CHECK: %[[LHS_CONV:.+]] = fptosi float %[[LHS]] to i32
170   // CHECK: %[[LHS_SPLAT_INSERT:.+]] = insertelement <4 x i32> poison, i32 %[[LHS_CONV]], i32 0
171   // CHECK: %[[LHS_SPLAT:.+]] = shufflevector <4 x i32> %[[LHS_SPLAT_INSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
172   // CHECK: %[[RHS:.+]] = load <4 x i32>
173   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
174   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i32> %[[LHS_SPLAT]], <4 x i32> %[[RHS]]
175 
176   four_ints ? four_floats : some_float;
177   // CHECK: %[[COND:.+]] = load <4 x i32>
178   // CHECK: %[[LHS:.+]] = load <4 x float>
179   // CHECK: %[[RHS:.+]] = load float
180   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x float> poison, float %[[RHS]], i32 0
181   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x float> %[[RHS_SPLAT_INSERT]], <4 x float> poison, <4 x i32> zeroinitializer
182   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i32> %[[COND]], zeroinitializer
183   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x float> %[[LHS]], <4 x float> %[[RHS_SPLAT]]
184 
185   four_ll ? four_doubles : 6.0;
186   // CHECK: %[[COND:.+]] = load <4 x i64>
187   // CHECK: %[[LHS:.+]] = load <4 x double>
188   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
189   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x double> %[[LHS]], <4 x double> <double 6.{{.+}}, double 6.{{.+}}, double 6.{{.+}}>
190 
191   four_ll ? four_ll : 6.0;
192   // CHECK: %[[COND:.+]] = load <4 x i64>
193   // CHECK: %[[LHS:.+]] = load <4 x i64>
194   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
195   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> <i64 6, i64 6, i64 6, i64 6>
196 
197   four_ll ? four_ll : 6;
198   // CHECK: %[[COND:.+]] = load <4 x i64>
199   // CHECK: %[[LHS:.+]] = load <4 x i64>
200   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
201   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> <i64 6, i64 6, i64 6, i64 6>
202 
203   four_ll ? four_ll : some_int;
204   // CHECK: %[[COND:.+]] = load <4 x i64>
205   // CHECK: %[[LHS:.+]] = load <4 x i64>
206   // CHECK: %[[RHS:.+]] = load i32
207   // CHECK: %[[RHS_CONV:.+]] = sext i32 %[[RHS]] to i64
208   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i64> poison, i64 %[[RHS_CONV]], i32 0
209   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i64> %[[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
210   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
211   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> %[[RHS_SPLAT]]
212 
213   four_ll ? four_ll : some_ll;
214   // CHECK: %[[COND:.+]] = load <4 x i64>
215   // CHECK: %[[LHS:.+]] = load <4 x i64>
216   // CHECK: %[[RHS:.+]] = load i64
217   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i64> poison, i64 %[[RHS]], i32 0
218   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i64> %[[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
219   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
220   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> %[[RHS_SPLAT]]
221 
222   four_ll ? four_ll : some_double;
223   // CHECK: %[[COND:.+]] = load <4 x i64>
224   // CHECK: %[[LHS:.+]] = load <4 x i64>
225   // CHECK: %[[RHS:.+]] = load double
226   // CHECK: %[[RHS_CONV:.+]] = fptosi double %[[RHS]] to i64
227   // CHECK: %[[RHS_SPLAT_INSERT:.+]] = insertelement <4 x i64> poison, i64 %[[RHS_CONV]], i32 0
228   // CHECK: %[[RHS_SPLAT:.+]] = shufflevector <4 x i64> %[[RHS_SPLAT_INSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
229   // CHECK: %[[NEZERO:.+]] = icmp ne <4 x i64> %[[COND]], zeroinitializer
230   // CHECK: %[[SELECT:.+]] = select <4 x i1> %[[NEZERO]], <4 x i64> %[[LHS]], <4 x i64> %[[RHS_SPLAT]]
231 }
232