public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2]
@ 2020-01-10 18:48 Stam Markianos-Wright
  2020-01-13 10:58 ` Kyrill Tkachov
  2020-05-16  8:49 ` Andreas Schwab
  0 siblings, 2 replies; 4+ messages in thread
From: Stam Markianos-Wright @ 2020-01-10 18:48 UTC (permalink / raw)
  To: gcc-patches
  Cc: Richard Earnshaw, Richard Sandiford, Ramana Radhakrishnan,
	Kyrylo Tkachov, nickc

[-- Attachment #1: Type: text/plain, Size: 1252 bytes --]

Hi all,

This patch is part 2 of Bfloat16_t enablement in the ARM 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 arm-none-eabi 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 



gcc/ChangeLog:

2020-01-10  Stam Markianos-Wright  <stam.markianos-wright@arm.com>

	* config/arm/arm.c
	(arm_invalid_conversion): New function for target hook.
	(arm_invalid_unary_op): New function for target hook.
	(arm_invalid_binary_op): New function for target hook.

2020-01-10  Stam Markianos-Wright  <stam.markianos-wright@arm.com>

	* gcc.target/arm/bfloat16_scalar_typecheck.c: New test.
	* gcc.target/arm/bfloat16_vector_typecheck_1.c: New test.
	* gcc.target/arm/bfloat16_vector_typecheck_2.c: New test.



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: BFmode2of2-A32.patch --]
[-- Type: text/x-patch; name="BFmode2of2-A32.patch", Size: 47130 bytes --]

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9bd228b5433..d4180d4166c 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -688,6 +688,15 @@ static const struct attribute_spec arm_attribute_table[] =
 #undef TARGET_MANGLE_TYPE
 #define TARGET_MANGLE_TYPE arm_mangle_type
 
+#undef TARGET_INVALID_CONVERSION
+#define TARGET_INVALID_CONVERSION arm_invalid_conversion
+
+#undef TARGET_INVALID_UNARY_OP
+#define TARGET_INVALID_UNARY_OP arm_invalid_unary_op
+
+#undef TARGET_INVALID_BINARY_OP
+#define TARGET_INVALID_BINARY_OP arm_invalid_binary_op
+
 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV arm_atomic_assign_expand_fenv
 
@@ -32432,6 +32441,55 @@ arm_coproc_ldc_stc_legitimate_address (rtx op)
   return false;
 }
 
+/* Return the diagnostic message string if conversion from FROMTYPE to
+   TOTYPE is not allowed, NULL otherwise.  */
+
+static const char *
+arm_invalid_conversion (const_tree fromtype, const_tree totype)
+{
+  if (element_mode (fromtype) != element_mode (totype))
+    {
+      /* Do no allow conversions to/from BFmode scalar types.  */
+      if (TYPE_MODE (fromtype) == BFmode)
+	return N_("invalid conversion from type %<bfloat16_t%>");
+      if (TYPE_MODE (totype) == BFmode)
+	return N_("invalid conversion to type %<bfloat16_t%>");
+    }
+
+  /* Conversion allowed.  */
+  return NULL;
+}
+
+/* Return the diagnostic message string if the unary operation OP is
+   not permitted on TYPE, NULL otherwise.  */
+
+static const char *
+arm_invalid_unary_op (int op, const_tree type)
+{
+  /* Reject all single-operand operations on BFmode except for &.  */
+  if (element_mode (type) == BFmode && op != ADDR_EXPR)
+    return N_("operation not permitted on type %<bfloat16_t%>");
+
+  /* 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 *
+arm_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1,
+			   const_tree type2)
+{
+  /* Reject all 2-operand operations on BFmode.  */
+  if (element_mode (type1) == BFmode
+      || element_mode (type2) == BFmode)
+    return N_("operation not permitted on type %<bfloat16_t%>");
+
+  /* Operation allowed.  */
+  return NULL;
+}
+
 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.
 
    In VFPv1, VFP registers could only be accessed in the mode they were
diff --git a/gcc/testsuite/g++.target/arm/bfloat_cpp_typecheck.C b/gcc/testsuite/g++.target/arm/bfloat_cpp_typecheck.C
new file mode 100644
index 00000000000..3e6f7d83752
--- /dev/null
+++ b/gcc/testsuite/g++.target/arm/bfloat_cpp_typecheck.C
@@ -0,0 +1,14 @@
+/* { dg-do assemble { target { arm*-*-* } } } */
+/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
+/* { dg-add-options arm_v8_2a_bf16_neon }  */
+/* { dg-additional-options "-O3 --save-temps" } */
+
+#include <arm_neon.h>
+
+void foo (void)
+{
+  bfloat16_t (); /* { dg-bogus {invalid conversion to type 'bfloat16_t'} "" { xfail *-*-* } } */
+  bfloat16_t a = bfloat16_t(); /* { dg-bogus {invalid conversion to type 'bfloat16_t'} "" { xfail *-*-* } } */
+  bfloat16_t (0x1234); /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t (0.1); /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+}
diff --git a/gcc/testsuite/gcc.target/arm/bfloat16_scalar_typecheck.c b/gcc/testsuite/gcc.target/arm/bfloat16_scalar_typecheck.c
new file mode 100644
index 00000000000..672641e6630
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bfloat16_scalar_typecheck.c
@@ -0,0 +1,219 @@
+/* { dg-do assemble { target { arm*-*-* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
+/* { dg-require-effective-target arm_v8_2a_fp16_neon_ok } */
+/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
+/* { dg-additional-options "-march=armv8.6-a+bf16+fp16 -Wno-pedantic -O3 --save-temps" }  */
+
+#include <arm_neon.h>
+
+bfloat16_t glob_bfloat;
+
+int is_an_int;
+short is_a_short_int;
+float is_a_float;
+float is_a_float16;
+double is_a_double;
+
+float *float_ptr;
+
+bfloat16_t foo1 (void) { return (bfloat16_t) 0x1234; } /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+bfloat16_t foo2 (void) { return (bfloat16_t) (short) 0x1234; } /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+bfloat16_t footest (bfloat16_t scalar0)
+{
+
+  /* Initialisation  */
+
+  bfloat16_t scalar1_1;
+  bfloat16_t scalar1_2 = glob_bfloat;
+  bfloat16_t scalar1_3 = 0;   /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar1_4 = 0.1; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar1_5 = is_a_float; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar1_6 = is_an_int;  /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar1_7 = is_a_float16; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar1_8 = is_a_double; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar1_9 = is_a_short_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  int initi_1_1 = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float initi_1_2 = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float16_t initi_1_3 = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  short initi_1_4 = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  double initi_1_5 = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  bfloat16_t scalar2_1 = {}; /* { dg-error {empty scalar initializer} } */
+  bfloat16_t scalar2_2 = { glob_bfloat };
+  bfloat16_t scalar2_3 = { 0 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar2_4 = { 0.1 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar2_5 = { is_a_float }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar2_6 = { is_an_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar2_7 = { is_a_float16 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar2_8 = { is_a_double }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16_t scalar2_9 = { is_a_short_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  int initi_2_1 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float initi_2_2 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float16_t initi_2_3 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  short initi_2_4 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  double initi_2_5 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* Assignments.  */
+
+  glob_bfloat = glob_bfloat;
+  glob_bfloat = 0;   /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  glob_bfloat = 0.1; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  glob_bfloat = is_a_float; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  glob_bfloat = is_an_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  glob_bfloat = is_a_float16; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  glob_bfloat = is_a_double; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  glob_bfloat = is_a_short_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  is_an_int = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_float = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_float16 = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_double = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_short_int = glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* Casting.  */
+
+  (void) glob_bfloat;
+  (bfloat16_t) glob_bfloat;
+
+  (int) glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (float) glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (float16_t) glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (double) glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (short) glob_bfloat; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  (bfloat16_t) is_an_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) is_a_float; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) is_a_float16; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) is_a_double; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) is_a_short_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  /* Compound literals.  */
+
+  (bfloat16_t) {}; /* { dg-error {empty scalar initializer} } */
+  (bfloat16_t) { glob_bfloat };
+  (bfloat16_t) { 0 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) { 0.1 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) { is_a_float }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) { is_an_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) { is_a_float16 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) { is_a_double }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16_t) { is_a_short_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  (int) { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (float) { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (float16_t) { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (double) { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  (short) { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* 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 some_other_type[is_an_int];
+
+  struct struct1 {
+    bfloat16_t a;
+  };
+
+  union union1 {
+    bfloat16_t a;
+  };
+
+  /* Addressing and dereferencing.  */
+
+  bfloat16_t *bfloat_ptr = &scalar0;
+  scalar0 = *bfloat_ptr;
+
+  /* Pointer assignment.  */
+
+  bfloat16_t *bfloat_ptr2 = bfloat_ptr;
+  bfloat16_t *bfloat_ptr3 = array;
+
+  /* Pointer arithmetic.  */
+
+  ++bfloat_ptr;
+  --bfloat_ptr;
+  bfloat_ptr++;
+  bfloat_ptr--;
+  bfloat_ptr += 1;
+  bfloat_ptr -= 1;
+  bfloat_ptr - bfloat_ptr2;
+  bfloat_ptr = &bfloat_ptr3[0];
+  bfloat_ptr = &bfloat_ptr3[1];
+
+  /* Simple comparison.  */
+  scalar0 > glob_bfloat; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  glob_bfloat == scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 > is_a_float; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  is_a_float == scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 > 0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  0 == scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 > 0.1; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  0.1 == scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 > is_an_int; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  is_an_int == scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Pointer comparison.  */
+
+  bfloat_ptr == &scalar0;
+  bfloat_ptr != &scalar0;
+  bfloat_ptr < &scalar0;
+  bfloat_ptr <= &scalar0;
+  bfloat_ptr > &scalar0;
+  bfloat_ptr >= &scalar0;
+  bfloat_ptr == bfloat_ptr2;
+  bfloat_ptr != bfloat_ptr2;
+  bfloat_ptr < bfloat_ptr2;
+  bfloat_ptr <= bfloat_ptr2;
+  bfloat_ptr > bfloat_ptr2;
+  bfloat_ptr >= bfloat_ptr2;
+
+  /* Conditional expressions.  */
+
+  0 ? scalar0 : scalar0;
+  0 ? scalar0 : is_a_float; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  0 ? is_a_float : scalar0; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  0 ? scalar0 : 0; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  0 ? 0 : scalar0; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  0 ? 0.1 : scalar0; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  0 ? scalar0 : 0.1; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  0 ? bfloat_ptr : bfloat_ptr2;
+  0 ? bfloat_ptr : float_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? float_ptr : bfloat_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+
+  scalar0 ? scalar0 : scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 ? is_a_float : scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 ? scalar0 : is_a_float; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 ? is_a_float : is_a_float; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Unary operators.  */
+
+  +scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  -scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  ~scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  !scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  *scalar0; /* { dg-error {invalid type argument of unary '\*'} } */
+  __real scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  __imag scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  ++scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  --scalar0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0++; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0--; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Binary arithmetic operations.  */
+
+  scalar0 = glob_bfloat + *bfloat_ptr; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 = glob_bfloat + 0.1; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 = glob_bfloat + 0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  scalar0 = glob_bfloat + is_a_float; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  return scalar0;
+}
+
diff --git a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c
new file mode 100644
index 00000000000..ba39cb6bcd3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_1.c
@@ -0,0 +1,263 @@
+/* { dg-do assemble { target { arm*-*-* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
+/* { dg-require-effective-target arm_v8_2a_fp16_neon_ok } */
+/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
+/* { dg-additional-options "-march=armv8.6-a+bf16+fp16 -Wno-pedantic -O3 --save-temps" }  */
+
+#include <arm_neon.h>
+
+bfloat16_t glob_bfloat;
+bfloat16x4_t glob_bfloat_vec;
+
+float32x4_t is_a_float_vec;
+float32x2_t is_a_float_pair;
+
+float16x4_t *float_ptr;
+float16x4_t is_a_float16_vec;
+
+int32x4_t is_an_int_vec;
+int32x2_t is_an_int_pair;
+int16x4_t is_a_short_vec;
+
+int is_an_int;
+short is_a_short_int;
+float is_a_float;
+float is_a_float16;
+double is_a_double;
+
+/* Create a vector of 2 bfloat16_t.  */
+typedef bfloat16_t v2bf __attribute__((vector_size(4)));
+v2bf foo1 (void) { return (v2bf) 0x12345678; }
+bfloat16x4_t foo2 (void) { return (bfloat16x4_t) 0x1234567812345678; }
+
+bfloat16x4_t footest (bfloat16x4_t vector0)
+{
+  /* Initialisation  */
+
+  bfloat16x4_t vector1_1;
+  bfloat16x4_t vector1_2 = glob_bfloat_vec;
+  bfloat16x4_t vector1_3 = is_a_float_vec; /* { dg-error {incompatible types when initializing type 'bfloat16x4_t' using type 'float32x4_t'} } */
+  bfloat16x4_t vector1_4 = is_an_int_vec;  /* { dg-error {incompatible types when initializing type 'bfloat16x4_t' using type 'int32x4_t'} } */
+  bfloat16x4_t vector1_5 = is_a_float16_vec; /* { dg-error {incompatible types when initializing type 'bfloat16x4_t' using type 'float16x4_t'} } */
+  bfloat16x4_t vector1_6 = is_a_float_pair; /* { dg-error {incompatible types when initializing type 'bfloat16x4_t' using type 'float32x2_t'} } */
+  bfloat16x4_t vector1_7 = is_an_int_pair; /* { dg-error {incompatible types when initializing type 'bfloat16x4_t' using type 'int32x2_t'} } */
+  bfloat16x4_t vector1_8 = is_a_short_vec; /* { dg-error {incompatible types when initializing type 'bfloat16x4_t' using type 'int16x4_t'} } */
+
+  int32x4_t initi_1_1 = glob_bfloat_vec;   /* { dg-error {incompatible types when initializing type 'int32x4_t' using type 'bfloat16x4_t'} } */
+  float32x4_t initi_1_2 = glob_bfloat_vec; /* { dg-error {incompatible types when initializing type 'float32x4_t' using type 'bfloat16x4_t'} } */
+  float16x4_t initi_1_3 = glob_bfloat_vec; /* { dg-error {incompatible types when initializing type 'float16x4_t' using type 'bfloat16x4_t'} } */
+  float32x2_t initi_1_4 = glob_bfloat_vec; /* { dg-error {incompatible types when initializing type 'float32x2_t' using type 'bfloat16x4_t'} } */
+  int32x2_t initi_1_5 = glob_bfloat_vec;  /* { dg-error {incompatible types when initializing type 'int32x2_t' using type 'bfloat16x4_t'} } */
+  int16x4_t initi_1_6 = glob_bfloat_vec;  /* { dg-error {incompatible types when initializing type 'int16x4_t' using type 'bfloat16x4_t'} } */
+
+  bfloat16x4_t vector2_1 = {};
+  bfloat16x4_t vector2_2 = { glob_bfloat };
+  bfloat16x4_t vector2_3 = { glob_bfloat, glob_bfloat, glob_bfloat, glob_bfloat };
+  bfloat16x4_t vector2_4 = { 0 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x4_t vector2_5 = { 0.1 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x4_t vector2_6 = { is_a_float16 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x4_t vector2_7 = { is_a_float }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x4_t vector2_8 = { is_an_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x4_t vector2_9 = { is_a_short_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x4_t vector2_10 = { 0.0, 0, is_a_short_int, is_a_float }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  int32x4_t initi_2_1 = { glob_bfloat };   /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float32x4_t initi_2_2 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float16x4_t initi_2_3 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float32x2_t initi_2_4 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  int32x2_t initi_2_5 = { glob_bfloat };   /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  int16x4_t initi_2_6 = { glob_bfloat };   /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* Assignments to/from vectors.  */
+
+  glob_bfloat_vec = glob_bfloat_vec;
+  glob_bfloat_vec = 0;   /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'int'} } */
+  glob_bfloat_vec = 0.1; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'double'} } */
+  glob_bfloat_vec = is_a_float_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'float32x4_t'} } */
+  glob_bfloat_vec = is_an_int_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'int32x4_t'} } */
+  glob_bfloat_vec = is_a_float16_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'float16x4_t'} } */
+  glob_bfloat_vec = is_a_float_pair; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'float32x2_t'} } */
+  glob_bfloat_vec = is_an_int_pair; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'int32x2_t'} } */
+  glob_bfloat_vec = is_a_short_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x4_t' from type 'int16x4_t'} } */
+
+  is_an_int_vec = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'int32x4_t' from type 'bfloat16x4_t'} } */
+  is_a_float_vec = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'float32x4_t' from type 'bfloat16x4_t'} } */
+  is_a_float16_vec = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'float16x4_t' from type 'bfloat16x4_t'} } */
+  is_a_float_pair = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'float32x2_t' from type 'bfloat16x4_t'} } */
+  is_an_int_pair = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'int32x2_t' from type 'bfloat16x4_t'} } */
+  is_a_short_vec = glob_bfloat_vec;/* { dg-error {incompatible types when assigning to type 'int16x4_t' from type 'bfloat16x4_t'} } */
+
+  /* Assignments to/from elements.  */
+
+  vector2_3[0] = glob_bfloat;
+  vector2_3[0] = is_an_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = is_a_short_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = is_a_float; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = is_a_float16; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = 0; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = 0.1; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  glob_bfloat = vector2_3[0];
+  is_an_int = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_short_int = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_float = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_float16 = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* Compound literals.  */
+
+  (bfloat16x4_t) {};
+
+  (bfloat16x4_t) { 0 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16x4_t) { 0.1 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16x4_t) { is_a_float_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'float32x4_t'} } */
+  (bfloat16x4_t) { is_an_int_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'int32x4_t'} } */
+  (bfloat16x4_t) { is_a_float_pair }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'float32x2_t'} } */
+  (bfloat16x4_t) { is_an_int_pair }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'int32x2_t'} } */
+  (bfloat16x4_t) { is_a_float16_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'float16x4_t'} } */
+  (bfloat16x4_t) { is_a_short_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'int16x4_t'} } */
+
+  (bfloat16x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'bfloat16x4_t'} } */
+  (int32x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'int' using type 'bfloat16x4_t'} } */
+  (float32x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'float' using type 'bfloat16x4_t'} } */
+  (int32x2_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'int' using type 'bfloat16x4_t'} } */
+  (float16x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type '__fp16' using type 'bfloat16x4_t'} } */
+  (int16x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'short int' using type 'bfloat16x4_t'} } */
+
+  /* Casting.  */
+
+  (void) glob_bfloat_vec;
+  (bfloat16x4_t) glob_bfloat_vec;
+
+  (bfloat16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+  (short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x4_t' to type 'short int' which has different size} } */
+  (int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x4_t' to type 'int' which has different size} } */
+  (float16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+  (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+  (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+
+  (int32x4_t) glob_bfloat_vec; /* { dg-error {cannot convert a value of type 'bfloat16x4_t' to vector type '__simd128_int32_t' which has different size} } */
+  (float32x4_t) glob_bfloat_vec; /* { dg-error {cannot convert a value of type 'bfloat16x4_t' to vector type '__simd128_float32_t' which has different size} } */
+  (float16x4_t) glob_bfloat_vec;
+  (int32x2_t) glob_bfloat_vec;
+  (float32x2_t) glob_bfloat_vec;
+  (int16x4_t) glob_bfloat_vec;
+
+  (bfloat16x4_t) is_an_int_vec; /* { dg-error {cannot convert a value of type 'int32x4_t' to vector type '__simd64_bfloat16_t' which has different size} } */
+  (bfloat16x4_t) is_a_float_vec; /* { dg-error {cannot convert a value of type 'float32x4_t' to vector type '__simd64_bfloat16_t' which has different size} } */
+  (bfloat16x4_t) is_a_float16_vec;
+  (bfloat16x4_t) is_an_int_pair;
+  (bfloat16x4_t) is_a_float_pair;
+  (bfloat16x4_t) is_a_short_vec;
+  (bfloat16x4_t) is_a_double; /* { dg-error {cannot convert value to a vector} } */
+
+  /* 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[is_an_int];
+
+  struct struct1 {
+    bfloat16x4_t a;
+  };
+
+  union union1 {
+    bfloat16x4_t a;
+  };
+
+  /* Addressing and dereferencing.  */
+
+  bfloat16x4_t *bfloat_ptr = &vector0;
+  vector0 = *bfloat_ptr;
+
+  /* Pointer assignment.  */
+
+  bfloat16x4_t *bfloat_ptr2 = bfloat_ptr;
+  bfloat16x4_t *bfloat_ptr3 = array;
+
+  /* Pointer arithmetic.  */
+
+  ++bfloat_ptr;
+  --bfloat_ptr;
+  bfloat_ptr++;
+  bfloat_ptr--;
+  bfloat_ptr += 1;
+  bfloat_ptr -= 1;
+  bfloat_ptr - bfloat_ptr2;
+  bfloat_ptr = &bfloat_ptr3[0];
+  bfloat_ptr = &bfloat_ptr3[1];
+
+  /* Simple comparison.  */
+  vector0 > glob_bfloat_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  glob_bfloat_vec == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > is_a_float_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  is_a_float_vec == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > 0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  0 == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > 0.1; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  0.1 == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > is_an_int_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  is_an_int_vec == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Pointer comparison.  */
+
+  bfloat_ptr == &vector0;
+  bfloat_ptr != &vector0;
+  bfloat_ptr < &vector0;
+  bfloat_ptr <= &vector0;
+  bfloat_ptr > &vector0;
+  bfloat_ptr >= &vector0;
+  bfloat_ptr == bfloat_ptr2;
+  bfloat_ptr != bfloat_ptr2;
+  bfloat_ptr < bfloat_ptr2;
+  bfloat_ptr <= bfloat_ptr2;
+  bfloat_ptr > bfloat_ptr2;
+  bfloat_ptr >= bfloat_ptr2;
+
+  /* Conditional expressions.  */
+
+  0 ? vector0 : vector0;
+  0 ? vector0 : is_a_float_vec; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? is_a_float_vec : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? vector0 : is_a_float16_vec; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? is_a_float16_vec : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? vector0 : 0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? 0 : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? 0.1 : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? vector0 : 0.1; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? bfloat_ptr : bfloat_ptr2;
+  0 ? bfloat_ptr : float_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? float_ptr : bfloat_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+
+  vector0 ? vector0 : vector0; /* { dg-error {used vector type where scalar is required} } */
+  vector0 ? is_a_float16_vec : vector0; /* { dg-error {used vector type where scalar is required} } */
+  vector0 ? vector0 : is_a_float16_vec; /* { dg-error {used vector type where scalar is required} } */
+  vector0 ? is_a_float16_vec : is_a_float16_vec; /* { dg-error {used vector type where scalar is required} } */
+
+  /* Unary operators.  */
+
+  +vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  -vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  ~vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  !vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  *vector0; /* { dg-error {invalid type argument of unary '\*'} } */
+  __real vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  __imag vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  ++vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  --vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0++; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0--; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Binary arithmetic operations.  */
+
+  vector0 = glob_bfloat_vec + *bfloat_ptr; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 = glob_bfloat_vec + 0.1; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 = glob_bfloat_vec + 0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 = glob_bfloat_vec + is_a_float_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  return vector0;
+}
+
diff --git a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
new file mode 100644
index 00000000000..16669dcf009
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
@@ -0,0 +1,252 @@
+/* { dg-do assemble { target { arm*-*-* } } } */
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
+/* { dg-require-effective-target arm_v8_2a_fp16_neon_ok } */
+/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
+/* { dg-additional-options "-march=armv8.6-a+bf16+fp16 -Wno-pedantic -O3 --save-temps" }  */
+
+#include <arm_neon.h>
+
+bfloat16_t glob_bfloat;
+bfloat16x8_t glob_bfloat_vec;
+
+float32x4_t is_a_float_vec;
+
+float16x8_t *float_ptr;
+float16x8_t is_a_float16_vec;
+
+int32x4_t is_an_int_vec;
+int64x2_t is_a_long_int_pair;
+int16x8_t is_a_short_vec;
+
+int is_an_int;
+short is_a_short_int;
+float is_a_float;
+float is_a_float16;
+double is_a_double;
+
+bfloat16x8_t foo3 (void) { return (bfloat16x8_t) 0x12345678123456781234567812345678; }
+ /* { dg-error {integer constant is too large for its type} "" {target *-*-*} 27 } */
+ /* { dg-error {cannot convert a value of type 'long long int' to vector type '__simd128_bfloat16_t' which has different size} "" {target *-*-*} 27 } */
+
+bfloat16x8_t footest (bfloat16x8_t vector0)
+{
+  /* Initialisation  */
+
+  bfloat16x8_t vector1_1;
+  bfloat16x8_t vector1_2 = glob_bfloat_vec;
+  bfloat16x8_t vector1_3 = is_a_float_vec; /* { dg-error {incompatible types when initializing type 'bfloat16x8_t' using type 'float32x4_t'} } */
+  bfloat16x8_t vector1_4 = is_an_int_vec;  /* { dg-error {incompatible types when initializing type 'bfloat16x8_t' using type 'int32x4_t'} } */
+  bfloat16x8_t vector1_5 = is_a_float16_vec; /* { dg-error {incompatible types when initializing type 'bfloat16x8_t' using type 'float16x8_t'} } */
+  bfloat16x8_t vector1_7 = is_a_long_int_pair; /* { dg-error {incompatible types when initializing type 'bfloat16x8_t' using type 'int64x2_t'} } */
+  bfloat16x8_t vector1_8 = is_a_short_vec; /* { dg-error {incompatible types when initializing type 'bfloat16x8_t' using type 'int16x8_t'} } */
+
+  int32x4_t initi_1_1 = glob_bfloat_vec;   /* { dg-error {incompatible types when initializing type 'int32x4_t' using type 'bfloat16x8_t'} } */
+  float32x4_t initi_1_2 = glob_bfloat_vec; /* { dg-error {incompatible types when initializing type 'float32x4_t' using type 'bfloat16x8_t'} } */
+  float16x8_t initi_1_3 = glob_bfloat_vec; /* { dg-error {incompatible types when initializing type 'float16x8_t' using type 'bfloat16x8_t'} } */
+  int64x2_t initi_1_5 = glob_bfloat_vec;  /* { dg-error {incompatible types when initializing type 'int64x2_t' using type 'bfloat16x8_t'} } */
+  int16x8_t initi_1_6 = glob_bfloat_vec;  /* { dg-error {incompatible types when initializing type 'int16x8_t' using type 'bfloat16x8_t'} } */
+
+  bfloat16x8_t vector2_1 = {};
+  bfloat16x8_t vector2_2 = { glob_bfloat };
+  bfloat16x8_t vector2_3 = { glob_bfloat, glob_bfloat, glob_bfloat, glob_bfloat };
+  bfloat16x8_t vector2_4 = { 0 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x8_t vector2_5 = { 0.1 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x8_t vector2_6 = { is_a_float16 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x8_t vector2_7 = { is_a_float }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x8_t vector2_8 = { is_an_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x8_t vector2_9 = { is_a_short_int }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  bfloat16x8_t vector2_10 = { 0.0, 0, is_a_short_int, is_a_float }; /* { dg-error "invalid conversion to type 'bfloat16_t'" } */
+
+  int32x4_t initi_2_1 = { glob_bfloat };   /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float32x4_t initi_2_2 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  float16x8_t initi_2_3 = { glob_bfloat }; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  int64x2_t initi_2_5 = { glob_bfloat };   /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  int16x8_t initi_2_6 = { glob_bfloat };   /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* Assignments to/from vectors.  */
+
+  glob_bfloat_vec = glob_bfloat_vec;
+  glob_bfloat_vec = 0;   /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'int'} } */
+  glob_bfloat_vec = 0.1; /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'double'} } */
+  glob_bfloat_vec = is_a_float_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'float32x4_t'} } */
+  glob_bfloat_vec = is_an_int_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'int32x4_t'} } */
+  glob_bfloat_vec = is_a_float16_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'float16x8_t'} } */
+  glob_bfloat_vec = is_a_long_int_pair; /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'int64x2_t'} } */
+  glob_bfloat_vec = is_a_short_vec; /* { dg-error {incompatible types when assigning to type 'bfloat16x8_t' from type 'int16x8_t'} } */
+
+  is_an_int_vec = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'int32x4_t' from type 'bfloat16x8_t'} } */
+  is_a_float_vec = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'float32x4_t' from type 'bfloat16x8_t'} } */
+  is_a_float16_vec = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'float16x8_t' from type 'bfloat16x8_t'} } */
+  is_a_long_int_pair = glob_bfloat_vec; /* { dg-error {incompatible types when assigning to type 'int64x2_t' from type 'bfloat16x8_t'} } */
+  is_a_short_vec = glob_bfloat_vec;/* { dg-error {incompatible types when assigning to type 'int16x8_t' from type 'bfloat16x8_t'} } */
+
+  /* Assignments to/from elements.  */
+
+  vector2_3[0] = glob_bfloat;
+  vector2_3[0] = is_an_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = is_a_short_int; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = is_a_float; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = is_a_float16; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = 0; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  vector2_3[0] = 0.1; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+
+  glob_bfloat = vector2_3[0];
+  is_an_int = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_short_int = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_float = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+  is_a_float16 = vector2_3[0]; /* { dg-error {invalid conversion from type 'bfloat16_t'} } */
+
+  /* Compound literals.  */
+
+  (bfloat16x8_t) {};
+
+  (bfloat16x8_t) { 0 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16x8_t) { 0.1 }; /* { dg-error {invalid conversion to type 'bfloat16_t'} } */
+  (bfloat16x8_t) { is_a_float_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'float32x4_t'} } */
+  (bfloat16x8_t) { is_an_int_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'int32x4_t'} } */
+  (bfloat16x8_t) { is_a_long_int_pair }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'int64x2_t'} } */
+  (bfloat16x8_t) { is_a_float16_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'float16x8_t'} } */
+  (bfloat16x8_t) { is_a_short_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'int16x8_t'} } */
+
+  (bfloat16x8_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type '__bf16' using type 'bfloat16x8_t'} } */
+  (int32x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'int' using type 'bfloat16x8_t'} } */
+  (float32x4_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'float' using type 'bfloat16x8_t'} } */
+  (int64x2_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'long long int' using type 'bfloat16x8_t'} } */
+  (float16x8_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type '__fp16' using type 'bfloat16x8_t'} } */
+  (int16x8_t) { glob_bfloat_vec }; /* { dg-error {incompatible types when initializing type 'short int' using type 'bfloat16x8_t'} } */
+
+  /* Casting.  */
+
+  (void) glob_bfloat_vec;
+  (bfloat16x8_t) glob_bfloat_vec;
+
+  (bfloat16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+  (short) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x8_t' to type 'short int' which has different size} } */
+  (int) glob_bfloat_vec; /* { dg-error {cannot convert a vector of type 'bfloat16x8_t' to type 'int' which has different size} } */
+  (float16_t) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+  (float) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+  (double) glob_bfloat_vec; /* { dg-error {aggregate value used where a floating-point was expected} } */
+
+  (int32x4_t) glob_bfloat_vec;
+  (float32x4_t) glob_bfloat_vec;
+  (float16x8_t) glob_bfloat_vec;
+  (int64x2_t) glob_bfloat_vec;
+  (int16x8_t) glob_bfloat_vec;
+
+  (bfloat16x8_t) is_an_int_vec;
+  (bfloat16x8_t) is_a_float_vec;
+  (bfloat16x8_t) is_a_float16_vec;
+  (bfloat16x8_t) is_a_long_int_pair;
+  (bfloat16x8_t) is_a_short_vec;
+
+  /* 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;
+  };
+
+  /* Addressing and dereferencing.  */
+
+  bfloat16x8_t *bfloat_ptr = &vector0;
+  vector0 = *bfloat_ptr;
+
+  /* Pointer assignment.  */
+
+  bfloat16x8_t *bfloat_ptr2 = bfloat_ptr;
+  bfloat16x8_t *bfloat_ptr3 = array;
+
+  /* Pointer arithmetic.  */
+
+  ++bfloat_ptr;
+  --bfloat_ptr;
+  bfloat_ptr++;
+  bfloat_ptr--;
+  bfloat_ptr += 1;
+  bfloat_ptr -= 1;
+  bfloat_ptr - bfloat_ptr2;
+  bfloat_ptr = &bfloat_ptr3[0];
+  bfloat_ptr = &bfloat_ptr3[1];
+
+  /* Simple comparison.  */
+  vector0 > glob_bfloat_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  glob_bfloat_vec == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > is_a_float_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  is_a_float_vec == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > 0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  0 == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > 0.1; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  0.1 == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 > is_an_int_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  is_an_int_vec == vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Pointer comparison.  */
+
+  bfloat_ptr == &vector0;
+  bfloat_ptr != &vector0;
+  bfloat_ptr < &vector0;
+  bfloat_ptr <= &vector0;
+  bfloat_ptr > &vector0;
+  bfloat_ptr >= &vector0;
+  bfloat_ptr == bfloat_ptr2;
+  bfloat_ptr != bfloat_ptr2;
+  bfloat_ptr < bfloat_ptr2;
+  bfloat_ptr <= bfloat_ptr2;
+  bfloat_ptr > bfloat_ptr2;
+  bfloat_ptr >= bfloat_ptr2;
+
+  /* Conditional expressions.  */
+
+  0 ? vector0 : vector0;
+  0 ? vector0 : is_a_float_vec; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? is_a_float_vec : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? vector0 : is_a_float16_vec; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? is_a_float16_vec : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? vector0 : 0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? 0 : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? 0.1 : vector0; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? vector0 : 0.1; /* { dg-error {type mismatch in conditional expression} } */
+  0 ? bfloat_ptr : bfloat_ptr2;
+  0 ? bfloat_ptr : float_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+  0 ? float_ptr : bfloat_ptr; /* { dg-error {pointer type mismatch in conditional expression} } */
+
+  vector0 ? vector0 : vector0; /* { dg-error {used vector type where scalar is required} } */
+  vector0 ? is_a_float16_vec : vector0; /* { dg-error {used vector type where scalar is required} } */
+  vector0 ? vector0 : is_a_float16_vec; /* { dg-error {used vector type where scalar is required} } */
+  vector0 ? is_a_float16_vec : is_a_float16_vec; /* { dg-error {used vector type where scalar is required} } */
+
+  /* Unary operators.  */
+
+  +vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  -vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  ~vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  !vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  *vector0; /* { dg-error {invalid type argument of unary '\*'} } */
+  __real vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  __imag vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  ++vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  --vector0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0++; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0--; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  /* Binary arithmetic operations.  */
+
+  vector0 = glob_bfloat_vec + *bfloat_ptr; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 = glob_bfloat_vec + 0.1; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 = glob_bfloat_vec + 0; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+  vector0 = glob_bfloat_vec + is_a_float_vec; /* { dg-error {operation not permitted on type 'bfloat16_t'} } */
+
+  return vector0;
+}
+

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2]
  2020-01-10 18:48 [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2] Stam Markianos-Wright
@ 2020-01-13 10:58 ` Kyrill Tkachov
  2020-01-16 16:02   ` Stam Markianos-Wright
  2020-05-16  8:49 ` Andreas Schwab
  1 sibling, 1 reply; 4+ messages in thread
From: Kyrill Tkachov @ 2020-01-13 10:58 UTC (permalink / raw)
  To: Stam Markianos-Wright, gcc-patches
  Cc: Richard Earnshaw, Richard Sandiford, Ramana Radhakrishnan, nickc

Hi Stam,

On 1/10/20 6:47 PM, Stam Markianos-Wright wrote:
> Hi all,
>
> This patch is part 2 of Bfloat16_t enablement in the ARM 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 arm-none-eabi passed successfully.
>
> Ok for trunk?


Ok.

Thanks,

Kyrill


>
> 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 
>
>
>
>
> gcc/ChangeLog:
>
> 2020-01-10  Stam Markianos-Wright <stam.markianos-wright@arm.com>
>
>         * config/arm/arm.c
>         (arm_invalid_conversion): New function for target hook.
>         (arm_invalid_unary_op): New function for target hook.
>         (arm_invalid_binary_op): New function for target hook.
>
> 2020-01-10  Stam Markianos-Wright <stam.markianos-wright@arm.com>
>
>         * gcc.target/arm/bfloat16_scalar_typecheck.c: New test.
>         * gcc.target/arm/bfloat16_vector_typecheck_1.c: New test.
>         * gcc.target/arm/bfloat16_vector_typecheck_2.c: New test.
>
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2]
  2020-01-13 10:58 ` Kyrill Tkachov
@ 2020-01-16 16:02   ` Stam Markianos-Wright
  0 siblings, 0 replies; 4+ messages in thread
From: Stam Markianos-Wright @ 2020-01-16 16:02 UTC (permalink / raw)
  To: Kyrill Tkachov, gcc-patches
  Cc: Richard Earnshaw, Richard Sandiford, Ramana Radhakrishnan, nickc



On 1/13/20 10:43 AM, Kyrill Tkachov wrote:
> Hi Stam,
> 
> On 1/10/20 6:47 PM, Stam Markianos-Wright wrote:
>> Hi all,
>>
>> This patch is part 2 of Bfloat16_t enablement in the ARM 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 arm-none-eabi passed successfully.
>>
>> Ok for trunk?
> 
> 
> Ok.
> 
> Thanks,
> 
> Kyrill

Committed as r10-6021-g3ea9140170b8a511822b1a873dea1227093f3ccf

Thank you!
Stam
> 
> 
>>
>> 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 
>>
>>
>>
>>
>> gcc/ChangeLog:
>>
>> 2020-01-10  Stam Markianos-Wright <stam.markianos-wright@arm.com>
>>
>>         * config/arm/arm.c
>>         (arm_invalid_conversion): New function for target hook.
>>         (arm_invalid_unary_op): New function for target hook.
>>         (arm_invalid_binary_op): New function for target hook.
>>
>> 2020-01-10  Stam Markianos-Wright <stam.markianos-wright@arm.com>
>>
>>         * gcc.target/arm/bfloat16_scalar_typecheck.c: New test.
>>         * gcc.target/arm/bfloat16_vector_typecheck_1.c: New test.
>>         * gcc.target/arm/bfloat16_vector_typecheck_2.c: New test.
>>
>>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2]
  2020-01-10 18:48 [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2] Stam Markianos-Wright
  2020-01-13 10:58 ` Kyrill Tkachov
@ 2020-05-16  8:49 ` Andreas Schwab
  1 sibling, 0 replies; 4+ messages in thread
From: Andreas Schwab @ 2020-05-16  8:49 UTC (permalink / raw)
  To: Stam Markianos-Wright
  Cc: gcc-patches, Richard Earnshaw, Richard Sandiford,
	Ramana Radhakrishnan, Kyrylo Tkachov, nickc

On Jan 10 2020, Stam Markianos-Wright wrote:

> diff --git a/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
> new file mode 100644
> index 00000000000..16669dcf009
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/bfloat16_vector_typecheck_2.c
> @@ -0,0 +1,252 @@
> +/* { dg-do assemble { target { arm*-*-* } } } */
> +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } } */
> +/* { dg-require-effective-target arm_v8_2a_fp16_neon_ok } */
> +/* { dg-require-effective-target arm_v8_2a_bf16_neon_ok } */
> +/* { dg-additional-options "-march=armv8.6-a+bf16+fp16 -Wno-pedantic -O3 --save-temps" }  */
> +
> +#include <arm_neon.h>
> +
> +bfloat16_t glob_bfloat;
> +bfloat16x8_t glob_bfloat_vec;
> +
> +float32x4_t is_a_float_vec;
> +
> +float16x8_t *float_ptr;
> +float16x8_t is_a_float16_vec;
> +
> +int32x4_t is_an_int_vec;
> +int64x2_t is_a_long_int_pair;
> +int16x8_t is_a_short_vec;
> +
> +int is_an_int;
> +short is_a_short_int;
> +float is_a_float;
> +float is_a_float16;
> +double is_a_double;
> +
> +bfloat16x8_t foo3 (void) { return (bfloat16x8_t) 0x12345678123456781234567812345678; }
> + /* { dg-error {integer constant is too large for its type} "" {target *-*-*} 27 } */
> + /* { dg-error {cannot convert a value of type 'long long int' to vector type '__simd128_bfloat16_t' which has different size} "" {target *-*-*} 27 } */

Duplicate test name.  Don't use absolute line numbers.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-16  8:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-10 18:48 [GCC][PATCH][ARM] Add Bfloat16_t scalar type, vector types and machine modes to ARM back-end [2/2] Stam Markianos-Wright
2020-01-13 10:58 ` Kyrill Tkachov
2020-01-16 16:02   ` Stam Markianos-Wright
2020-05-16  8:49 ` Andreas Schwab

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).