gcc/ChangeLog:

	PR target/106742
	* config/i386/i386-expand.cc (ix86_expand_vector_init_duplicate):
	Handle V8BF mode.
	(expand_vec_perm_broadcast_1): Ditto.
	* config/i386/sse.md (avx512fmaskhalfmode): Add BF vector mode.
	(vec_set<mode>_0): Add @ to it.
	(@vec_set<mode>_0): Ditto.
	(vec_interleave_high<mode><mask_name>): Ditto.
	(@vec_interleave_high<mode><mask_name>): Ditto.
	(vec_interleave_low<mode><mask_name>): Ditto.
	(@vec_interleave_low<mode><mask_name>): Ditto.
	* config/i386/subst.md (SUBST_V): Add BF vector mode.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr106742.c: New test.
---
 gcc/config/i386/i386-expand.cc           | 15 +++++++++------
 gcc/config/i386/sse.md                   |  7 ++++---
 gcc/config/i386/subst.md                 |  1 +
 gcc/testsuite/gcc.target/i386/pr106742.c | 10 ++++++++++
 4 files changed, 24 insertions(+), 9 deletions(-)  create mode 100644 gcc/testsuite/gcc.target/i386/pr106742.c

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 836ebc82d67..d7b49c99dc8 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -15034,11 +15034,12 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, machine_mode mode,
 	  dperm.op0 = dperm.op1 = gen_reg_rtx (mode);
 	  dperm.one_operand_p = true;
 
-	  if (mode == V8HFmode)
+	  if (mode == V8HFmode || mode == V8BFmode)
 	    {
-	      tmp1 = force_reg (HFmode, val);
+	      tmp1 = force_reg (GET_MODE_INNER (mode), val);
 	      tmp2 = gen_reg_rtx (mode);
-	      emit_insn (gen_vec_setv8hf_0 (tmp2, CONST0_RTX (mode), tmp1));
+	      emit_insn (maybe_gen_vec_set_0 (mode, tmp2,
+					      CONST0_RTX (mode), tmp1));
 	      tmp1 = gen_lowpart (mode, tmp2);
 	    }
 	  else
@@ -21826,21 +21827,23 @@ expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d)
       return true;
 
     case E_V8HFmode:
+    case E_V8BFmode:
       /* This can be implemented via interleave and pshufd.  */
       if (d->testing_p)
 	return true;
 
+      rtx (*maybe_gen) (machine_mode, int, rtx, rtx, rtx);
       if (elt >= nelt2)
 	{
-	  gen = gen_vec_interleave_highv8hf;
+	  maybe_gen = maybe_gen_vec_interleave_high;
 	  elt -= nelt2;
 	}
       else
-	gen = gen_vec_interleave_lowv8hf;
+	maybe_gen = maybe_gen_vec_interleave_low;
       nelt2 /= 2;
 
       dest = gen_reg_rtx (vmode);
-      emit_insn (gen (dest, op0, op0));
+      emit_insn (maybe_gen (vmode, 1, dest, op0, op0));
 
       vmode = V4SImode;
       op0 = gen_lowpart (vmode, dest);
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 259048481b6..72acf0b3e23 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -984,6 +984,7 @@
    (V16SI "QI") (V8SI  "QI") (V4SI  "QI")
    (V8DI  "QI") (V4DI  "QI") (V2DI  "QI")
    (V32HF "HI") (V16HF "QI") (V8HF  "QI")
+   (V32BF "HI") (V16BF "QI") (V8BF  "QI")
    (V16SF "QI") (V8SF  "QI") (V4SF  "QI")
    (V8DF  "QI") (V4DF  "QI") (V2DF  "QI")])
 
@@ -10712,7 +10713,7 @@
 	   ]
 	   (symbol_ref "true")))])
 
-(define_insn "vec_set<mode>_0"
+(define_insn "@vec_set<mode>_0"
   [(set (match_operand:V8_128 0 "register_operand"
 	  "=v,v,v,x,x,Yr,*x,x,x,x,v,v")
 	(vec_merge:V8_128
@@ -17895,7 +17896,7 @@
    (set_attr "prefix" "maybe_evex")
    (set_attr "mode" "OI")])
 
-(define_insn "vec_interleave_high<mode><mask_name>"
+(define_insn "@vec_interleave_high<mode><mask_name>"
   [(set (match_operand:V8_128 0 "register_operand" "=x,Yw")
 	(vec_select:V8_128
 	  (vec_concat:<ssedoublevecmode>
@@ -17963,7 +17964,7 @@
    (set_attr "prefix" "maybe_evex")
    (set_attr "mode" "OI")])
 
-(define_insn "vec_interleave_low<mode><mask_name>"
+(define_insn "@vec_interleave_low<mode><mask_name>"
   [(set (match_operand:V8_128 0 "register_operand" "=x,Yw")
 	(vec_select:V8_128
 	  (vec_concat:<ssedoublevecmode>
diff --git a/gcc/config/i386/subst.md b/gcc/config/i386/subst.md index 0b7588237fe..e169282fbbc 100644
--- a/gcc/config/i386/subst.md
+++ b/gcc/config/i386/subst.md
@@ -25,6 +25,7 @@
    V16SI V8SI  V4SI
    V8DI  V4DI  V2DI
    V32HF V16HF V8HF
+   V32BF V16BF V8BF
    V16SF V8SF  V4SF
    V8DF  V4DF  V2DF])
 
diff --git a/gcc/testsuite/gcc.target/i386/pr106742.c b/gcc/testsuite/gcc.target/i386/pr106742.c
new file mode 100644
index 00000000000..36ac93c9623
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr106742.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -mno-sse4 -O1" } */ typedef __bf16 v8bf 
+__attribute__ ((__vector_size__ (16)));
+
+v8bf
+vec_init_dup_v8bf (__bf16 a1)
+{
+  return __extension__ (v8bf) { a1, a1, a1, a1, a1, a1, a1, a1 }; }
+/* { dg-final { scan-assembler-times "pinsrw" 1} } */
--
2.18.2