diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -757,8 +757,6 @@ * 32-bit ARM * 64-bit ARM (AArch64) -The ``__bf16`` type is only available when supported in hardware. - ``__fp16`` is a storage and interchange format only. This means that values of ``__fp16`` are immediately promoted to (at least) ``float`` when used in arithmetic operations, so that e.g. the result of adding two ``__fp16`` values has type ``float``. diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -116,6 +116,8 @@ bool handleTargetFeatures(std::vector &Features, DiagnosticsEngine &Diags) override; + bool hasBFloat16Type() const override; + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; bool isCLZForZeroUndef() const override; diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -670,6 +670,10 @@ return true; } +bool AArch64TargetInfo::hasBFloat16Type() const { + return true; +} + TargetInfo::CallingConvCheckResult AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { switch (CC) { diff --git a/clang/test/CodeGen/arm-bf16-params-returns.c b/clang/test/CodeGen/arm-bf16-params-returns.c --- a/clang/test/CodeGen/arm-bf16-params-returns.c +++ b/clang/test/CodeGen/arm-bf16-params-returns.c @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-abi aapcs -mfloat-abi hard -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK32-HARD // RUN: %clang_cc1 -triple armv8.6a-arm-none-eabi -target-abi aapcs -mfloat-abi softfp -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK32-SOFTFP -// RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-abi aapcs -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK64 +// RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-abi aapcs -target-feature +bf16 -target-feature +neon -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefixes=CHECK64,CHECK64NEON +// RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-abi aapcs -target-feature -bf16 -target-feature +neon -DNONEON -emit-llvm -O2 -o - %s | opt -S -mem2reg -sroa | FileCheck %s --check-prefix=CHECK64 // REQUIRES: aarch64-registered-target || arm-registered-target @@ -17,6 +18,8 @@ // CHECK64: define{{.*}} bfloat @test_ret_bf16(bfloat noundef returned %v) {{.*}} { // CHECK64: ret bfloat %v +#ifndef NONEON + bfloat16x4_t test_ret_bf16x4_t(bfloat16x4_t v) { return v; } @@ -24,5 +27,7 @@ // CHECK32-HARD: ret <4 x bfloat> %v // CHECK32-SOFTFP: define{{.*}} <2 x i32> @test_ret_bf16x4_t(<2 x i32> [[V0:.*]]) {{.*}} { // CHECK32-SOFTFP: ret <2 x i32> %v -// CHECK64: define{{.*}} <4 x bfloat> @test_ret_bf16x4_t(<4 x bfloat> noundef returned %v) {{.*}} { -// CHECK64: ret <4 x bfloat> %v +// CHECK64NEON: define{{.*}} <4 x bfloat> @test_ret_bf16x4_t(<4 x bfloat> noundef returned %v) {{.*}} { +// CHECK64NEON: ret <4 x bfloat> %v + +#endif \ No newline at end of file diff --git a/clang/test/CodeGen/arm-mangle-bf16.cpp b/clang/test/CodeGen/arm-mangle-bf16.cpp --- a/clang/test/CodeGen/arm-mangle-bf16.cpp +++ b/clang/test/CodeGen/arm-mangle-bf16.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature +bf16 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-arm-none-eabi -target-feature -bf16 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi hard -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi softfp -emit-llvm -o - %s | FileCheck %s diff --git a/clang/test/Sema/arm-bf16-forbidden-ops.c b/clang/test/Sema/arm-bf16-forbidden-ops.c --- a/clang/test/Sema/arm-bf16-forbidden-ops.c +++ b/clang/test/Sema/arm-bf16-forbidden-ops.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64 -target-feature +bf16 %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64 -target-feature -bf16 %s __bf16 test_cast_from_float(float in) { return (__bf16)in; // expected-error {{cannot type-cast to __bf16}} diff --git a/clang/test/Sema/arm-bf16-forbidden-ops.cpp b/clang/test/Sema/arm-bf16-forbidden-ops.cpp --- a/clang/test/Sema/arm-bf16-forbidden-ops.cpp +++ b/clang/test/Sema/arm-bf16-forbidden-ops.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64 -target-feature +bf16 %s +// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64 -target-feature -bf16 %s __bf16 test_static_cast_from_float(float in) { return static_cast<__bf16>(in); // expected-error {{static_cast from 'float' to '__bf16' is not allowed}} diff --git a/clang/test/Sema/arm-bfloat.cpp b/clang/test/Sema/arm-bfloat.cpp --- a/clang/test/Sema/arm-bfloat.cpp +++ b/clang/test/Sema/arm-bfloat.cpp @@ -1,49 +1,57 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \ -// RUN: -triple aarch64-arm-none-eabi -target-cpu cortex-a75 \ -// RUN: -target-feature +bf16 -target-feature +neon %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \ -// RUN: -triple arm-arm-none-eabi -target-cpu cortex-a53 \ -// RUN: -target-feature +bf16 -target-feature +neon %s +// RUN: %clang_cc1 -fsyntax-only -verify=scalar,neon -std=c++11 \ +// RUN: -triple aarch64-arm-none-eabi -target-cpu cortex-a75 \ +// RUN: -target-feature +bf16 -target-feature +neon %s +// RUN: %clang_cc1 -fsyntax-only -verify=scalar,neon -std=c++11 \ +// RUN: -triple arm-arm-none-eabi -target-cpu cortex-a53 \ +// RUN: -target-feature +bf16 -target-feature +neon %s + +// The types should be available under AArch64 even without the bf16 feature +// RUN: %clang_cc1 -fsyntax-only -verify=scalar -DNONEON -std=c++11 \ +// RUN: -triple aarch64-arm-none-eabi -target-cpu cortex-a75 \ +// RUN: -target-feature -bf16 -target-feature +neon %s // REQUIRES: aarch64-registered-target || arm-registered-target void test(bool b) { __bf16 bf16; - bf16 + bf16; // expected-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} - bf16 - bf16; // expected-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} - bf16 * bf16; // expected-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} - bf16 / bf16; // expected-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} + bf16 + bf16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} + bf16 - bf16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} + bf16 * bf16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} + bf16 / bf16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__bf16')}} __fp16 fp16; - bf16 + fp16; // expected-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} - fp16 + bf16; // expected-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} - bf16 - fp16; // expected-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} - fp16 - bf16; // expected-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} - bf16 * fp16; // expected-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} - fp16 * bf16; // expected-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} - bf16 / fp16; // expected-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} - fp16 / bf16; // expected-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} - bf16 = fp16; // expected-error {{assigning to '__bf16' from incompatible type '__fp16'}} - fp16 = bf16; // expected-error {{assigning to '__fp16' from incompatible type '__bf16'}} - bf16 + (b ? fp16 : bf16); // expected-error {{incompatible operand types ('__fp16' and '__bf16')}} + bf16 + fp16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} + fp16 + bf16; // scalar-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} + bf16 - fp16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} + fp16 - bf16; // scalar-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} + bf16 * fp16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} + fp16 * bf16; // scalar-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} + bf16 / fp16; // scalar-error {{invalid operands to binary expression ('__bf16' and '__fp16')}} + fp16 / bf16; // scalar-error {{invalid operands to binary expression ('__fp16' and '__bf16')}} + bf16 = fp16; // scalar-error {{assigning to '__bf16' from incompatible type '__fp16'}} + fp16 = bf16; // scalar-error {{assigning to '__fp16' from incompatible type '__bf16'}} + bf16 + (b ? fp16 : bf16); // scalar-error {{incompatible operand types ('__fp16' and '__bf16')}} } +#ifndef NONEON + #include void test_vector(bfloat16x4_t a, bfloat16x4_t b, float16x4_t c) { - a + b; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} - a - b; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} - a * b; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} - a / b; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} - - a + c; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} - a - c; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} - a * c; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} - a / c; // expected-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} - c + b; // expected-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} - c - b; // expected-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} - c * b; // expected-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} - c / b; // expected-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} + a + b; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} + a - b; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} + a * b; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} + a / b; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'bfloat16x4_t')}} + + a + c; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} + a - c; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} + a * c; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} + a / c; // neon-error {{invalid operands to binary expression ('bfloat16x4_t' (vector of 4 'bfloat16_t' values) and 'float16x4_t' (vector of 4 'float16_t' values))}} + c + b; // neon-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} + c - b; // neon-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} + c * b; // neon-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} + c / b; // neon-error {{invalid operands to binary expression ('float16x4_t' (vector of 4 'float16_t' values) and 'bfloat16x4_t' (vector of 4 'bfloat16_t' values))}} } +#endif \ No newline at end of file