Skip to content

Commit e9bcddd

Browse files
committedMay 14, 2015
Add flag to enable native half type
Summary: r235215 enables support in LLVM for legalizing f16 type in the IR. AArch64 already had support for this. r235215 and some backend patches brought support for ARM, X86, X86-64, Mips and Mips64. This change exposes the LangOption 'NativeHalfType' in the command line, so the backend legalization can be used if desired. NativeHalfType is enabled for OpenCL (current behavior) or if '-fnative-half-type' is set. Reviewers: olista01, steven_wu, ab Subscribers: cfe-commits, srhines, aemerson Differential Revision: http://reviews.llvm.org/D9781 llvm-svn: 237406
1 parent ffc2009 commit e9bcddd

File tree

3 files changed

+142
-37
lines changed

3 files changed

+142
-37
lines changed
 

‎clang/include/clang/Driver/CC1Options.td

+2
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,8 @@ def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">,
547547
HelpText<"Control vtordisp placement on win32 targets">;
548548
def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
549549
HelpText<"Control emission of RTTI data">;
550+
def fnative_half_type: Flag<["-"], "fnative-half-type">,
551+
HelpText<"Use the native half type for __fp16 instead of promoting to float">;
550552
def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
551553
HelpText<"Allow function arguments and returns of type half">;
552554

‎clang/lib/Frontend/CompilerInvocation.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1587,7 +1587,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
15871587
Opts.ImplementationOfModule =
15881588
Args.getLastArgValue(OPT_fmodule_implementation_of);
15891589
Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
1590-
Opts.NativeHalfType = Opts.NativeHalfType;
1590+
Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type);
15911591
Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);
15921592
Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
15931593

‎clang/test/CodeGen/fp16-ops.c

+139-36
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
44
// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=HALF --check-prefix=CHECK
55
// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=HALF --check-prefix=CHECK
6+
// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \
7+
// RUN: | FileCheck %s --check-prefix=NATIVE-HALF
8+
// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fnative-half-type %s \
9+
// RUN: | FileCheck %s --check-prefix=NATIVE-HALF
610
typedef unsigned cond_t;
711

812
volatile cond_t test;
@@ -18,297 +22,396 @@ void foo(void) {
1822
// NOHALF: [[F16TOF32:call float @llvm.convert.from.fp16.f32]]
1923
// HALF: [[F16TOF32:fpext half]]
2024
// CHECK: fptoui float
25+
// NATIVE-HALF: fptoui half
2126
test = (h0);
2227
// CHECK: uitofp i32
2328
// NOHALF: [[F32TOF16:call i16 @llvm.convert.to.fp16.f32]]
2429
// HALF: [[F32TOF16:fptrunc float]]
30+
// NATIVE-HALF: uitofp i32 {{.*}} to half
2531
h0 = (test);
2632
// CHECK: [[F16TOF32]]
2733
// CHECK: fcmp une float
34+
// NATIVE-HALF: fcmp une half
2835
test = (!h1);
2936
// CHECK: [[F16TOF32]]
3037
// CHECK: fsub float
3138
// NOHALF: [[F32TOF16]]
3239
// HALF: [[F32TOF16]]
40+
// NATIVE-HALF: fsub half
3341
h1 = -h1;
3442
// CHECK: [[F16TOF32]]
3543
// CHECK: [[F32TOF16]]
44+
// NATIVE-HALF: load volatile half
45+
// NATIVE-HALF-NEXT: store volatile half
3646
h1 = +h1;
3747
// CHECK: [[F16TOF32]]
3848
// CHECK: fadd float
3949
// CHECK: [[F32TOF16]]
50+
// NATIVE-HALF: fadd half
4051
h1++;
4152
// CHECK: [[F16TOF32]]
4253
// CHECK: fadd float
4354
// CHECK: [[F32TOF16]]
55+
// NATIVE-HALF: fadd half
4456
++h1;
4557
// CHECK: [[F16TOF32]]
4658
// CHECK: fadd float
4759
// CHECK: [[F32TOF16]]
60+
// NATIVE-HALF: fadd half
4861
--h1;
4962
// CHECK: [[F16TOF32]]
5063
// CHECK: fadd float
5164
// CHECK: [[F32TOF16]]
65+
// NATIVE-HALF: fadd half
5266
h1--;
5367

5468
// Check binary ops with various operands
5569
// CHECK: [[F16TOF32]]
5670
// CHECK: [[F16TOF32]]
5771
// CHECK: fmul float
5872
// CHECK: [[F32TOF16]]
73+
// NATIVE-HALF: fmul half
5974
h1 = h0 * h2;
6075
// CHECK: [[F16TOF32]]
6176
// NOHALF: [[F32TOF16]]
6277
// NOHALF: [[F16TOF32]]
6378
// CHECK: fmul float
6479
// CHECK: [[F32TOF16]]
80+
// NATIVE-HALF: fmul half
6581
h1 = h0 * (__fp16) -2.0f;
6682
// CHECK: [[F16TOF32]]
6783
// CHECK: fmul float
6884
// CHECK: [[F32TOF16]]
85+
// NATIVE-HALF: fpext half
86+
// NATIVE-HALF: fmul float
6987
h1 = h0 * f2;
7088
// CHECK: [[F16TOF32]]
7189
// CHECK: fmul float
7290
// CHECK: [[F32TOF16]]
91+
// NATIVE-HALF: fpext half
92+
// NATIVE-HALF: fmul float
7393
h1 = f0 * h2;
7494

7595
// CHECK: [[F16TOF32]]
7696
// CHECK: [[F16TOF32]]
7797
// CHECK: fdiv float
7898
// CHECK: [[F32TOF16]]
99+
// NATIVE-HALF: fdiv half
79100
h1 = (h0 / h2);
80101
// CHECK: [[F16TOF32]]
81102
// NOHALF: [[F16TOF32]]
82103
// CHECK: fdiv float
83104
// CHECK: [[F32TOF16]]
105+
// NATIVE-HALF: fdiv half
84106
h1 = (h0 / (__fp16) -2.0f);
85107
// CHECK: [[F16TOF32]]
86108
// CHECK: fdiv float
87109
// CHECK: [[F32TOF16]]
110+
// NATIVE-HALF: fpext half
111+
// NATIVE-HALF: fdiv float
88112
h1 = (h0 / f2);
89113
// CHECK: [[F16TOF32]]
90114
// CHECK: fdiv float
91115
// CHECK: [[F32TOF16]]
116+
// NATIVE-HALF: fpext half
117+
// NATIVE-HALF: fdiv float
92118
h1 = (f0 / h2);
93119

94120
// CHECK: [[F16TOF32]]
95121
// CHECK: [[F16TOF32]]
96122
// CHECK: fadd float
97123
// CHECK: [[F32TOF16]]
124+
// NATIVE-HALF: fadd half
98125
h1 = (h2 + h0);
99126
// CHECK: [[F16TOF32]]
100127
// NOHALF: [[F16TOF32]]
101128
// CHECK: fadd float
102129
// CHECK: [[F32TOF16]]
130+
// NATIVE-HALF: fadd half
103131
h1 = ((__fp16)-2.0 + h0);
104132
// CHECK: [[F16TOF32]]
105133
// CHECK: fadd float
106134
// CHECK: [[F32TOF16]]
135+
// NATIVE-HALF: fpext half
136+
// NATIVE-HALF: fadd float
107137
h1 = (h2 + f0);
108138
// CHECK: [[F16TOF32]]
109139
// CHECK: fadd float
110140
// CHECK: [[F32TOF16]]
141+
// NATIVE-HALF: fpext half
142+
// NATIVE-HALF: fadd float
111143
h1 = (f2 + h0);
112144

113145
// CHECK: [[F16TOF32]]
114146
// CHECK: [[F16TOF32]]
115147
// CHECK: fsub float
116148
// CHECK: [[F32TOF16]]
149+
// NATIVE-HALF: fsub half
117150
h1 = (h2 - h0);
118151
// CHECK: [[F16TOF32]]
119152
// NOHALF: [[F16TOF32]]
120153
// CHECK: fsub float
121154
// CHECK: [[F32TOF16]]
155+
// NATIVE-HALF: fsub half
122156
h1 = ((__fp16)-2.0f - h0);
123157
// CHECK: [[F16TOF32]]
124158
// CHECK: fsub float
125159
// CHECK: [[F32TOF16]]
160+
// NATIVE-HALF: fpext half
161+
// NATIVE-HALF: fsub float
126162
h1 = (h2 - f0);
127163
// CHECK: [[F16TOF32]]
128164
// CHECK: fsub float
129165
// CHECK: [[F32TOF16]]
166+
// NATIVE-HALF: fpext half
167+
// NATIVE-HALF: fsub float
130168
h1 = (f2 - h0);
131169

132170
// CHECK: [[F16TOF32]]
133171
// CHECK: [[F16TOF32]]
134-
// CHECK: fcmp olt
172+
// CHECK: fcmp olt float
173+
// NATIVE-HALF: fcmp olt half
135174
test = (h2 < h0);
136175
// CHECK: [[F16TOF32]]
137176
// NOHALF: [[F16TOF32]]
138-
// CHECK: fcmp olt
177+
// CHECK: fcmp olt float
178+
// NATIVE-HALF: fcmp olt half
139179
test = (h2 < (__fp16)42.0);
140180
// CHECK: [[F16TOF32]]
141-
// CHECK: fcmp olt
181+
// CHECK: fcmp olt float
182+
// NATIVE-HALF: fpext half
183+
// NATIVE-HALF: fcmp olt float
142184
test = (h2 < f0);
143185
// CHECK: [[F16TOF32]]
144-
// CHECK: fcmp olt
186+
// CHECK: fcmp olt float
187+
// NATIVE-HALF: fpext half
188+
// NATIVE-HALF: fcmp olt float
145189
test = (f2 < h0);
146190

147191
// CHECK: [[F16TOF32]]
148192
// CHECK: [[F16TOF32]]
149-
// CHECK: fcmp ogt
193+
// CHECK: fcmp ogt float
194+
// NATIVE-HALF: fcmp ogt half
150195
test = (h0 > h2);
151196
// CHECK: [[F16TOF32]]
152197
// NOHALF: [[F16TOF32]]
153-
// CHECK: fcmp ogt
198+
// CHECK: fcmp ogt float
199+
// NATIVE-HALF: fcmp ogt half
154200
test = ((__fp16)42.0 > h2);
155201
// CHECK: [[F16TOF32]]
156-
// CHECK: fcmp ogt
202+
// CHECK: fcmp ogt float
203+
// NATIVE-HALF: fpext half
204+
// NATIVE-HALF: fcmp ogt float
157205
test = (h0 > f2);
158206
// CHECK: [[F16TOF32]]
159-
// CHECK: fcmp ogt
207+
// CHECK: fcmp ogt float
208+
// NATIVE-HALF: fpext half
209+
// NATIVE-HALF: fcmp ogt float
160210
test = (f0 > h2);
161211

162212
// CHECK: [[F16TOF32]]
163213
// CHECK: [[F16TOF32]]
164-
// CHECK: fcmp ole
214+
// CHECK: fcmp ole float
215+
// NATIVE-HALF: fcmp ole half
165216
test = (h2 <= h0);
166217
// CHECK: [[F16TOF32]]
167218
// NOHALF: [[F16TOF32]]
168-
// CHECK: fcmp ole
219+
// CHECK: fcmp ole float
220+
// NATIVE-HALF: fcmp ole half
169221
test = (h2 <= (__fp16)42.0);
170222
// CHECK: [[F16TOF32]]
171-
// CHECK: fcmp ole
223+
// CHECK: fcmp ole float
224+
// NATIVE-HALF: fpext half
225+
// NATIVE-HALF: fcmp ole float
172226
test = (h2 <= f0);
173227
// CHECK: [[F16TOF32]]
174-
// CHECK: fcmp ole
228+
// CHECK: fcmp ole float
229+
// NATIVE-HALF: fpext half
230+
// NATIVE-HALF: fcmp ole float
175231
test = (f2 <= h0);
176232

177233
// CHECK: [[F16TOF32]]
178234
// CHECK: [[F16TOF32]]
179-
// CHECK: fcmp oge
235+
// CHECK: fcmp oge float
236+
// NATIVE-HALF: fcmp oge half
180237
test = (h0 >= h2);
181238
// CHECK: [[F16TOF32]]
182239
// NOHALF: [[F16TOF32]]
183-
// CHECK: fcmp oge
240+
// CHECK: fcmp oge float
241+
// NATIVE-HALF: fcmp oge half
184242
test = (h0 >= (__fp16)-2.0);
185243
// CHECK: [[F16TOF32]]
186-
// CHECK: fcmp oge
244+
// CHECK: fcmp oge float
245+
// NATIVE-HALF: fpext half
246+
// NATIVE-HALF: fcmp oge float
187247
test = (h0 >= f2);
188248
// CHECK: [[F16TOF32]]
189-
// CHECK: fcmp oge
249+
// CHECK: fcmp oge float
250+
// NATIVE-HALF: fpext half
251+
// NATIVE-HALF: fcmp oge float
190252
test = (f0 >= h2);
191253

192254
// CHECK: [[F16TOF32]]
193255
// CHECK: [[F16TOF32]]
194-
// CHECK: fcmp oeq
256+
// CHECK: fcmp oeq float
257+
// NATIVE-HALF: fcmp oeq half
195258
test = (h1 == h2);
196259
// CHECK: [[F16TOF32]]
197260
// NOHALF: [[F16TOF32]]
198-
// CHECK: fcmp oeq
261+
// CHECK: fcmp oeq float
262+
// NATIVE-HALF: fcmp oeq half
199263
test = (h1 == (__fp16)1.0);
200264
// CHECK: [[F16TOF32]]
201-
// CHECK: fcmp oeq
265+
// CHECK: fcmp oeq float
266+
// NATIVE-HALF: fpext half
267+
// NATIVE-HALF: fcmp oeq float
202268
test = (h1 == f1);
203269
// CHECK: [[F16TOF32]]
204-
// CHECK: fcmp oeq
270+
// CHECK: fcmp oeq float
271+
// NATIVE-HALF: fpext half
272+
// NATIVE-HALF: fcmp oeq float
205273
test = (f1 == h1);
206274

207275
// CHECK: [[F16TOF32]]
208276
// CHECK: [[F16TOF32]]
209-
// CHECK: fcmp une
277+
// CHECK: fcmp une float
278+
// NATIVE-HALF: fcmp une half
210279
test = (h1 != h2);
211280
// CHECK: [[F16TOF32]]
212281
// NOHALF: [[F16TOF32]]
213-
// CHECK: fcmp une
282+
// CHECK: fcmp une float
283+
// NATIVE-HALF: fcmp une half
214284
test = (h1 != (__fp16)1.0);
215285
// CHECK: [[F16TOF32]]
216-
// CHECK: fcmp une
286+
// CHECK: fcmp une float
287+
// NATIVE-HALF: fpext half
288+
// NATIVE-HALF: fcmp une float
217289
test = (h1 != f1);
218290
// CHECK: [[F16TOF32]]
219-
// CHECK: fcmp une
291+
// CHECK: fcmp une float
292+
// NATIVE-HALF: fpext half
293+
// NATIVE-HALF: fcmp une float
220294
test = (f1 != h1);
221295

222296
// CHECK: [[F16TOF32]]
223-
// CHECK: fcmp une
297+
// CHECK: fcmp une float
224298
// CHECK: [[F16TOF32]]
225299
// CHECK: [[F16TOF32]]
226300
// CHECK: [[F32TOF16]]
301+
// NATIVE-HALF: fcmp une half {{.*}}, 0xH0000
227302
h1 = (h1 ? h2 : h0);
228303
// Check assignments (inc. compound)
229304
h0 = h1;
230305
// NOHALF: [[F32TOF16]]
231306
// HALF: store {{.*}} half 0xHC000
307+
// NATIVE-HALF: store {{.*}} half 0xHC000
232308
h0 = (__fp16)-2.0f;
233309
// CHECK: [[F32TOF16]]
310+
// NATIVE-HALF: fptrunc float
234311
h0 = f0;
235312

236313
// CHECK: [[F16TOF32]]
237314
// CHECK: [[F16TOF32]]
238315
// CHECK: fadd float
239316
// CHECK: [[F32TOF16]]
317+
// NATIVE-HALF: fadd half
240318
h0 += h1;
241319
// CHECK: [[F16TOF32]]
242320
// NOHALF: [[F16TOF32]]
243-
// CHECK: fadd
321+
// CHECK: fadd float
244322
// CHECK: [[F32TOF16]]
323+
// NATIVE-HALF: fadd half
245324
h0 += (__fp16)1.0f;
246325
// CHECK: [[F16TOF32]]
247-
// CHECK: fadd
326+
// CHECK: fadd float
248327
// CHECK: [[F32TOF16]]
328+
// NATIVE-HALF: fpext half
329+
// NATIVE-HALF: fadd float
330+
// NATIVE-HALF: fptrunc float
249331
h0 += f2;
250332

251333
// CHECK: [[F16TOF32]]
252334
// CHECK: [[F16TOF32]]
253-
// CHECK: fsub
335+
// CHECK: fsub float
254336
// CHECK: [[F32TOF16]]
337+
// NATIVE-HALF: fsub half
255338
h0 -= h1;
256339
// CHECK: [[F16TOF32]]
257340
// NOHALF: [[F16TOF32]]
258-
// CHECK: fsub
341+
// CHECK: fsub float
259342
// CHECK: [[F32TOF16]]
343+
// NATIVE-HALF: fsub half
260344
h0 -= (__fp16)1.0;
261345
// CHECK: [[F16TOF32]]
262-
// CHECK: fsub
346+
// CHECK: fsub float
263347
// CHECK: [[F32TOF16]]
348+
// NATIVE-HALF: fpext half
349+
// NATIVE-HALF: fsub float
350+
// NATIVE-HALF: fptrunc float
264351
h0 -= f2;
265352

266353
// CHECK: [[F16TOF32]]
267354
// CHECK: [[F16TOF32]]
268-
// CHECK: fmul
355+
// CHECK: fmul float
269356
// CHECK: [[F32TOF16]]
357+
// NATIVE-HALF: fmul half
270358
h0 *= h1;
271359
// CHECK: [[F16TOF32]]
272360
// NOHALF: [[F16TOF32]]
273-
// CHECK: fmul
361+
// CHECK: fmul float
274362
// CHECK: [[F32TOF16]]
363+
// NATIVE-HALF: fmul half
275364
h0 *= (__fp16)1.0;
276365
// CHECK: [[F16TOF32]]
277-
// CHECK: fmul
366+
// CHECK: fmul float
278367
// CHECK: [[F32TOF16]]
368+
// NATIVE-HALF: fpext half
369+
// NATIVE-HALF: fmul float
370+
// NATIVE-HALF: fptrunc float
279371
h0 *= f2;
280372

281373
// CHECK: [[F16TOF32]]
282374
// CHECK: [[F16TOF32]]
283-
// CHECK: fdiv
375+
// CHECK: fdiv float
284376
// CHECK: [[F32TOF16]]
377+
// NATIVE-HALF: fdiv half
285378
h0 /= h1;
286379
// CHECK: [[F16TOF32]]
287380
// NOHALF: [[F16TOF32]]
288-
// CHECK: fdiv
381+
// CHECK: fdiv float
289382
// CHECK: [[F32TOF16]]
383+
// NATIVE-HALF: fdiv half
290384
h0 /= (__fp16)1.0;
291385
// CHECK: [[F16TOF32]]
292-
// CHECK: fdiv
386+
// CHECK: fdiv float
293387
// CHECK: [[F32TOF16]]
388+
// NATIVE-HALF: fpext half
389+
// NATIVE-HALF: fdiv float
390+
// NATIVE-HALF: fptrunc float
294391
h0 /= f2;
295392

296393
// Check conversions to/from double
297394
// NOHALF: call i16 @llvm.convert.to.fp16.f64(
298395
// HALF: fptrunc double {{.*}} to half
396+
// NATIVE-HALF: fptrunc double {{.*}} to half
299397
h0 = d0;
300398

301399
// CHECK: [[MID:%.*]] = fptrunc double {{%.*}} to float
302400
// NOHALF: call i16 @llvm.convert.to.fp16.f32(float [[MID]])
303401
// HALF: fptrunc float [[MID]] to half
402+
// NATIVE-HALF: [[MID:%.*]] = fptrunc double {{%.*}} to float
403+
// NATIVE-HALF: fptrunc float {{.*}} to half
304404
h0 = (float)d0;
305405

306406
// NOHALF: call double @llvm.convert.from.fp16.f64(
307407
// HALF: fpext half {{.*}} to double
408+
// NATIVE-HALF: fpext half {{.*}} to double
308409
d0 = h0;
309410

310411
// NOHALF: [[MID:%.*]] = call float @llvm.convert.from.fp16.f32(
311412
// HALF: [[MID:%.*]] = fpext half {{.*}} to float
312413
// CHECK: fpext float [[MID]] to double
414+
// NATIVE-HALF: [[MID:%.*]] = fpext half {{.*}} to float
415+
// NATIVE-HALF: fpext float [[MID]] to double
313416
d0 = (float)h0;
314417
}

0 commit comments

Comments
 (0)
Please sign in to comment.