diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1114,7 +1114,7 @@ SatUnsignedLongFractTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType BFloat16Ty; - CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 + CanQualType Float16Ty, Float16ComplexTy; // C11 extension ISO/IEC TS 18661-3 CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; CanQualType BuiltinFnTy; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1327,6 +1327,7 @@ // C11 extension ISO/IEC TS 18661-3 InitBuiltinType(Float16Ty, BuiltinType::Float16); + InitBuiltinType(Float16ComplexTy, BuiltinType::Float16); // ISO/IEC JTC1 SC22 WG14 N1169 Extension InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum); @@ -6807,9 +6808,10 @@ FloatingRank EltRank = getFloatingRank(Size); if (Domain->isComplexType()) { switch (EltRank) { - case BFloat16Rank: llvm_unreachable("Complex bfloat16 is not supported"); - case Float16Rank: + case BFloat16Rank: + llvm_unreachable("Complex bfloat16 is not supported"); case HalfRank: llvm_unreachable("Complex half is not supported"); + case Float16Rank: return getComplexType(Float16Ty); case Ibm128Rank: return getComplexType(Ibm128Ty); case FloatRank: return getComplexType(FloatTy); case DoubleRank: return getComplexType(DoubleTy); diff --git a/clang/test/CodeGen/aarch64-complex-half-math.c b/clang/test/CodeGen/aarch64-complex-half-math.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/aarch64-complex-half-math.c @@ -0,0 +1,145 @@ +// RUN: %clang_cc1 %s -O1 -emit-llvm -triple aarch64-unknown-unknown -ffast-math -o - | FileCheck %s --check-prefix=AARCH64 + +_Float16 _Complex add_float_rr(_Float16 a, _Float16 b) { + // AARCH64-LABEL: @add_float_rr( + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fadd + // AARCH64: ret { half, half } + return a + b; +} +_Float16 _Complex add_float_cr(_Float16 _Complex a, _Float16 b) { + // AARCH64-LABEL: @add_float_cr( + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fadd + // AARCH64: ret { half, half } + return a + b; +} +_Float16 _Complex add_float_rc(_Float16 a, _Float16 _Complex b) { + // AARCH64-LABEL: @add_float_rc( + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fadd + // AARCH64: ret { half, half } + return a + b; +} +_Float16 _Complex add_float_cc(_Float16 _Complex a, _Float16 _Complex b) { + // AARCH64-LABEL: @add_float_cc( + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fadd + // AARCH64: ret { half, half } + return a + b; +} + +_Float16 _Complex sub_float_rr(_Float16 a, _Float16 b) { + // AARCH64-LABEL: @sub_float_rr( + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fsub + // AARCH64: ret { half, half } + return a - b; +} +_Float16 _Complex sub_float_cr(_Float16 _Complex a, _Float16 b) { + // AARCH64-LABEL: @sub_float_cr( + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fsub + // AARCH64: ret { half, half } + return a - b; +} +_Float16 _Complex sub_float_rc(_Float16 a, _Float16 _Complex b) { + // AARCH64-LABEL: @sub_float_rc( + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64: fneg reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fsub + // AARCH64: ret { half, half } + return a - b; +} +_Float16 _Complex sub_float_cc(_Float16 _Complex a, _Float16 _Complex b) { + // AARCH64-LABEL: @sub_float_cc( + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fsub + // AARCH64: ret { half, half } + return a - b; +} + +_Float16 _Complex mul_float_rr(_Float16 a, _Float16 b) { + // AARCH64-LABEL: @mul_float_rr( + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fmul + // AARCH64: ret { half, half } + return a * b; +} +_Float16 _Complex mul_float_cr(_Float16 _Complex a, _Float16 b) { + // AARCH64-LABEL: @mul_float_cr( + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fmul + // AARCH64: ret { half, half } + return a * b; +} +_Float16 _Complex mul_float_rc(_Float16 a, _Float16 _Complex b) { + // AARCH64-LABEL: @mul_float_rc( + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fmul + // AARCH64: ret { half, half } + return a * b; +} +_Float16 _Complex mul_float_cc(_Float16 _Complex a, _Float16 _Complex b) { + // AARCH64-LABEL: @mul_float_cc( + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fmul + // AARCH64: ret { half, half } + return a * b; +} + +_Float16 _Complex div_float_rr(_Float16 a, _Float16 b) { + // AARCH64-LABEL: @div_float_rr( + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: ret { half, half } + return a / b; +} +_Float16 _Complex div_float_cr(_Float16 _Complex a, _Float16 b) { + // AARCH64-LABEL: @div_float_cr( + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: ret { half, half } + return a / b; +} +_Float16 _Complex div_float_rc(_Float16 a, _Float16 _Complex b) { + // AARCH64-LABEL: @div_float_rc( + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64: fneg reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: ret { half, half } + return a / b; +} +_Float16 _Complex div_float_cc(_Float16 _Complex a, _Float16 _Complex b) { + // AARCH64-LABEL: @div_float_cc( + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fadd reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fmul reassoc nnan ninf nsz arcp afn half + // AARCH64: fsub reassoc nnan ninf nsz arcp afn half + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64-NOT: fdiv reassoc nnan ninf nsz arcp afn half + // AARCH64: ret { half, half } + return a / b; +}