Hi olista01, steven_wu, ab,

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.

http://reviews.llvm.org/D9781

Files:
  include/clang/Driver/CC1Options.td
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/fp16-ops.c

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -547,6 +547,8 @@
   HelpText<"Control vtordisp placement on win32 targets">;
 def fno_rtti_data : Flag<["-"], "fno-rtti-data">,
   HelpText<"Control emission of RTTI data">;
+def fnative_half_type: Flag<["-"], "fnative-half-type">,
+  HelpText<"Allow half types to appear natively in IR">;
 def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,
   HelpText<"Allow function arguments and returns of type half">;
 
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -1585,10 +1585,12 @@
   Opts.ImplementationOfModule =
       Args.getLastArgValue(OPT_fmodule_implementation_of);
   Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
-  Opts.NativeHalfType = Opts.NativeHalfType;
+  if (!Opts.NativeHalfType && Args.hasArg(OPT_fnative_half_type))
+    Opts.NativeHalfType = Args.hasArg(OPT_fnative_half_type);
   Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);
   Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
 
+
   if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() &&
       Opts.CurrentModule != Opts.ImplementationOfModule) {
     Diags.Report(diag::err_conflicting_module_names)
Index: test/CodeGen/fp16-ops.c
===================================================================
--- test/CodeGen/fp16-ops.c
+++ test/CodeGen/fp16-ops.c
@@ -1,8 +1,16 @@
 // REQUIRES: arm-registered-target
-// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
-// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
-// 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
-// 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
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s \
+// RUN:   | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi %s \
+// RUN:   | FileCheck %s --check-prefix=NOHALF --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fallow-half-arguments-and-returns %s \
+// RUN:   | FileCheck %s --check-prefix=HALF --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fallow-half-arguments-and-returns %s \
+// RUN:   | FileCheck %s --check-prefix=HALF --check-prefix=CHECK
+// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi -fnative-half-type %s \
+// RUN:   | FileCheck %s --check-prefix=NATIVE-HALF
+// RUN: %clang_cc1 -emit-llvm -o - -triple aarch64-none-linux-gnueabi -fnative-half-type %s \
+// RUN:   | FileCheck %s --check-prefix=NATIVE-HALF
 typedef unsigned cond_t;
 
 volatile cond_t test;
@@ -18,297 +26,396 @@
   // NOHALF: [[F16TOF32:call float @llvm.convert.from.fp16.f32]]
   // HALF: [[F16TOF32:fpext half]]
   // CHECK: fptoui float
+  // NATIVE-HALF: fptoui half
   test = (h0);
   // CHECK: uitofp i32
   // NOHALF: [[F32TOF16:call i16 @llvm.convert.to.fp16.f32]]
   // HALF: [[F32TOF16:fptrunc float]]
+  // NATIVE-HALF: uitofp i32 {{.*}} to half
   h0 = (test);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp une float
+  // NATIVE-HALF: fcmp une half
   test = (!h1);
   // CHECK: [[F16TOF32]]
   // CHECK: fsub float
   // NOHALF: [[F32TOF16]]
   // HALF: [[F32TOF16]]
+  // NATIVE-HALF: fsub half
   h1 = -h1;
   // CHECK: [[F16TOF32]]
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: load volatile half
+  // NATIVE-HALF-NEXT: store volatile half
   h1 = +h1;
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   h1++;
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   ++h1;
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   --h1;
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   h1--;
 
   // Check binary ops with various operands
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fmul float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fmul half
   h1 = h0 * h2;
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F32TOF16]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fmul float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fmul half
   h1 = h0 * (__fp16) -2.0f;
   // CHECK: [[F16TOF32]]
   // CHECK: fmul float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fmul float
   h1 = h0 * f2;
   // CHECK: [[F16TOF32]]
   // CHECK: fmul float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fmul float
   h1 = f0 * h2;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fdiv float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fdiv half
   h1 = (h0 / h2);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fdiv float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fdiv half
   h1 = (h0 / (__fp16) -2.0f);
   // CHECK: [[F16TOF32]]
   // CHECK: fdiv float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fdiv float
   h1 = (h0 / f2);
   // CHECK: [[F16TOF32]]
   // CHECK: fdiv float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fdiv float
   h1 = (f0 / h2);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   h1 = (h2 + h0);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   h1 = ((__fp16)-2.0 + h0);
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fadd float
   h1 = (h2 + f0);
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fadd float
   h1 = (f2 + h0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fsub float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fsub half
   h1 = (h2 - h0);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fsub float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fsub half
   h1 = ((__fp16)-2.0f - h0);
   // CHECK: [[F16TOF32]]
   // CHECK: fsub float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fsub float
   h1 = (h2 - f0);
   // CHECK: [[F16TOF32]]
   // CHECK: fsub float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fsub float
   h1 = (f2 - h0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp olt
+  // NATIVE-HALF: fcmp olt half
   test = (h2 < h0);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fcmp olt
+  // NATIVE-HALF: fcmp olt half
   test = (h2 < (__fp16)42.0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp olt
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp olt float
   test = (h2 < f0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp olt
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp olt float
   test = (f2 < h0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp ogt
+  // NATIVE-HALF: fcmp ogt half
   test = (h0 > h2);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fcmp ogt
+  // NATIVE-HALF: fcmp ogt half
   test = ((__fp16)42.0 > h2);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp ogt
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp ogt float
   test = (h0 > f2);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp ogt
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp ogt float
   test = (f0 > h2);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp ole
+  // NATIVE-HALF: fcmp ole half
   test = (h2 <= h0);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fcmp ole
+  // NATIVE-HALF: fcmp ole half
   test = (h2 <= (__fp16)42.0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp ole
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp ole float
   test = (h2 <= f0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp ole
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp ole float
   test = (f2 <= h0);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp oge
+  // NATIVE-HALF: fcmp oge half
   test = (h0 >= h2);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fcmp oge
+  // NATIVE-HALF: fcmp oge half
   test = (h0 >= (__fp16)-2.0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp oge
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp oge float
   test = (h0 >= f2);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp oge
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp oge float
   test = (f0 >= h2);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp oeq
+  // NATIVE-HALF: fcmp oeq half
   test = (h1 == h2);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fcmp oeq
+  // NATIVE-HALF: fcmp oeq half
   test = (h1 == (__fp16)1.0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp oeq
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp oeq float
   test = (h1 == f1);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp oeq
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp oeq float
   test = (f1 == h1);
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp une
+  // NATIVE-HALF: fcmp une half
   test = (h1 != h2);
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fcmp une
+  // NATIVE-HALF: fcmp une half
   test = (h1 != (__fp16)1.0);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp une
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp une float
   test = (h1 != f1);
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp une
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fcmp une float
   test = (f1 != h1);
 
   // CHECK: [[F16TOF32]]
   // CHECK: fcmp une
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fcmp une half {{.*}}, 0xH0000
   h1 = (h1 ? h2 : h0);
   // Check assignments (inc. compound)
   h0 = h1;
   // NOHALF: [[F32TOF16]]
   // HALF: store {{.*}} half 0xHC000
+  // NATIVE-HALF: store {{.*}} half 0xHC000
   h0 = (__fp16)-2.0f;
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fptrunc float
   h0 = f0;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fadd float
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   h0 += h1;
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fadd
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fadd half
   h0 += (__fp16)1.0f;
   // CHECK: [[F16TOF32]]
   // CHECK: fadd
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fadd float
+  // NATIVE-HALF: fptrunc float
   h0 += f2;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fsub
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fsub half
   h0 -= h1;
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fsub
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fsub half
   h0 -= (__fp16)1.0;
   // CHECK: [[F16TOF32]]
   // CHECK: fsub
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fsub float
+  // NATIVE-HALF: fptrunc float
   h0 -= f2;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fmul
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fmul half
   h0 *= h1;
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fmul
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fmul half
   h0 *= (__fp16)1.0;
   // CHECK: [[F16TOF32]]
   // CHECK: fmul
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fmul float
+  // NATIVE-HALF: fptrunc float
   h0 *= f2;
 
   // CHECK: [[F16TOF32]]
   // CHECK: [[F16TOF32]]
   // CHECK: fdiv
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fdiv half
   h0 /= h1;
   // CHECK: [[F16TOF32]]
   // NOHALF: [[F16TOF32]]
   // CHECK: fdiv
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fdiv half
   h0 /= (__fp16)1.0;
   // CHECK: [[F16TOF32]]
   // CHECK: fdiv
   // CHECK: [[F32TOF16]]
+  // NATIVE-HALF: fpext half
+  // NATIVE-HALF: fdiv float
+  // NATIVE-HALF: fptrunc float
   h0 /= f2;
 
   // Check conversions to/from double
   // NOHALF: call i16 @llvm.convert.to.fp16.f64(
   // HALF: fptrunc double {{.*}} to half
+  // NATIVE-HALF: fptrunc double {{.*}} to half
   h0 = d0;
 
   // CHECK: [[MID:%.*]] = fptrunc double {{%.*}} to float
   // NOHALF: call i16 @llvm.convert.to.fp16.f32(float [[MID]])
   // HALF: fptrunc float [[MID]] to half
+  // NATIVE-HALF: [[MID:%.*]] = fptrunc double {{%.*}} to float
+  // NATIVE-HALF: fptrunc float {{.*}} to half
   h0 = (float)d0;
 
   // NOHALF: call double @llvm.convert.from.fp16.f64(
   // HALF: fpext half {{.*}} to double
+  // NATIVE-HALF: fpext half {{.*}} to double
   d0 = h0;
 
   // NOHALF: [[MID:%.*]] = call float @llvm.convert.from.fp16.f32(
   // HALF: [[MID:%.*]] = fpext half {{.*}} to float
   // CHECK: fpext float [[MID]] to double
+  // NATIVE-HALF: [[MID:%.*]] = fpext half {{.*}} to float
+  // NATIVE-HALF: fpext float [[MID]] to double
   d0 = (float)h0;
 }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to