diff mbox series

[rs6000,V2] Add Power 9 support for vec_first builtins

Message ID 1510270962.10279.72.camel@us.ibm.com
State New
Headers show
Series [rs6000,V2] Add Power 9 support for vec_first builtins | expand

Commit Message

Carl Love Nov. 9, 2017, 11:42 p.m. UTC
GCC Maintainers:

The following is an updated patch to add support for the
vec_first_match_index, vec_first_match_or_eos_index,
vec_first_mismatch_index, and vec_first_mismatch_or_eos_index builtins
for ISA 3.0.  I have addressed the comments from Segher and Jakub.

The patch has been re-tested on:

  powerpc64le-unknown-linux-gnu (Power 8 LE)
  powerpc64le-unknown-linux-gnu (Power 9 LE)

without regressions.  

Please let me know if the following patch is acceptable.  Thanks.

                      Carl 


---------------------------------------------------------------------------------

gcc/ChangeLog:

2017-11-07  Carl Love  <cel@us.ibm.com>

	* config/rs6000/rs6000-c.c (altivec_overloaded_builtins):
	Add support for builtins:
	unsigned int vec_first_{,miss}_match_{,or_eos}index (
	vector {un,}signed {char,int,short},
	vector {un,}signed {char,int,short}) arguments.
	* config/rs6000/rs6000-builtin.def (VFIRSTMATCHINDEX,
	VFIRSTMATCHOREOSINDEX, VFIRSTMISMATCHINDEX, VFIRSTMISMATCHOREOSINDEX):
	Add BU_P9V_AV_2 expansions for the builtins.
	* config/rs6000/altivec.h (vec_first_match_index,
	vec_first_mismatch_index, vec_first_match_or_eos_index,
	vec_first_mismatch_or_eos_index): Add #defines for the builtins.
	* config/rs6000/rs6000-protos.h (bytes_in_mode): Add
	new extern	declaration.
	* config/rs6000/rs6000.c (bytes_in_mode): Add new function.
	* config/rs6000/vsx.md (first_match_index_<mode>,
	first_match_or_eos_index_<mode>, first_mismatch_index_<mode>,
	first_mismatch_or_eos_index_<mode>): Add define expand.
	(vctzlsbb_<mode>): Add mode field to define_insn for vctzlsbb.
	* doc/extend.texi: Update the built-in documenation file for the new
	built-in functions.

gcc/testsuite/ChangeLog:

2017-11-07  Carl Love  <cel@us.ibm.com>

	* gcc.target/powerpc/builtins-6-p9-runnable.c: Add new runnable test.
	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c (dg-error): Add _v16qi to
	__builtin_altivec_vctzlsbb.
---
 gcc/config/rs6000/altivec.h                        |    4 +
 gcc/config/rs6000/rs6000-builtin.def               |   34 +-
 gcc/config/rs6000/rs6000-c.c                       |   64 +-
 gcc/config/rs6000/vsx.md                           |  151 ++-
 gcc/doc/extend.texi                                |   45 +
 .../gcc.target/powerpc/builtins-6-p9-runnable.c    | 1046 ++++++++++++++++++++
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c      |    2 +-
 7 files changed, 1340 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-6-p9-runnable.c

Comments

Segher Boessenkool Nov. 10, 2017, 6:37 p.m. UTC | #1
Hi!

On Thu, Nov 09, 2017 at 03:42:42PM -0800, Carl Love wrote:
> 	* config/rs6000/rs6000-c.c (altivec_overloaded_builtins):
> 	Add support for builtins:
> 	unsigned int vec_first_{,miss}_match_{,or_eos}index (

Don't end a line with an opening parenthesis.

> 	vector {un,}signed {char,int,short},
> 	vector {un,}signed {char,int,short}) arguments.
> 	* config/rs6000/rs6000-builtin.def (VFIRSTMATCHINDEX,
> 	VFIRSTMATCHOREOSINDEX, VFIRSTMISMATCHINDEX, VFIRSTMISMATCHOREOSINDEX):
> 	Add BU_P9V_AV_2 expansions for the builtins.
> 	* config/rs6000/altivec.h (vec_first_match_index,
> 	vec_first_mismatch_index, vec_first_match_or_eos_index,
> 	vec_first_mismatch_or_eos_index): Add #defines for the builtins.
> 	* config/rs6000/rs6000-protos.h (bytes_in_mode): Add
> 	new extern	declaration.

There's a tab character there.

> 	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c (dg-error): Add _v16qi to
> 	__builtin_altivec_vctzlsbb.

"dg-error" is not a function name or similar; there can be many such
statements with the same name even!  I'd do something like

	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c: Adjust expected error
	message.

> +	     first_mismatch_index_v16qi)
> +BU_P9V_AV_2 (VFIRSTMISMATCHINDEX_V8HI, "first_mismatch_index_v8hi", CONST,
> +	     first_mismatch_index_v8hi)
> +BU_P9V_AV_2 (VFIRSTMISMATCHINDEX_V4SI, "first_mismatch_index_v4si", CONST,
> +	     first_mismatch_index_v4si)
> +BU_P9V_AV_2 (VFIRSTMISMATCHOREOSINDEX_V16QI, "first_mismatch_or_eos_index_v16qi",
> +	     CONST, first_mismatch_or_eos_index_v16qi)
> +BU_P9V_AV_2 (VFIRSTMISMATCHOREOSINDEX_V8HI, "first_mismatch_or_eos_index_v8hi", CONST,
> +	     first_mismatch_or_eos_index_v8hi)
> +BU_P9V_AV_2 (VFIRSTMISMATCHOREOSINDEX_V4SI, "first_mismatch_or_eos_index_v4si", CONST,
> +	      first_mismatch_or_eos_index_v4si)

Some of those lines are too long; there's not terribly much you can do
about that, but you have moved "CONST" to the next line in one case and not
in others?  And that last line is unaligned (has a space to many).

Other than those nits it looks fine.  Please commit to trunk.  Thanks!


Segher
diff mbox series

Patch

diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h
index cec617a20..646712d31 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -420,6 +420,10 @@ 
 
 #ifdef __POWER9_VECTOR__
 /* Vector additions added in ISA 3.0.  */
+#define vec_first_match_index __builtin_vec_first_match_index
+#define vec_first_match_or_eos_index __builtin_vec_first_match_or_eos_index
+#define vec_first_mismatch_index __builtin_vec_first_mismatch_index
+#define vec_first_mismatch_or_eos_index __builtin_vec_first_mismatch_or_eos_index
 #define vec_pack_to_short_fp32 __builtin_vec_convert_4f32_8i16
 #define vec_parity_lsbb __builtin_vec_vparity_lsbb
 #define vec_vctz __builtin_vec_vctz
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 9dddc1101..4fa13e681 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2006,6 +2006,31 @@  BU_P9V_AV_2 (VSLV,		"vslv",			CONST, vslv)
 BU_P9V_AV_2 (VSRV,		"vsrv",			CONST, vsrv)
 BU_P9V_AV_2 (CONVERT_4F32_8I16, "convert_4f32_8i16", CONST, convert_4f32_8i16)
 
+BU_P9V_AV_2 (VFIRSTMATCHINDEX_V16QI, "first_match_index_v16qi", CONST,
+	     first_match_index_v16qi)
+BU_P9V_AV_2 (VFIRSTMATCHINDEX_V8HI, "first_match_index_v8hi", CONST,
+	     first_match_index_v8hi)
+BU_P9V_AV_2 (VFIRSTMATCHINDEX_V4SI, "first_match_index_v4si", CONST,
+	     first_match_index_v4si)
+BU_P9V_AV_2 (VFIRSTMATCHOREOSINDEX_V16QI, "first_match_or_eos_index_v16qi",
+	     CONST, first_match_or_eos_index_v16qi)
+BU_P9V_AV_2 (VFIRSTMATCHOREOSINDEX_V8HI, "first_match_or_eos_index_v8hi",
+	     CONST, first_match_or_eos_index_v8hi)
+BU_P9V_AV_2 (VFIRSTMATCHOREOSINDEX_V4SI, "first_match_or_eos_index_v4si",
+	     CONST, first_match_or_eos_index_v4si)
+BU_P9V_AV_2 (VFIRSTMISMATCHINDEX_V16QI, "first_mismatch_index_v16qi", CONST,
+	     first_mismatch_index_v16qi)
+BU_P9V_AV_2 (VFIRSTMISMATCHINDEX_V8HI, "first_mismatch_index_v8hi", CONST,
+	     first_mismatch_index_v8hi)
+BU_P9V_AV_2 (VFIRSTMISMATCHINDEX_V4SI, "first_mismatch_index_v4si", CONST,
+	     first_mismatch_index_v4si)
+BU_P9V_AV_2 (VFIRSTMISMATCHOREOSINDEX_V16QI, "first_mismatch_or_eos_index_v16qi",
+	     CONST, first_mismatch_or_eos_index_v16qi)
+BU_P9V_AV_2 (VFIRSTMISMATCHOREOSINDEX_V8HI, "first_mismatch_or_eos_index_v8hi", CONST,
+	     first_mismatch_or_eos_index_v8hi)
+BU_P9V_AV_2 (VFIRSTMISMATCHOREOSINDEX_V4SI, "first_mismatch_or_eos_index_v4si", CONST,
+	      first_mismatch_or_eos_index_v4si)
+
 /* ISA 3.0 vector overloaded 2-argument functions. */
 BU_P9V_OVERLOAD_2 (VSLV,	"vslv")
 BU_P9V_OVERLOAD_2 (VSRV,	"vsrv")
@@ -2082,6 +2107,11 @@  BU_P9V_OVERLOAD_1 (VEXTRACT_FP_FROM_SHORTH, "vextract_fp_from_shorth")
 BU_P9V_OVERLOAD_1 (VEXTRACT_FP_FROM_SHORTL, "vextract_fp_from_shortl")
 
 /* ISA 3.0 vector scalar overloaded 2 argument functions.  */
+BU_P9V_OVERLOAD_2 (VFIRSTMATCHINDEX,	"first_match_index")
+BU_P9V_OVERLOAD_2 (VFIRSTMISMATCHINDEX,	"first_mismatch_index")
+BU_P9V_OVERLOAD_2 (VFIRSTMATCHOREOSINDEX,	"first_match_or_eos_index")
+BU_P9V_OVERLOAD_2 (VFIRSTMISMATCHOREOSINDEX,	"first_mismatch_or_eos_index")
+
 BU_P9V_OVERLOAD_2 (VSIEDP,	"scalar_insert_exp")
 
 BU_P9V_OVERLOAD_2 (VSTDC,	"scalar_test_data_class")
@@ -2149,7 +2179,9 @@  BU_P9V_64BIT_AV_X (XST_LEN_R,	"xst_len_r",	MISC)
 
 /* 1 argument vector functions added in ISA 3.0 (power9). */
 BU_P9V_AV_1 (VCLZLSBB, "vclzlsbb",		CONST,	vclzlsbb)
-BU_P9V_AV_1 (VCTZLSBB, "vctzlsbb",		CONST,	vctzlsbb)
+BU_P9V_AV_1 (VCTZLSBB_V16QI, "vctzlsbb_v16qi",	CONST,	vctzlsbb_v16qi)
+BU_P9V_AV_1 (VCTZLSBB_V8HI, "vctzlsbb_v8hi",	CONST,	vctzlsbb_v8hi)
+BU_P9V_AV_1 (VCTZLSBB_V4SI, "vctzlsbb_v4si",	CONST,	vctzlsbb_v4si)
 
 /* Built-in support for Power9 "VSU option" string operations includes
    new awareness of the "vector compare not equal" (vcmpneb, vcmpneb.,
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 0959c0b48..c397d2060 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -2411,6 +2411,62 @@  const struct altivec_builtin_types altivec_overloaded_builtins[] = {
   { P9V_BUILTIN_VEC_CONVERT_4F32_8I16, P9V_BUILTIN_CONVERT_4F32_8I16,
     RS6000_BTI_unsigned_V8HI, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
 
+  { P9V_BUILTIN_VEC_VFIRSTMATCHINDEX, P9V_BUILTIN_VFIRSTMATCHINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHINDEX, P9V_BUILTIN_VFIRSTMATCHINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHINDEX, P9V_BUILTIN_VFIRSTMATCHINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHINDEX, P9V_BUILTIN_VFIRSTMATCHINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHINDEX, P9V_BUILTIN_VFIRSTMATCHINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHINDEX, P9V_BUILTIN_VFIRSTMATCHINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHOREOSINDEX, P9V_BUILTIN_VFIRSTMATCHOREOSINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHOREOSINDEX, P9V_BUILTIN_VFIRSTMATCHOREOSINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHOREOSINDEX, P9V_BUILTIN_VFIRSTMATCHOREOSINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHOREOSINDEX, P9V_BUILTIN_VFIRSTMATCHOREOSINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHOREOSINDEX, P9V_BUILTIN_VFIRSTMATCHOREOSINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMATCHOREOSINDEX, P9V_BUILTIN_VFIRSTMATCHOREOSINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHINDEX, P9V_BUILTIN_VFIRSTMISMATCHINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHINDEX, P9V_BUILTIN_VFIRSTMISMATCHINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHINDEX, P9V_BUILTIN_VFIRSTMISMATCHINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHINDEX, P9V_BUILTIN_VFIRSTMISMATCHINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHINDEX, P9V_BUILTIN_VFIRSTMISMATCHINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHINDEX, P9V_BUILTIN_VFIRSTMISMATCHINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHOREOSINDEX,
+    P9V_BUILTIN_VFIRSTMISMATCHOREOSINDEX_V16QI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V16QI, RS6000_BTI_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHOREOSINDEX,
+    P9V_BUILTIN_VFIRSTMISMATCHOREOSINDEX_V16QI, RS6000_BTI_UINTSI,
+    RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHOREOSINDEX,
+    P9V_BUILTIN_VFIRSTMISMATCHOREOSINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHOREOSINDEX,
+    P9V_BUILTIN_VFIRSTMISMATCHOREOSINDEX_V8HI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHOREOSINDEX,
+    P9V_BUILTIN_VFIRSTMISMATCHOREOSINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
+  { P9V_BUILTIN_VEC_VFIRSTMISMATCHOREOSINDEX,
+    P9V_BUILTIN_VFIRSTMISMATCHOREOSINDEX_V4SI,
+    RS6000_BTI_UINTSI, RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI, 0 },
+
   { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM,
     RS6000_BTI_V8HI, RS6000_BTI_V4SI, RS6000_BTI_V4SI, 0 },
   { ALTIVEC_BUILTIN_VEC_VPKUWUM, ALTIVEC_BUILTIN_VPKUWUM,
@@ -5189,10 +5245,14 @@  const struct altivec_builtin_types altivec_overloaded_builtins[] = {
   { P9V_BUILTIN_VEC_VCLZLSBB, P9V_BUILTIN_VCLZLSBB,
     RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 },
 
-  { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB,
+  { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB_V16QI,
     RS6000_BTI_INTSI, RS6000_BTI_V16QI, 0, 0 },
-  { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB,
+  { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB_V16QI,
     RS6000_BTI_INTSI, RS6000_BTI_unsigned_V16QI, 0, 0 },
+  { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB_V8HI,
+    RS6000_BTI_INTSI, RS6000_BTI_V8HI, 0, 0 },
+  { P9V_BUILTIN_VEC_VCTZLSBB, P9V_BUILTIN_VCTZLSBB_V4SI,
+    RS6000_BTI_INTSI, RS6000_BTI_V4SI, 0, 0 },
 
   { P9V_BUILTIN_VEC_VEXTRACT4B, P9V_BUILTIN_VEXTRACT4B,
     RS6000_BTI_INTDI, RS6000_BTI_V16QI, RS6000_BTI_UINTSI, 0 },
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 901688ed1..335e5c1a6 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -418,6 +418,10 @@ 
    UNSPEC_VCMPNEZW
    UNSPEC_XXEXTRACTUW
    UNSPEC_XXINSERTW
+   UNSPEC_VSX_FIRST_MATCH_INDEX
+   UNSPEC_VSX_FIRST_MATCH_EOS_INDEX
+   UNSPEC_VSX_FIRST_MISMATCH_INDEX
+   UNSPEC_VSX_FIRST_MISMATCH_EOS_INDEX
   ])
 
 ;; VSX moves
@@ -4345,6 +4349,149 @@ 
   "vcmpnez<VSX_EXTRACT_WIDTH>. %0,%1,%2"
   [(set_attr "type" "vecsimple")])
 
+;; Return first position of match between vectors
+(define_expand "first_match_index_<mode>"
+  [(match_operand:SI 0 "register_operand")
+   (unspec:SI [(match_operand:VSX_EXTRACT_I 1 "register_operand")
+	       (match_operand:VSX_EXTRACT_I 2 "register_operand")]
+  UNSPEC_VSX_FIRST_MATCH_INDEX)]
+  "TARGET_P9_VECTOR"
+{
+  int sh;
+
+  rtx cmp_result = gen_reg_rtx (<MODE>mode);
+  rtx not_result = gen_reg_rtx (<MODE>mode);
+
+  emit_insn (gen_vcmpnez<VSX_EXTRACT_WIDTH> (cmp_result, operands[1],
+					     operands[2]));
+  emit_insn (gen_one_cmpl<mode>2 (not_result, cmp_result));
+
+  sh = GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) / 2;
+
+  if (<MODE>mode == V16QImode)
+    emit_insn (gen_vctzlsbb_<mode> (operands[0], not_result));
+  else
+    {
+      rtx tmp = gen_reg_rtx (SImode);
+      emit_insn (gen_vctzlsbb_<mode> (tmp, not_result));
+      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (sh)));
+    }
+  DONE;
+})
+
+;; Return first position of match between vectors or end of string (EOS)
+(define_expand "first_match_or_eos_index_<mode>"
+  [(match_operand:SI 0 "register_operand")
+   (unspec: SI [(match_operand:VSX_EXTRACT_I 1 "register_operand")
+   (match_operand:VSX_EXTRACT_I 2 "register_operand")]
+  UNSPEC_VSX_FIRST_MATCH_EOS_INDEX)]
+  "TARGET_P9_VECTOR"
+{
+  int sh;
+  rtx cmpz1_result = gen_reg_rtx (<MODE>mode);
+  rtx cmpz2_result = gen_reg_rtx (<MODE>mode);
+  rtx cmpz_result = gen_reg_rtx (<MODE>mode);
+  rtx and_result = gen_reg_rtx (<MODE>mode);
+  rtx result = gen_reg_rtx (<MODE>mode);
+  rtx vzero = gen_reg_rtx (<MODE>mode);
+
+  /* Vector with zeros in elements that correspond to zeros in operands.  */
+  emit_move_insn (vzero, CONST0_RTX (<MODE>mode));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz1_result, operands[1], vzero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz2_result, operands[2], vzero));
+  emit_insn (gen_and<mode>3 (and_result, cmpz1_result, cmpz2_result));
+
+  /* Vector with ones in elments that do not match.  */
+  emit_insn (gen_vcmpnez<VSX_EXTRACT_WIDTH> (cmpz_result, operands[1],
+                                             operands[2]));
+
+  /* Create vector with ones in elements where there was a zero in one of
+     the source elements or the elements that match.  */
+  emit_insn (gen_nand<mode>3 (result, and_result, cmpz_result));
+  sh = GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) / 2;
+
+  if (<MODE>mode == V16QImode)
+    emit_insn (gen_vctzlsbb_<mode> (operands[0], result));
+  else
+    {
+      rtx tmp = gen_reg_rtx (SImode);
+      emit_insn (gen_vctzlsbb_<mode> (tmp, result));
+      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (sh)));
+    }
+  DONE;
+})
+
+;; Return first position of mismatch between vectors
+(define_expand "first_mismatch_index_<mode>"
+  [(match_operand:SI 0 "register_operand")
+   (unspec: SI [(match_operand:VSX_EXTRACT_I 1 "register_operand")
+   (match_operand:VSX_EXTRACT_I 2 "register_operand")]
+  UNSPEC_VSX_FIRST_MISMATCH_INDEX)]
+  "TARGET_P9_VECTOR"
+{
+  int sh;
+  rtx cmp_result = gen_reg_rtx (<MODE>mode);
+
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmp_result, operands[1],
+					    operands[2]));
+  sh = GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) / 2;
+
+  if (<MODE>mode == V16QImode)
+    emit_insn (gen_vctzlsbb_<mode> (operands[0], cmp_result));
+  else
+    {
+      rtx tmp = gen_reg_rtx (SImode);
+      emit_insn (gen_vctzlsbb_<mode> (tmp, cmp_result));
+      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (sh)));
+    }
+  DONE;
+})
+
+;; Return first position of mismatch between vectors or end of string (EOS)
+(define_expand "first_mismatch_or_eos_index_<mode>"
+  [(match_operand:SI 0 "register_operand")
+   (unspec: SI [(match_operand:VSX_EXTRACT_I 1 "register_operand")
+   (match_operand:VSX_EXTRACT_I 2 "register_operand")]
+  UNSPEC_VSX_FIRST_MISMATCH_EOS_INDEX)]
+  "TARGET_P9_VECTOR"
+{
+  int sh;
+  rtx cmpz1_result = gen_reg_rtx (<MODE>mode);
+  rtx cmpz2_result = gen_reg_rtx (<MODE>mode);
+  rtx cmpz_result = gen_reg_rtx (<MODE>mode);
+  rtx not_cmpz_result = gen_reg_rtx (<MODE>mode);
+  rtx and_result = gen_reg_rtx (<MODE>mode);
+  rtx result = gen_reg_rtx (<MODE>mode);
+  rtx vzero = gen_reg_rtx (<MODE>mode);
+
+  /* Vector with zeros in elements that correspond to zeros in operands.  */
+  emit_move_insn (vzero, CONST0_RTX (<MODE>mode));
+
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz1_result, operands[1], vzero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz2_result, operands[2], vzero));
+  emit_insn (gen_and<mode>3 (and_result, cmpz1_result, cmpz2_result));
+
+  /* Vector with ones in elments that match.  */
+  emit_insn (gen_vcmpnez<VSX_EXTRACT_WIDTH> (cmpz_result, operands[1],
+                                             operands[2]));
+  emit_insn (gen_one_cmpl<mode>2 (not_cmpz_result, cmpz_result));
+
+  /* Create vector with ones in elements where there was a zero in one of
+     the source elements or the elements did not match.  */
+  emit_insn (gen_nand<mode>3 (result, and_result, not_cmpz_result));
+  sh = GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) / 2;
+
+  if (<MODE>mode == V16QImode)
+    emit_insn (gen_vctzlsbb_<mode> (operands[0], result));
+  else
+    {
+      rtx tmp = gen_reg_rtx (SImode);
+      emit_insn (gen_vctzlsbb_<mode> (tmp, result));
+      emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (sh)));
+    }
+  DONE;
+})
+
 ;; Load VSX Vector with Length
 (define_expand "lxvl"
   [(set (match_dup 3)
@@ -4524,10 +4671,10 @@ 
   [(set_attr "type" "vecsimple")])
 
 ;; Vector Count Trailing Zero Least-Significant Bits Byte
-(define_insn "vctzlsbb"
+(define_insn "vctzlsbb_<mode>"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(unspec:SI
-	 [(match_operand:V16QI 1 "altivec_register_operand" "v")]
+	 [(match_operand:VSX_EXTRACT_I 1 "altivec_register_operand" "v")]
 	 UNSPEC_VCTZLSBB))]
   "TARGET_P9_VECTOR"
   "vctzlsbb %0,%1"
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 63b58c068..79f609fd0 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -15875,6 +15875,51 @@  signed int vec_cntlz_lsbb (vector unsigned char);
 signed int vec_cnttz_lsbb (vector signed char);
 signed int vec_cnttz_lsbb (vector unsigned char);
 
+unsigned int vec_first_match_index (vector signed char, vector signed char);
+unsigned int vec_first_match_index (vector unsigned char,
+                                    vector unsigned char);
+unsigned int vec_first_match_index (vector signed int, vector signed int);
+unsigned int vec_first_match_index (vector unsigned int, vector unsigned int);
+unsigned int vec_first_match_index (vector signed short, vector signed short);
+unsigned int vec_first_match_index (vector unsigned short,
+                                    vector unsigned short);
+unsigned int vec_first_match_or_eos_index (vector signed char,
+                                           vector signed char);
+unsigned int vec_first_match_or_eos_index (vector unsigned char,
+                                           vector unsigned char);
+unsigned int vec_first_match_or_eos_index (vector signed int,
+                                           vector signed int);
+unsigned int vec_first_match_or_eos_index (vector unsigned int,
+                                           vector unsigned int);
+unsigned int vec_first_match_or_eos_index (vector signed short,
+                                           vector signed short);
+unsigned int vec_first_match_or_eos_index (vector unsigned short,
+                                           vector unsigned short);
+unsigned int vec_first_mismatch_index (vector signed char,
+                                       vector signed char);
+unsigned int vec_first_mismatch_index (vector unsigned char,
+                                       vector unsigned char);
+unsigned int vec_first_mismatch_index (vector signed int,
+                                       vector signed int);
+unsigned int vec_first_mismatch_index (vector unsigned int,
+                                       vector unsigned int);
+unsigned int vec_first_mismatch_index (vector signed short,
+                                       vector signed short);
+unsigned int vec_first_mismatch_index (vector unsigned short,
+                                       vector unsigned short);
+unsigned int vec_first_mismatch_or_eos_index (vector signed char,
+                                              vector signed char);
+unsigned int vec_first_mismatch_or_eos_index (vector unsigned char,
+                                              vector unsigned char);
+unsigned int vec_first_mismatch_or_eos_index (vector signed int,
+                                              vector signed int);
+unsigned int vec_first_mismatch_or_eos_index (vector unsigned int,
+                                              vector unsigned int);
+unsigned int vec_first_mismatch_or_eos_index (vector signed short,
+                                              vector signed short);
+unsigned int vec_first_mismatch_or_eos_index (vector unsigned short,
+                                              vector unsigned short);
+
 vector unsigned short vec_pack_to_short_fp32 (vector float, vector float);
 
 vector signed char vec_xl_be (signed long long, signed char *);
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-6-p9-runnable.c b/gcc/testsuite/gcc.target/powerpc/builtins-6-p9-runnable.c
new file mode 100644
index 000000000..9319a3727
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-6-p9-runnable.c
@@ -0,0 +1,1046 @@ 
+/* { dg-do run { target { powerpc*-*-* &&  p9vector_hw } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2" } */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <altivec.h> // vector
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+int main() {
+   vector signed char char_src1, char_src2;
+   vector unsigned char uchar_src1, uchar_src2;
+   vector signed short int short_src1, short_src2;
+   vector unsigned short int ushort_src1, ushort_src2;
+   vector signed int int_src1, int_src2;
+   vector unsigned int uint_src1, uint_src2;
+   unsigned int result, expected_result;
+
+   /* Tests for: vec_first_match_index() */
+   /* char */
+   char_src1 = (vector signed char) {-1, 2, 3, 4, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {-1, 2, 3, 20, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 0;
+
+   result = vec_first_match_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   char_src1 = (vector signed char) {1, 2, 3, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {-1, -2, -3, -4, -5, -6, -7, -8,
+				     -9, -10, -11, -12, -13, -14, -15, -16};
+   expected_result = 16;
+
+   result = vec_first_match_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {0, 2, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {1, 0, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 2;
+
+   result = vec_first_match_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16, 17};
+   uchar_src2 = (vector unsigned char) {3, 4, 5, 6, 7, 8, 9, 10,
+					11, 12, 13, 14, 15, 16, 17, 18};
+   expected_result = 16;
+
+   result = vec_first_match_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* short int */
+   short_src1 = (vector short int) {10, -20, -30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {-10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 3;
+
+   result = vec_first_match_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+
+   short_src1 = (vector short int) {10, 20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {0, 0, 0, 0, 0, 0, 0, 0};
+
+   expected_result = 8;
+
+   result = vec_first_match_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {0, 0, 0, 0, 0, 60, 70, 0};
+   ushort_src2 = (vector short unsigned int) {10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 5;
+
+   result = vec_first_match_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {-20, 30, -40, 50,
+					      60, -70, 80, -90};
+   ushort_src2 = (vector short unsigned int) {20, -30, 40, -50,
+					      -60, 70, -80, 90};
+
+   expected_result = 8;
+
+   result = vec_first_match_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* int */
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {10, 20, 30, 4};
+
+   expected_result = 3;
+
+   result = vec_first_match_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {4, 3, 2, 1};
+
+   expected_result = 4;
+
+   result = vec_first_match_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {11, 2, 33, 4};
+
+   expected_result = 1;
+
+   result = vec_first_match_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {2, 3, 4, 5};
+
+   expected_result = 4;
+
+   result = vec_first_match_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* Tests for: vec_first_mismatch_index() */
+   /* char */
+   char_src1 = (vector signed char) {-1, 2, 3, 4, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {-1, 2, 3, 20, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 3;
+
+   result = vec_first_mismatch_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   char_src1 = (vector signed char) {1, 2, 3, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {1, 2, 3, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 16;
+
+   result = vec_first_mismatch_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {1, 2, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {1, 0, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 1;
+
+   result = vec_first_mismatch_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					0, 11, 12, 13, 14, 15, 16};
+   expected_result = 8;
+
+   result = vec_first_mismatch_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16};
+   expected_result = 16;
+
+   result = vec_first_mismatch_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* short int */
+   short_src1 = (vector short int) {-10, -20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {-10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {10, 20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 8;
+
+   result = vec_first_mismatch_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {10, 20, 30, 40, 50, 60, 70, 0};
+   ushort_src2 = (vector short unsigned int) {10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 7;
+
+   result = vec_first_mismatch_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {20, 30, 40, 50, 60, 70, 80, 90};
+   ushort_src2 = (vector short unsigned int) {20, 30, 40, 50, 60, 70, 80, 90};
+
+   expected_result = 8;
+
+   result = vec_first_mismatch_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* int */
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {1, 20, 3, 4};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {1, 2, 3, 4};
+
+   expected_result = 4;
+
+   result = vec_first_mismatch_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {1, 0, 3, 4};
+   int_src2 = (vector int) {1, 2, 3, 4};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {11, 2, 33, 4};
+
+   expected_result = 0;
+
+   result = vec_first_mismatch_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {1, 2, 3, 4};
+
+   expected_result = 4;
+
+   result = vec_first_mismatch_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* Tests for: vec_first_match_or_eos_index() */
+   /* char */
+   char_src1 = (vector signed char) {-1, 2, 3, 4, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {-1, 2, 3, 20, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 0;
+
+   result = vec_first_match_or_eos_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first match result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   char_src1 = (vector signed char) {-1, 2, 3, 0, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {2, 3, 20, 0, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 3;
+
+   result = vec_first_match_or_eos_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+  char_src1 = (vector signed char) {1, 2, 3, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {-1, -2, -3, -4, -5, -6, -7, -8,
+				     -9, -10, -11, -12, -13, -14, -15, -16};
+   expected_result = 16;
+
+   result = vec_first_match_or_eos_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+#endif
+
+   uchar_src1 = (vector unsigned char) {1, 2, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {-1, 0, -3, -4, -5, -6, -7, -8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 1;
+
+   result = vec_first_match_or_eos_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16, 17};
+   uchar_src2 = (vector unsigned char) {3, 4, 5, 6, 7, 8, 9, 10,
+					11, 12, 13, 14, 15, 16, 17, 18};
+   expected_result = 16;
+
+   result = vec_first_match_or_eos_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first match or EOS  result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* short int */
+   short_src1 = (vector short int) {10, -20, -30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {-10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 3;
+
+   result = vec_first_match_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {1, 20, 30, 40, 50, 60, 70, 80};
+
+   short_src2 = (vector short int) {10, 0, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 1;
+
+   result = vec_first_match_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {-10, -20, -30, -40, -50, -60, -70, -80};
+
+   short_src2 = (vector short int) {10, 20, 30, 40, 50, 0, 70, 80};
+
+   expected_result = 5;
+
+   result = vec_first_match_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {10, 20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {0, 0, 0, 0, 0, 0, 0, 0};
+
+   expected_result = 0;
+
+   result = vec_first_match_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {1, 2, 0, 0, 60, 70, 0};
+   ushort_src2 = (vector short unsigned int) {10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 2;
+
+   result = vec_first_match_or_eos_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {-20, 30, -40, 50,
+					      60, -70, 80, -90};
+   ushort_src2 = (vector short unsigned int) {20, -30, 40, -50,
+					      -60, 70, -80, 90};
+
+   expected_result = 8;
+
+   result = vec_first_match_or_eos_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+   ushort_src1 = (vector short unsigned int) {-20, 30, -40, 50,
+					      60, -70, 80, 0};
+
+   ushort_src2 = (vector short unsigned int) {20, -30, 40, -50,
+					      -60, 70, -80, 90};
+
+   expected_result = 7;
+
+   result = vec_first_match_or_eos_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* int */
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {10, 20, 30, 4};
+
+   expected_result = 3;
+
+   result = vec_first_match_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {0, 2, 3, 4};
+   int_src2 = (vector int) {4, 3, 2, 1};
+
+   expected_result = 0;
+
+   result = vec_first_match_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {4, 3, 2, 1};
+
+   expected_result = 4;
+
+   result = vec_first_match_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {11, 2, 33, 4};
+
+   expected_result = 1;
+
+   result = vec_first_match_or_eos_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 0, 4};
+   uint_src2 = (vector unsigned int) {2, 3, 4, 5};
+
+   expected_result = 2;
+
+   result = vec_first_match_or_eos_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {2, 3, 4, 5};
+
+   expected_result = 4;
+
+   result = vec_first_match_or_eos_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first match or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* Tests for: vec_first_mismatch_or_eos_index() */
+   /* char */
+   char_src1 = (vector signed char) {-1, 2, 3, 4, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {-1, 2, 3, 20, -5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 3;
+
+   result = vec_first_mismatch_or_eos_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   char_src1 = (vector signed char) {1, 2, 0, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {1, 2, 0, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 2;
+
+   result = vec_first_mismatch_or_eos_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   char_src1 = (vector signed char) {1, 2, 3, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   char_src2 = (vector signed char) {1, 2, 3, 4, 5, 6, 7, 8,
+				     9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 16;
+
+   result = vec_first_mismatch_or_eos_index (char_src1, char_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: char first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {1, 2, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {1, 0, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15, 16};
+   expected_result = 1;
+
+   result = vec_first_mismatch_or_eos_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					0, 11, 12, 13, 14, 15, 16};
+   uchar_src2 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					0, 11, 12, 13, 14, 15, 16};
+   expected_result = 8;
+
+   result = vec_first_mismatch_or_eos_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16, 17};
+   uchar_src2 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 0, 16, 17};
+   expected_result = 13;
+
+   result = vec_first_mismatch_or_eos_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uchar_src1 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16, 17};
+   uchar_src2 = (vector unsigned char) {2, 3, 4, 5, 6, 7, 8, 9,
+					10, 11, 12, 13, 14, 15, 16, 17};
+   expected_result = 16;
+
+   result = vec_first_mismatch_or_eos_index (uchar_src1, uchar_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uchar first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* short int */
+   short_src1 = (vector short int) {-10, -20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {-10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {0, 20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {0, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 0;
+
+   result = vec_first_mismatch_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {10, 20, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 8;
+
+   result = vec_first_mismatch_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   short_src1 = (vector short int) {10, 0, 30, 40, 50, 60, 70, 80};
+   short_src2 = (vector short int) {10, 0, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_or_eos_index (short_src1, short_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: short int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {10, 20, 30, 40, 50, 60, 70, 0};
+   ushort_src2 = (vector short unsigned int) {10, 20, 30, 40, 50, 60, 70, 80};
+
+   expected_result = 7;
+
+   result = vec_first_mismatch_or_eos_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {20, 0, 40, 50, 60, 70, 80, 90};
+   ushort_src2 = (vector short unsigned int) {20, 0, 40, 50, 60, 70, 80, 90};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_or_eos_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   ushort_src1 = (vector short unsigned int) {20, 30, 40, 50, 60, 70, 80, 90};
+   ushort_src2 = (vector short unsigned int) {20, 30, 40, 50, 60, 70, 80, 90};
+
+   expected_result = 8;
+
+   result = vec_first_mismatch_or_eos_index (ushort_src1, ushort_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: ushort int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   /* int */
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {1, 20, 3, 4};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch or EOS result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {1, 2, 3, 4};
+   int_src2 = (vector int) {1, 2, 3, 4};
+
+   expected_result = 4;
+
+   result = vec_first_mismatch_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {1, 2, 0, 4};
+   int_src2 = (vector int) {1, 2, 0, 4};
+
+   expected_result = 2;
+
+   result = vec_first_mismatch_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   int_src1 = (vector int) {1, 0, 3, 4};
+   int_src2 = (vector int) {1, 2, 3, 4};
+
+   expected_result = 1;
+
+   result = vec_first_mismatch_or_eos_index (int_src1, int_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: int first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {11, 2, 33, 4};
+
+   expected_result = 0;
+
+   result = vec_first_mismatch_or_eos_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 0};
+   uint_src2 = (vector unsigned int) {1, 2, 3, 0};
+
+   expected_result = 3;
+
+   result = vec_first_mismatch_or_eos_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+   uint_src1 = (vector unsigned int) {1, 2, 3, 4};
+   uint_src2 = (vector unsigned int) {1, 2, 3, 4};
+
+   expected_result = 4;
+
+   result = vec_first_mismatch_or_eos_index (uint_src1, uint_src2);
+
+   if (result != expected_result)
+#ifdef DEBUG
+      printf("Error: uint first mismatch result (%d) does not match expected result (%d)\n",
+	     result, expected_result);
+#else
+      abort();
+#endif
+
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c
index 969107a24..cd4bb9dc9 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c
@@ -10,5 +10,5 @@  count_trailing_zero_byte_bits (vector unsigned char *arg1_p)
 {
   vector unsigned char arg_1 = *arg1_p;
 
-  return __builtin_vec_vctzlsbb (arg_1);	/* { dg-error "builtin function '__builtin_altivec_vctzlsbb' requires the '-mcpu=power9' option" } */
+  return __builtin_vec_vctzlsbb (arg_1);	/* { dg-error "builtin function '__builtin_altivec_vctzlsbb_v16qi' requires the '-mcpu=power9' option" } */
 }