From: Stam Markianos-Wright <Stam.Markianos-Wright@arm.com>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Cc: Richard Earnshaw <Richard.Earnshaw@arm.com>,
Richard Sandiford <Richard.Sandiford@arm.com>,
Kyrylo Tkachov <Kyrylo.Tkachov@arm.com>,
Marcus Shawcroft <Marcus.Shawcroft@arm.com>
Subject: [GCC][PATCH][Aarch64] Add Bfloat16_t scalar type, vector types and machine modes to Aarch64 back-end [2/2]
Date: Wed, 18 Dec 2019 16:40:00 -0000 [thread overview]
Message-ID: <2958be47-b626-f48c-7e88-22ad8ac223da@arm.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1526 bytes --]
Hi all,
This patch is part 2 of Bfloat16_t enablement in the Aarch64 back-end.
This new type is constrained using target hooks TARGET_INVALID_CONVERSION,
TARGET_INVALID_UNARY_OP, TARGET_INVALID_BINARY_OP so that it may only be used
through ACLE intrinsics (will be provided in later patches).
Regression testing on aarch64-none-elf passed successfully.
Ok for trunk?
Cheers,
Stam
ACLE documents are at https://developer.arm.com/docs/101028/latest
ISA documents are at https://developer.arm.com/docs/ddi0596/latest
Details on ARM Bfloat can be found here:
https://community.arm.com/developer/ip-products/processors/b/ml-ip-blog/posts/bfloat16-processing-for-neural-networks-on-armv8_2d00_a
PS. I don't have commit rights, so if someone could commit on my behalf,
that would be great :)
gcc/ChangeLog:
2019-12-16 Stam Markianos-Wright <stam.markianos-wright@arm.com>
* config/aarch64/aarch64.c
(aarch64_invalid_conversion): New function for target hook.
(aarch64_invalid_unary_op): Likewise.
(aarch64_invalid_binary_op): Likewise.
(TARGET_INVALID_CONVERSION): Add back-end define for target hook.
(TARGET_INVALID_UNARY_OP): Likewise.
(TARGET_INVALID_BINARY_OP): Likewise.
gcc/testsuite/ChangeLog:
2019-12-16 Stam Markianos-Wright <stam.markianos-wright@arm.com>
* gcc.target/aarch64/bfloat16_scalar_typecheck.c: New test.
* gcc.target/aarch64/bfloat16_vector_typecheck1.c: New test.
* gcc.target/aarch64/bfloat16_vector_typecheck2.c: New test.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: BFmode2of2.patch --]
[-- Type: text/x-patch; name="BFmode2of2.patch", Size: 14386 bytes --]
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index f57469b6e23..f40f6432fd4 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -21661,6 +21661,68 @@ aarch64_stack_protect_guard (void)
return NULL_TREE;
}
+/* Return the diagnostic message string if conversion from FROMTYPE to
+ TOTYPE is not allowed, NULL otherwise. */
+
+static const char *
+aarch64_invalid_conversion (const_tree fromtype, const_tree totype)
+{
+ static char templ[100];
+ if ((GET_MODE_INNER (TYPE_MODE (fromtype)) == BFmode
+ || GET_MODE_INNER (TYPE_MODE (totype)) == BFmode)
+ && TYPE_MODE (fromtype) != TYPE_MODE (totype))
+ {
+ snprintf (templ, sizeof (templ), \
+ "incompatible types when assigning to type '%s' from type '%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (totype))),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (fromtype))));
+ return N_(templ);
+ }
+ /* Conversion allowed. */
+ return NULL;
+}
+
+/* Return the diagnostic message string if the unary operation OP is
+ not permitted on TYPE, NULL otherwise. */
+
+static const char *
+aarch64_invalid_unary_op (int op, const_tree type)
+{
+ static char templ[100];
+ /* Reject all single-operand operations on BFmode except for &. */
+ if (GET_MODE_INNER (TYPE_MODE (type)) == BFmode && op != ADDR_EXPR)
+ {
+ snprintf (templ, sizeof (templ),
+ "operation not permitted on type '%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ return N_(templ);
+ }
+ /* Operation allowed. */
+ return NULL;
+}
+
+/* Return the diagnostic message string if the binary operation OP is
+ not permitted on TYPE1 and TYPE2, NULL otherwise. */
+
+static const char *
+aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
+ const_tree type2)
+{
+ static char templ[100];
+ /* Reject all 2-operand operations on BFmode. */
+ if (GET_MODE_INNER (TYPE_MODE (type1)) == BFmode
+ || GET_MODE_INNER (TYPE_MODE (type2)) == BFmode)
+ {
+ snprintf (templ, sizeof (templ), \
+ "operation not permitted on types '%s', '%s'",
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type1))),
+ IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2))));
+ return N_(templ);
+ }
+ /* Operation allowed. */
+ return NULL;
+}
+
/* Implement TARGET_ASM_FILE_END for AArch64. This adds the AArch64 GNU NOTE
section at the end if needed. */
#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000
@@ -21911,6 +21973,15 @@ aarch64_libgcc_floating_mode_supported_p
#undef TARGET_MANGLE_TYPE
#define TARGET_MANGLE_TYPE aarch64_mangle_type
+#undef TARGET_INVALID_CONVERSION
+#define TARGET_INVALID_CONVERSION aarch64_invalid_conversion
+
+#undef TARGET_INVALID_UNARY_OP
+#define TARGET_INVALID_UNARY_OP aarch64_invalid_unary_op
+
+#undef TARGET_INVALID_BINARY_OP
+#define TARGET_INVALID_BINARY_OP aarch64_invalid_binary_op
+
#undef TARGET_VERIFY_TYPE_CONTEXT
#define TARGET_VERIFY_TYPE_CONTEXT aarch64_verify_type_context
diff --git a/gcc/testsuite/gcc.target/aarch64/bfloat16_scalar_typecheck.c b/gcc/testsuite/gcc.target/aarch64/bfloat16_scalar_typecheck.c
new file mode 100644
index 00000000000..6f6a6af9587
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bfloat16_scalar_typecheck.c
@@ -0,0 +1,83 @@
+/* { dg-do compile { target { aarch64*-*-* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
+/* { dg-options "-march=armv8.2-a+i8mm" } */
+
+#include <arm_neon.h>
+
+bfloat16_t glob;
+float is_a_float;
+int n;
+
+bfloat16_t footest (bfloat16_t scalar0)
+{
+
+ /* Initialisation */
+
+ bfloat16_t scalar1 = 0.1; /* { dg-error "incompatible types when assigning to type 'bfloat16_t' from type 'double'" "" {target *-*-*} } */
+ bfloat16_t scalar2 = 0; /* { dg-error "incompatible types when assigning to type 'bfloat16_t' from type 'int'" "" {target *-*-*} } */
+ bfloat16_t scalar3 = {}; /* { dg-error "empty scalar initializer" "" {target *-*-*} } */
+
+ float16_t initi_a = scalar1; /* { dg-error "incompatible types when assigning to type 'float16_t' from type 'bfloat16_t'" "" {target *-*-*} } */
+ float16_t initi_b = { scalar1 }; /* { dg-error "incompatible types when assigning to type 'float16_t' from type 'bfloat16_t'" "" {target *-*-*} } */
+
+ /* Compound literals. */
+
+ (bfloat16_t) {}; /* { dg-error "empty scalar initializer" "" {target *-*-*} } */
+ (bfloat16_t) { scalar1 };
+
+ (int) { scalar1 }; /* { dg-error "incompatible types when assigning to type 'int' from type 'bfloat16_t'" "" {target *-*-*} } */
+
+ /* Casting. */
+
+ (void) scalar1;
+ (bfloat16_t) scalar1;
+
+ /* Arrays and Structs. */
+
+ typedef bfloat16_t array_type[2];
+ extern bfloat16_t extern_array[];
+
+ bfloat16_t array[2];
+ bfloat16_t zero_length_array[0];
+ bfloat16_t empty_init_array[] = {};
+ typedef bfloat16_t vla_type[n];
+
+ struct struct1 {
+ bfloat16_t a;
+ };
+
+ union union1 {
+ bfloat16_t a;
+ };
+
+ /* Assignments. */
+
+ n = scalar1; /* { dg-error "incompatible types when assigning to type 'int' from type 'bfloat16_t'" "" {target *-*-*} } */
+ is_a_float = scalar1; /* { dg-error "incompatible types when assigning to type 'float' from type 'bfloat16_t'" "" {target *-*-*} } */
+ scalar1 = 0; /* { dg-error "incompatible types when assigning to type 'bfloat16_t' from type 'int'" "" {target *-*-*} } */
+ scalar1 = 0.1; /* { dg-error "incompatible types when assigning to type 'bfloat16_t' from type 'double'" "" {target *-*-*} } */
+ scalar1 = scalar2;
+
+ /* Addressing and dereferencing. */
+
+ bfloat16_t *bfloat_ptr = &scalar1;
+ scalar1 = *bfloat_ptr;
+
+ /* Pointer assignment. */
+
+ bfloat16_t *bfloat_ptr2 = bfloat_ptr;
+
+ /* Single-operand operation. */
+
+ scalar1 = !glob; /* { dg-error "operation not permitted on type 'bfloat16_t'" "" {target *-*-*} } */
+
+ /* Double-operand operations. */
+
+ scalar1 = glob + *bfloat_ptr; /* { dg-error "operation not permitted on types 'bfloat16_t', 'bfloat16_t'" "" {target *-*-*} } */
+ scalar1 = glob + 0.1; /* { dg-error "operation not permitted on types 'bfloat16_t', 'double'" "" {target *-*-*} } */
+ scalar1 = glob + 0; /* { dg-error "operation not permitted on types 'bfloat16_t', 'int'" "" {target *-*-*} } */
+ scalar1 = glob + is_a_float; /* { dg-error "operation not permitted on types 'bfloat16_t', 'float'" "" {target *-*-*} } */
+
+ return scalar0;
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck1.c b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck1.c
new file mode 100644
index 00000000000..06786d9daa9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck1.c
@@ -0,0 +1,85 @@
+/* { dg-do compile { target { aarch64*-*-* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
+/* { dg-options "-march=armv8.2-a+i8mm" } */
+
+#include <arm_neon.h>
+
+bfloat16x4_t glob;
+float is_a_float;
+float16x4_t is_a_floatx4;
+int16x4_t intvec;
+int n;
+short n2;
+bfloat16_t scalar0, scalar1, scalar2, scalar3;
+
+bfloat16x4_t footest (bfloat16x4_t vector0)
+{
+ /* Initialisation */
+
+ bfloat16x4_t vector1 = { 0.0, n, n2, is_a_float };
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'double'" "" {target *-*-*} 19 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'int'" "" {target *-*-*} 19 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'short int'" "" {target *-*-*} 19 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'float'" "" {target *-*-*} 19 } */
+
+ bfloat16x4_t vector2 = {};
+
+ (bfloat16x4_t) {};
+
+ bfloat16x4_t vector4 = { scalar0, scalar1, scalar2, scalar3 };
+
+ float16x4_t initi_a = vector1; /* { dg-error "incompatible types when initializing type 'float16x4_t' using type 'bfloat16x4_t'" "" {target *-*-*} } */
+
+ /* Casting. */
+
+ (void) vector1;
+ (bfloat16x4_t) vector1;
+
+ /* Arrays and Structs. */
+
+ typedef bfloat16x4_t array_type[2];
+ extern bfloat16x4_t extern_array[];
+
+ bfloat16x4_t array[2];
+ bfloat16x4_t zero_length_array[0];
+ bfloat16x4_t empty_init_array[] = {};
+ typedef bfloat16x4_t some_other_type[n];
+
+ struct struct1 {
+ bfloat16x4_t a;
+ };
+
+ union union1 {
+ bfloat16x4_t a;
+ };
+
+ /* Assignments. */
+
+ intvec = vector1; /* { dg-error "incompatible types when assigning to type 'int16x4_t' from type 'bfloat16x4_t'" "" {target *-*-*} } */
+ is_a_floatx4 = vector1; /* { dg-error "incompatible types when assigning to type 'float16x4_t' from type 'bfloat16x4_t'" "" {target *-*-*} } */
+ vector1 = 0; /* { dg-error "incompatible types when assigning to type 'bfloat16x4_t' from type 'int'" "" {target *-*-*} } */
+ vector1 = 0.1; /* { dg-error "incompatible types when assigning to type 'bfloat16x4_t' from type 'double'" "" {target *-*-*} } */
+ vector1 = vector2;
+
+ /* Addressing and dereferencing. */
+
+ bfloat16x4_t *bfloat_ptr = &vector1;
+ vector1 = *bfloat_ptr;
+
+ /* Pointer assignment. */
+
+ bfloat16x4_t *bfloat_ptr2 = bfloat_ptr;
+
+ /* Single-operand operation. */
+
+ vector1 = !glob; /* { dg-error "operation not permitted on type 'bfloat16x4_t'" "" {target *-*-*} } */
+
+ /* Double-operand operations. */
+
+ vector1 = glob + *bfloat_ptr; /* { dg-error "operation not permitted on types 'bfloat16x4_t', 'bfloat16x4_t'" "" {target *-*-*} } */
+ vector1 = glob + 0.1; /* { dg-error "operation not permitted on types 'bfloat16x4_t', 'double'" "" {target *-*-*} } */
+ vector1 = glob + 0; /* { dg-error "operation not permitted on types 'bfloat16x4_t', 'int'" "" {target *-*-*} } */
+ vector1 = glob + is_a_floatx4; /* { dg-error "operation not permitted on types 'bfloat16x4_t', 'float16x4_t'" "" {target *-*-*} } */
+
+ return vector0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck2.c b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck2.c
new file mode 100644
index 00000000000..3be3e0551b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/bfloat16_vector_typecheck2.c
@@ -0,0 +1,95 @@
+/* { dg-do compile { target { aarch64*-*-* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
+/* { dg-options "-march=armv8.2-a+i8mm" } */
+
+#include <arm_neon.h>
+
+bfloat16_t scalar0, scalar1, scalar2, scalar3;
+bfloat16x8_t glob;
+
+float16_t is_a_half_float;
+float16x8_t is_a_floatx8;
+int16x8_t intvec;
+
+float is_a_float;
+int is_an_int;
+unsigned int is_a_uint;
+short is_a_short_int;
+long is_long;
+long double is_long_double;
+
+bfloat16x8_t footest (bfloat16x8_t vector0)
+{
+ /* Initialisation */
+
+ bfloat16x8_t vector1 = { 0.0, is_an_int, is_a_short_int, is_a_float, is_a_half_float, is_long, is_a_uint, is_long_double };
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'double'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'int'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'short int'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'float'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'float16_t'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'long int'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'unsigned int'" "" {target *-*-*} 25 } */
+ /* { dg-error "incompatible types when assigning to type '__bf16' from type 'long double'" "" {target *-*-*} 25 } */
+
+ bfloat16x8_t vector2 = {};
+
+ (bfloat16x8_t) {};
+
+ bfloat16x8_t vector4 = { scalar0, scalar1, scalar2, scalar3, scalar0, scalar1, scalar2, scalar3 };
+
+ float16x8_t initi_a = vector1; /* { dg-error "incompatible types when initializing type 'float16x8_t' using type 'bfloat16x8_t'" "" {target *-*-*} } */
+
+ /* Casting. */
+
+ (void) vector1;
+ (bfloat16x8_t) vector1;
+
+ /* Arrays and Structs. */
+
+ typedef bfloat16x8_t array_type[2];
+ extern bfloat16x8_t extern_array[];
+
+ bfloat16x8_t array[2];
+ bfloat16x8_t zero_length_array[0];
+ bfloat16x8_t empty_init_array[] = {};
+ typedef bfloat16x8_t some_other_type[is_an_int];
+
+ struct struct1 {
+ bfloat16x8_t a;
+ };
+
+ union union1 {
+ bfloat16x8_t a;
+ };
+
+ /* Assignments. */
+
+ intvec = vector1; /* { dg-error "incompatible types when assigning to type 'int16x8_t' from type 'bfloat16x8_t'" "" {target *-*-*} } */
+ is_a_floatx8 = vector1; /* { dg-error "incompatible types when assigning to type 'float16x8_t' from type 'bfloat16x8_t'" "" {target *-*-*} } */
+ vector1 = 0; /* { dg-error "incompatible types when assigning to type 'bfloat16x8_t' from type 'int'" "" {target *-*-*} } */
+ vector1 = 0.1; /* { dg-error "incompatible types when assigning to type 'bfloat16x8_t' from type 'double'" "" {target *-*-*} } */
+ vector1 = vector2;
+
+ /* Addressing and dereferencing. */
+
+ bfloat16x8_t *bfloat_ptr = &vector1;
+ vector1 = *bfloat_ptr;
+
+ /* Pointer assignment. */
+
+ bfloat16x8_t *bfloat_ptr2 = bfloat_ptr;
+
+ /* Single-operand operation. */
+
+ vector1 = !glob; /* { dg-error "operation not permitted on type 'bfloat16x8_t'" "" {target *-*-*} } */
+
+ /* Double-operand operations. */
+
+ vector1 = glob + *bfloat_ptr; /* { dg-error "operation not permitted on types 'bfloat16x8_t', 'bfloat16x8_t'" "" {target *-*-*} } */
+ vector1 = glob + 0.1; /* { dg-error "operation not permitted on types 'bfloat16x8_t', 'double'" "" {target *-*-*} } */
+ vector1 = glob + 0; /* { dg-error "operation not permitted on types 'bfloat16x8_t', 'int'" "" {target *-*-*} } */
+ vector1 = glob + is_a_floatx8; /* { dg-error "operation not permitted on types 'bfloat16x8_t', 'float16x8_t'" "" {target *-*-*} } */
+
+ return vector0;
+}
next reply other threads:[~2019-12-18 16:35 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-18 16:40 Stam Markianos-Wright [this message]
2019-12-19 10:10 ` Richard Sandiford
2020-01-07 11:42 ` Stam Markianos-Wright
2020-01-07 15:26 ` Richard Sandiford
2020-01-09 15:03 ` Stam Markianos-Wright
2020-01-09 16:13 ` Richard Sandiford
2020-01-09 16:21 ` Stam Markianos-Wright
2020-01-10 16:22 ` Stam Markianos-Wright
2020-01-10 16:30 ` Richard Sandiford
2020-01-10 20:13 ` Stam Markianos-Wright
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2958be47-b626-f48c-7e88-22ad8ac223da@arm.com \
--to=stam.markianos-wright@arm.com \
--cc=Kyrylo.Tkachov@arm.com \
--cc=Marcus.Shawcroft@arm.com \
--cc=Richard.Earnshaw@arm.com \
--cc=Richard.Sandiford@arm.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).