forked from OSchip/llvm-project
[CFE][X86] Enable complex _Float16 support
Support complex _Float16 on X86 in C/C++ following the latest X86 psABI. (https://gitlab.com/x86-psABIs) Reviewed By: LuoYuanke Differential Revision: https://reviews.llvm.org/D105331
This commit is contained in:
parent
59dfde7d94
commit
5aeca3b0a5
|
@ -1524,6 +1524,14 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
|
|||
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())) {
|
||||
|
|
|
@ -1300,8 +1300,8 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue