1 // RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s
2 typedef unsigned cond_t;
3 
4 volatile cond_t test;
5 volatile __fp16 h0 = 0.0, h1 = 1.0, h2;
6 volatile float f0, f1, f2;
7 
8 void foo(void) {
9   // CHECK: define void @foo()
10 
11   // Check unary ops
12 
13   // CHECK: call float @llvm.convert.from.fp16
14   // CHECK fptoi float
15   test = (h0);
16   // CHECK: call float @llvm.convert.from.fp16
17   // CHECK: fcmp une float
18   test = (!h1);
19   // CHECK: call float @llvm.convert.from.fp16
20   // CHECK: fsub float
21   // CHECK: call i16 @llvm.convert.to.fp16
22   h1 = -h1;
23   // CHECK: call float @llvm.convert.from.fp16
24   // CHECK: call i16 @llvm.convert.to.fp16
25   h1 = +h1;
26   // CHECK: call float @llvm.convert.from.fp16
27   // CHECK: fadd float
28   // CHECK: call i16 @llvm.convert.to.fp16
29   h1++;
30   // CHECK: call float @llvm.convert.from.fp16
31   // CHECK: fadd float
32   // CHECK: call i16 @llvm.convert.to.fp16
33   ++h1;
34   // CHECK: call float @llvm.convert.from.fp16
35   // CHECK: fadd float
36   // CHECK: call i16 @llvm.convert.to.fp16
37   --h1;
38   // CHECK: call float @llvm.convert.from.fp16
39   // CHECK: fadd float
40   // CHECK: call i16 @llvm.convert.to.fp16
41   h1--;
42 
43   // Check binary ops with various operands
44   // CHECK: call float @llvm.convert.from.fp16
45   // CHECK: call float @llvm.convert.from.fp16
46   // CHECK: fmul float
47   // CHECK: call i16 @llvm.convert.to.fp16
48   h1 = h0 * h2;
49   // CHECK: call float @llvm.convert.from.fp16
50   // CHECK: call i16 @llvm.convert.to.fp16
51   // CHECK: call float @llvm.convert.from.fp16
52   // CHECK: fmul float
53   // CHECK: call i16 @llvm.convert.to.fp16
54   h1 = h0 * (__fp16) -2.0;
55   // CHECK: call float @llvm.convert.from.fp16
56   // CHECK: fmul float
57   // CHECK: call i16 @llvm.convert.to.fp16
58   h1 = h0 * f2;
59   // CHECK: call float @llvm.convert.from.fp16
60   // CHECK: fmul float
61   // CHECK: call i16 @llvm.convert.to.fp16
62   h1 = f0 * h2;
63 
64   // CHECK: call float @llvm.convert.from.fp16
65   // CHECK: call float @llvm.convert.from.fp16
66   // CHECK: fdiv float
67   // CHECK: call i16 @llvm.convert.to.fp16
68   h1 = (h0 / h2);
69   // CHECK: call float @llvm.convert.from.fp16
70   // CHECK: call float @llvm.convert.from.fp16
71   // CHECK: fdiv float
72   // CHECK: call i16 @llvm.convert.to.fp16
73   h1 = (h0 / (__fp16) -2.0);
74   // CHECK: call float @llvm.convert.from.fp16
75   // CHECK: fdiv float
76   // CHECK: call i16 @llvm.convert.to.fp16
77   h1 = (h0 / f2);
78   // CHECK: call float @llvm.convert.from.fp16
79   // CHECK: fdiv float
80   // CHECK: call i16 @llvm.convert.to.fp16
81   h1 = (f0 / h2);
82 
83   // CHECK: call float @llvm.convert.from.fp16
84   // CHECK: call float @llvm.convert.from.fp16
85   // CHECK: fadd float
86   // CHECK: call i16 @llvm.convert.to.fp16
87   h1 = (h2 + h0);
88   // CHECK: call float @llvm.convert.from.fp16
89   // CHECK: call float @llvm.convert.from.fp16
90   // CHECK: fadd float
91   // CHECK: call i16 @llvm.convert.to.fp16
92   h1 = ((__fp16)-2.0 + h0);
93   // CHECK: call float @llvm.convert.from.fp16
94   // CHECK: fadd float
95   // CHECK: call i16 @llvm.convert.to.fp16
96   h1 = (h2 + f0);
97   // CHECK: call float @llvm.convert.from.fp16
98   // CHECK: fadd float
99   // CHECK: call i16 @llvm.convert.to.fp16
100   h1 = (f2 + h0);
101 
102   // CHECK: call float @llvm.convert.from.fp16
103   // CHECK: call float @llvm.convert.from.fp16
104   // CHECK: fsub float
105   // CHECK: call i16 @llvm.convert.to.fp16
106   h1 = (h2 - h0);
107   // CHECK: call float @llvm.convert.from.fp16
108   // CHECK: call float @llvm.convert.from.fp16
109   // CHECK: fsub float
110   // CHECK: call i16 @llvm.convert.to.fp16
111   h1 = ((__fp16)-2.0 - h0);
112   // CHECK: call float @llvm.convert.from.fp16
113   // CHECK: fsub float
114   // CHECK: call i16 @llvm.convert.to.fp16
115   h1 = (h2 - f0);
116   // CHECK: call float @llvm.convert.from.fp16
117   // CHECK: fsub float
118   // CHECK: call i16 @llvm.convert.to.fp16
119   h1 = (f2 - h0);
120 
121   // CHECK: call float @llvm.convert.from.fp16
122   // CHECK: call float @llvm.convert.from.fp16
123   // CHECK: fcmp olt
124   test = (h2 < h0);
125   // CHECK: call float @llvm.convert.from.fp16
126   // CHECK: call float @llvm.convert.from.fp16
127   // CHECK: fcmp olt
128   test = (h2 < (__fp16)42.0);
129   // CHECK: call float @llvm.convert.from.fp16
130   // CHECK: fcmp olt
131   test = (h2 < f0);
132   // CHECK: call float @llvm.convert.from.fp16
133   // CHECK: fcmp olt
134   test = (f2 < h0);
135 
136   // CHECK: call float @llvm.convert.from.fp16
137   // CHECK: call float @llvm.convert.from.fp16
138   // CHECK: fcmp ogt
139   test = (h0 > h2);
140   // CHECK: call float @llvm.convert.from.fp16
141   // CHECK: call float @llvm.convert.from.fp16
142   // CHECK: fcmp ogt
143   test = ((__fp16)42.0 > h2);
144   // CHECK: call float @llvm.convert.from.fp16
145   // CHECK: fcmp ogt
146   test = (h0 > f2);
147   // CHECK: call float @llvm.convert.from.fp16
148   // CHECK: fcmp ogt
149   test = (f0 > h2);
150 
151   // CHECK: call float @llvm.convert.from.fp16
152   // CHECK: call float @llvm.convert.from.fp16
153   // CHECK: fcmp ole
154   test = (h2 <= h0);
155   // CHECK: call float @llvm.convert.from.fp16
156   // CHECK: call float @llvm.convert.from.fp16
157   // CHECK: fcmp ole
158   test = (h2 <= (__fp16)42.0);
159   // CHECK: call float @llvm.convert.from.fp16
160   // CHECK: fcmp ole
161   test = (h2 <= f0);
162   // CHECK: call float @llvm.convert.from.fp16
163   // CHECK: fcmp ole
164   test = (f2 <= h0);
165 
166   // CHECK: call float @llvm.convert.from.fp16
167   // CHECK: call float @llvm.convert.from.fp16
168   // CHECK: fcmp oge
169   test = (h0 >= h2);
170   // CHECK: call float @llvm.convert.from.fp16
171   // CHECK: call float @llvm.convert.from.fp16
172   // CHECK: fcmp oge
173   test = (h0 >= (__fp16)-2.0);
174   // CHECK: call float @llvm.convert.from.fp16
175   // CHECK: fcmp oge
176   test = (h0 >= f2);
177   // CHECK: call float @llvm.convert.from.fp16
178   // CHECK: fcmp oge
179   test = (f0 >= h2);
180 
181   // CHECK: call float @llvm.convert.from.fp16
182   // CHECK: call float @llvm.convert.from.fp16
183   // CHECK: fcmp oeq
184   test = (h1 == h2);
185   // CHECK: call float @llvm.convert.from.fp16
186   // CHECK: call float @llvm.convert.from.fp16
187   // CHECK: fcmp oeq
188   test = (h1 == (__fp16)1.0);
189   // CHECK: call float @llvm.convert.from.fp16
190   // CHECK: fcmp oeq
191   test = (h1 == f1);
192   // CHECK: call float @llvm.convert.from.fp16
193   // CHECK: fcmp oeq
194   test = (f1 == h1);
195 
196   // CHECK: call float @llvm.convert.from.fp16
197   // CHECK: call float @llvm.convert.from.fp16
198   // CHECK: fcmp une
199   test = (h1 != h2);
200   // CHECK: call float @llvm.convert.from.fp16
201   // CHECK: call float @llvm.convert.from.fp16
202   // CHECK: fcmp une
203   test = (h1 != (__fp16)1.0);
204   // CHECK: call float @llvm.convert.from.fp16
205   // CHECK: fcmp une
206   test = (h1 != f1);
207   // CHECK: call float @llvm.convert.from.fp16
208   // CHECK: fcmp une
209   test = (f1 != h1);
210 
211   // CHECK: call float @llvm.convert.from.fp16
212   // CHECK: fcmp une
213   // CHECK: call float @llvm.convert.from.fp16
214   // CHECK: call float @llvm.convert.from.fp16
215   // CHECK: call i16 @llvm.convert.to.fp16
216   h1 = (h1 ? h2 : h0);
217   // Check assignments (inc. compound)
218   h0 = h1;
219   // CHECK: call i16 @llvm.convert.to.fp16
220   h0 = (__fp16)-2.0;
221   // CHECK: call i16 @llvm.convert.to.fp16
222   h0 = f0;
223 
224   // CHECK: call float @llvm.convert.from.fp16
225   // CHECK: call float @llvm.convert.from.fp16
226   // CHECK: fadd float
227   // CHECK: call i16 @llvm.convert.to.fp16
228   h0 += h1;
229   // CHECK: call float @llvm.convert.from.fp16
230   // CHECK: call float @llvm.convert.from.fp16
231   // CHECK: fadd
232   // CHECK: call i16 @llvm.convert.to.fp16
233   h0 += (__fp16)1.0;
234   // CHECK: call float @llvm.convert.from.fp16
235   // CHECK: fadd
236   // CHECK: call i16 @llvm.convert.to.fp16
237   h0 += f2;
238 
239   // CHECK: call float @llvm.convert.from.fp16
240   // CHECK: call float @llvm.convert.from.fp16
241   // CHECK: fsub
242   // CHECK: call i16 @llvm.convert.to.fp16
243   h0 -= h1;
244   // CHECK: call float @llvm.convert.from.fp16
245   // CHECK: call float @llvm.convert.from.fp16
246   // CHECK: fsub
247   // CHECK: call i16 @llvm.convert.to.fp16
248   h0 -= (__fp16)1.0;
249   // CHECK: call float @llvm.convert.from.fp16
250   // CHECK: fsub
251   // CHECK: call i16 @llvm.convert.to.fp16
252   h0 -= f2;
253 
254   // CHECK: call float @llvm.convert.from.fp16
255   // CHECK: call float @llvm.convert.from.fp16
256   // CHECK: fmul
257   // CHECK: call i16 @llvm.convert.to.fp16
258   h0 *= h1;
259   // CHECK: call float @llvm.convert.from.fp16
260   // CHECK: call float @llvm.convert.from.fp16
261   // CHECK: fmul
262   // CHECK: call i16 @llvm.convert.to.fp16
263   h0 *= (__fp16)1.0;
264   // CHECK: call float @llvm.convert.from.fp16
265   // CHECK: fmul
266   // CHECK: call i16 @llvm.convert.to.fp16
267   h0 *= f2;
268 
269   // CHECK: call float @llvm.convert.from.fp16
270   // CHECK: call float @llvm.convert.from.fp16
271   // CHECK: fdiv
272   // CHECK: call i16 @llvm.convert.to.fp16
273   h0 /= h1;
274   // CHECK: call float @llvm.convert.from.fp16
275   // CHECK: call float @llvm.convert.from.fp16
276   // CHECK: fdiv
277   // CHECK: call i16 @llvm.convert.to.fp16
278   h0 /= (__fp16)1.0;
279   // CHECK: call float @llvm.convert.from.fp16
280   // CHECK: fdiv
281   // CHECK: call i16 @llvm.convert.to.fp16
282   h0 /= f2;
283 }
284