pengfei updated this revision to Diff 365360.
pengfei added a comment.

Rebased.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105331/new/

https://reviews.llvm.org/D105331

Files:
  clang/lib/CodeGen/TargetInfo.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/CodeGen/X86/avx512fp16-complex-abi.c
  clang/test/CodeGen/X86/avx512fp16-complex.c
  clang/test/Sema/Float16.c

Index: clang/test/Sema/Float16.c
===================================================================
--- clang/test/Sema/Float16.c
+++ clang/test/Sema/Float16.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc -target-feature +avx512fp16 %s -DHAVE
 // RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s -DHAVE
 // RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s -DHAVE
 // RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s -DHAVE
@@ -9,8 +10,7 @@
 _Float16 f;
 
 #ifdef HAVE
-// FIXME: Should this be valid?
-_Complex _Float16 a; // expected-error {{'_Complex _Float16' is invalid}}
+_Complex _Float16 a;
 void builtin_complex() {
   _Float16 a = 0;
   (void)__builtin_complex(a, a); // expected-error {{'_Complex _Float16' is invalid}}
Index: clang/test/CodeGen/X86/avx512fp16-complex.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/X86/avx512fp16-complex.c
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 %s -O0 -fno-experimental-new-pass-manager -emit-llvm -triple x86_64-unknown-unknown -target-feature +avx512fp16 -o - | FileCheck %s --check-prefix=X86
+
+_Float16 _Complex add_half_rr(_Float16 a, _Float16 b) {
+  // X86-LABEL: @add_half_rr(
+  // X86: fadd
+  // X86-NOT: fadd
+  // X86: ret
+  return a + b;
+}
+_Float16 _Complex add_half_cr(_Float16 _Complex a, _Float16 b) {
+  // X86-LABEL: @add_half_cr(
+  // X86: fadd
+  // X86-NOT: fadd
+  // X86: ret
+  return a + b;
+}
+_Float16 _Complex add_half_rc(_Float16 a, _Float16 _Complex b) {
+  // X86-LABEL: @add_half_rc(
+  // X86: fadd
+  // X86-NOT: fadd
+  // X86: ret
+  return a + b;
+}
+_Float16 _Complex add_half_cc(_Float16 _Complex a, _Float16 _Complex b) {
+  // X86-LABEL: @add_half_cc(
+  // X86: fadd
+  // X86: fadd
+  // X86-NOT: fadd
+  // X86: ret
+  return a + b;
+}
+
+_Float16 _Complex sub_half_rr(_Float16 a, _Float16 b) {
+  // X86-LABEL: @sub_half_rr(
+  // X86: fsub
+  // X86-NOT: fsub
+  // X86: ret
+  return a - b;
+}
+_Float16 _Complex sub_half_cr(_Float16 _Complex a, _Float16 b) {
+  // X86-LABEL: @sub_half_cr(
+  // X86: fsub
+  // X86-NOT: fsub
+  // X86: ret
+  return a - b;
+}
+_Float16 _Complex sub_half_rc(_Float16 a, _Float16 _Complex b) {
+  // X86-LABEL: @sub_half_rc(
+  // X86: fsub
+  // X86: fneg
+  // X86-NOT: fsub
+  // X86: ret
+  return a - b;
+}
+_Float16 _Complex sub_half_cc(_Float16 _Complex a, _Float16 _Complex b) {
+  // X86-LABEL: @sub_half_cc(
+  // X86: fsub
+  // X86: fsub
+  // X86-NOT: fsub
+  // X86: ret
+  return a - b;
+}
+
+_Float16 _Complex mul_half_rr(_Float16 a, _Float16 b) {
+  // X86-LABEL: @mul_half_rr(
+  // X86: fmul
+  // X86-NOT: fmul
+  // X86: ret
+  return a * b;
+}
+_Float16 _Complex mul_half_cr(_Float16 _Complex a, _Float16 b) {
+  // X86-LABEL: @mul_half_cr(
+  // X86: fmul
+  // X86: fmul
+  // X86-NOT: fmul
+  // X86: ret
+  return a * b;
+}
+_Float16 _Complex mul_half_rc(_Float16 a, _Float16 _Complex b) {
+  // X86-LABEL: @mul_half_rc(
+  // X86: fmul
+  // X86: fmul
+  // X86-NOT: fmul
+  // X86: ret
+  return a * b;
+}
+_Float16 _Complex mul_half_cc(_Float16 _Complex a, _Float16 _Complex b) {
+  // X86-LABEL: @mul_half_cc(
+  // X86: %[[AC:[^ ]+]] = fmul
+  // X86: %[[BD:[^ ]+]] = fmul
+  // X86: %[[AD:[^ ]+]] = fmul
+  // X86: %[[BC:[^ ]+]] = fmul
+  // X86: %[[RR:[^ ]+]] = fsub half %[[AC]], %[[BD]]
+  // X86: %[[RI:[^ ]+]] = fadd half
+  // X86-DAG: %[[AD]]
+  // X86-DAG: ,
+  // X86-DAG: %[[BC]]
+  // X86: fcmp uno half %[[RR]]
+  // X86: fcmp uno half %[[RI]]
+  // X86: call {{.*}} @__mulhc3(
+  // X86: ret
+  return a * b;
+}
+
+_Float16 _Complex div_half_rr(_Float16 a, _Float16 b) {
+  // X86-LABEL: @div_half_rr(
+  // X86: fdiv
+  // X86-NOT: fdiv
+  // X86: ret
+  return a / b;
+}
+_Float16 _Complex div_half_cr(_Float16 _Complex a, _Float16 b) {
+  // X86-LABEL: @div_half_cr(
+  // X86: fdiv
+  // X86: fdiv
+  // X86-NOT: fdiv
+  // X86: ret
+  return a / b;
+}
+_Float16 _Complex div_half_rc(_Float16 a, _Float16 _Complex b) {
+  // X86-LABEL: @div_half_rc(
+  // X86-NOT: fdiv
+  // X86: call {{.*}} @__divhc3(
+  // X86: ret
+  return a / b;
+}
+_Float16 _Complex div_half_cc(_Float16 _Complex a, _Float16 _Complex b) {
+  // X86-LABEL: @div_half_cc(
+  // X86-NOT: fdiv
+  // X86: call {{.*}} @__divhc3(
+  // X86: ret
+  return a / b;
+}
Index: clang/test/CodeGen/X86/avx512fp16-complex-abi.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/X86/avx512fp16-complex-abi.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -target-feature +avx512fp16 -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
+
+// Return value should be passed in <2 x half> so the backend will use xmm0
+_Complex _Float16 f16(_Complex _Float16 A, _Complex _Float16 B) {
+  // CHECK-LABEL: define{{.*}}<2 x half> @f16({ half, half }* byval({ half, half }) align 4 %{{.*}}, { half, half }* byval({ half, half }) align 4 %{{.*}})
+  return A + B;
+}
Index: clang/lib/Sema/DeclSpec.cpp
===================================================================
--- clang/lib/Sema/DeclSpec.cpp
+++ clang/lib/Sema/DeclSpec.cpp
@@ -1300,8 +1300,8 @@
       if (!S.getLangOpts().CPlusPlus)
         S.Diag(TSTLoc, diag::ext_integer_complex);
     } else if (TypeSpecType != TST_float && TypeSpecType != TST_double &&
-               TypeSpecType != TST_float128) {
-      // FIXME: _Float16, __fp16?
+               TypeSpecType != TST_float128 && TypeSpecType != TST_float16) {
+      // FIXME: __fp16?
       S.Diag(TSCLoc, diag::err_invalid_complex_spec)
         << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecComplex = TSC_unspecified;
Index: clang/lib/CodeGen/TargetInfo.cpp
===================================================================
--- clang/lib/CodeGen/TargetInfo.cpp
+++ clang/lib/CodeGen/TargetInfo.cpp
@@ -1524,6 +1524,14 @@
     if (isEmptyRecord(getContext(), RetTy, true))
       return ABIArgInfo::getIgnore();
 
+    // Return complex of _Float16 as <2 x half> so the backend will use xmm0.
+    if (const ComplexType *CT = RetTy->getAs<ComplexType>()) {
+      QualType ET = getContext().getCanonicalType(CT->getElementType());
+      if (ET->isFloat16Type())
+        return ABIArgInfo::getDirect(llvm::FixedVectorType::get(
+            llvm::Type::getHalfTy(getVMContext()), 2));
+    }
+
     // Small structures which are register sized are generally returned
     // in a register.
     if (shouldReturnTypeInRegister(RetTy, getContext())) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to