This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

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" } */
 }
-- 
2.11.0




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]