public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, rs6000] Add Power 9 support for vec_first builtins
@ 2017-10-20  2:03 Carl Love
  2017-10-23 23:15 ` Segher Boessenkool
  0 siblings, 1 reply; 5+ messages in thread
From: Carl Love @ 2017-10-20  2:03 UTC (permalink / raw)
  To: gcc-patches, David Edelsohn, Segher Boessenkool; +Cc: Bill Schmidt, cel

GCC maintainers:

The following patch adds 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.  The patch has
been 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 Love
------------------------------------------------------------

gcc/ChangeLog:

2017-10-19  Carl Love  <cel@us.ibm.com>

	* config/rs6000/rs6000-c.c: Add support for builtins:
	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);
	* 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 extern
	declaration.
	* config/rs6000/rs6000.c (bytes_in_mode): Add function to return mode
	size in bytes.
	* 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 to implement
	the builtins.
	(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-10-19  Carl Love  <cel@us.ibm.com>

	* gcc.target/powerpc/builtins-6-p9-runnable.c: Add runnable test for
	the new builtins.
---
 gcc/config/rs6000/altivec.h                        |    4 +
 gcc/config/rs6000/rs6000-builtin.def               |   40 +-
 gcc/config/rs6000/rs6000-c.c                       |   68 +-
 gcc/config/rs6000/rs6000-protos.h                  |    1 +
 gcc/config/rs6000/rs6000.c                         |   28 +
 gcc/config/rs6000/vsx.md                           |  150 ++-
 gcc/doc/extend.texi                                |   45 +
 .../gcc.target/powerpc/builtins-6-p9-runnable.c    | 1049 ++++++++++++++++++++
 8 files changed, 1380 insertions(+), 5 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 94a4db24a..0fa43f897 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -419,6 +419,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 ac9ddae3e..1abbfc2e1 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2040,6 +2040,37 @@ 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")
@@ -2118,6 +2149,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")
@@ -2185,7 +2221,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 2a916b438..d78a3da9a 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -2400,6 +2400,66 @@ 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,
@@ -5178,10 +5238,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/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index c6be5b1ef..e3ca88400 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -167,6 +167,7 @@ extern rtx rs6000_address_for_altivec (rtx);
 extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool);
 extern int rs6000_loop_align (rtx);
 extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
+extern int bytes_in_mode (machine_mode);
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b903f47ee..c9fa2c73d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -14286,6 +14286,34 @@ swap_selector_for_mode (machine_mode mode)
   return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)));
 }
 
+/* Return bytes in type */
+int
+bytes_in_mode (machine_mode mode)
+{
+   int bytes;
+   switch (mode)
+    {
+    case E_V2DFmode:
+    case E_V2DImode:
+      bytes = 8;
+      break;
+    case E_V4SFmode:
+    case E_V4SImode:
+      bytes = 4;
+      break;
+    case E_V8HImode:
+      bytes = 2;
+      break;
+    case E_V16QImode:
+      bytes = 1;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+   return bytes;
+}
+
 /* Generate code for an "lvxl", or "lve*x" built-in for a little endian target
    with -maltivec=be specified.  Issue the load followed by an element-
    reversing permute.  */
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 35be5dead..d5696c60e 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -408,6 +408,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
@@ -4335,6 +4339,148 @@
   "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 = bytes_in_mode(<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 zero = gen_reg_rtx (<MODE>mode);
+
+  // Vector with zeros in elements that correspond to zeros in operands
+  emit_insn (gen_xor<mode>3 (zero, zero, zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz1_result, operands[1], zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz2_result, operands[2], zero));
+  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 = bytes_in_mode(<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 = bytes_in_mode(<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 zero = gen_reg_rtx (<MODE>mode);
+
+  // Vector with zeros in elements that correspond to zeros in operands
+  emit_insn (gen_xor<mode>3 (zero, zero, zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz1_result, operands[1], zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz2_result, operands[2], zero));
+  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 = bytes_in_mode(<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)
@@ -4514,10 +4660,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 4156291b6..f32c73a56 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -15658,6 +15658,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..8ee3e79f5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-6-p9-runnable.c
@@ -0,0 +1,1049 @@
+/* { 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;
+
+#if 1
+   /* 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();
+#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 = 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
+
+#if 1
+   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
+#endif
+}
-- 
2.11.0



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

* Re: [PATCH, rs6000] Add Power 9 support for vec_first builtins
  2017-10-20  2:03 [PATCH, rs6000] Add Power 9 support for vec_first builtins Carl Love
@ 2017-10-23 23:15 ` Segher Boessenkool
  2017-10-31 15:50   ` Carl Love
  0 siblings, 1 reply; 5+ messages in thread
From: Segher Boessenkool @ 2017-10-23 23:15 UTC (permalink / raw)
  To: Carl Love; +Cc: gcc-patches, David Edelsohn, Bill Schmidt

Hi Carl,

On Thu, Oct 19, 2017 at 04:31:13PM -0700, Carl Love wrote:
> 	* config/rs6000/rs6000-builtin.def (VFIRSTMATCHINDEX,
> 	VFIRSTMATCHOREOSINDEX, VFIRSTMISMATCHINDEX, VFIRSTMISMATCHOREOSINDEX):
> 	Add BU_P9V_AV_2 expansions for the builtins.

Those names are a bit unwieldy ;-)

> +BU_P9V_OVERLOAD_2 (VFIRSTMISMATCHOREOSINDEX,	'first_mismatch_or_eos_index")

How did this compile?


Segher

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

* Re: [PATCH, rs6000] Add Power 9 support for vec_first builtins
  2017-10-23 23:15 ` Segher Boessenkool
@ 2017-10-31 15:50   ` Carl Love
  2017-10-31 16:04     ` Jakub Jelinek
  2017-11-01 21:31     ` Segher Boessenkool
  0 siblings, 2 replies; 5+ messages in thread
From: Carl Love @ 2017-10-31 15:50 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, David Edelsohn, Bill Schmidt

GCC maintainers:

The patch has been updated to fix the typo and retested.  Unfortunately
the names of the builtins are rather long and unwieldy to begin with.  


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

                       Carl Love

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

gcc/ChangeLog:

2017-10-31  Carl Love  <cel@us.ibm.com>

	* config/rs6000/rs6000-c.c: Add support for builtins:
	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);
	* 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 extern
	declaration.
	* config/rs6000/rs6000.c (bytes_in_mode): Add function to return mode
	size in bytes.
	* 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 to implement
	the builtins.
	(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-10-31  Carl Love  <cel@us.ibm.com>

	* gcc.target/powerpc/builtins-6-p9-runnable.c: Add runnable test for
	the new builtins.
---
 gcc/config/rs6000/altivec.h                        |    4 +
 gcc/config/rs6000/rs6000-builtin.def               |   40 +-
 gcc/config/rs6000/rs6000-c.c                       |   68 +-
 gcc/config/rs6000/rs6000-protos.h                  |    1 +
 gcc/config/rs6000/rs6000.c                         |   28 +
 gcc/config/rs6000/vsx.md                           |  150 ++-
 gcc/doc/extend.texi                                |   45 +
 .../gcc.target/powerpc/builtins-6-p9-runnable.c    | 1046 ++++++++++++++++++++
 8 files changed, 1377 insertions(+), 5 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 94a4db24a..0fa43f897 100644
--- a/gcc/config/rs6000/altivec.h
+++ b/gcc/config/rs6000/altivec.h
@@ -419,6 +419,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 ac9ddae3e..6b035093c 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -2040,6 +2040,37 @@ 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")
@@ -2118,6 +2149,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")
@@ -2185,7 +2221,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 2a916b438..d78a3da9a 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -2400,6 +2400,66 @@ 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,
@@ -5178,10 +5238,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/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index c6be5b1ef..e3ca88400 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -167,6 +167,7 @@ extern rtx rs6000_address_for_altivec (rtx);
 extern rtx rs6000_allocate_stack_temp (machine_mode, bool, bool);
 extern int rs6000_loop_align (rtx);
 extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
+extern int bytes_in_mode (machine_mode);
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b903f47ee..c9fa2c73d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -14286,6 +14286,34 @@ swap_selector_for_mode (machine_mode mode)
   return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)));
 }
 
+/* Return bytes in type */
+int
+bytes_in_mode (machine_mode mode)
+{
+   int bytes;
+   switch (mode)
+    {
+    case E_V2DFmode:
+    case E_V2DImode:
+      bytes = 8;
+      break;
+    case E_V4SFmode:
+    case E_V4SImode:
+      bytes = 4;
+      break;
+    case E_V8HImode:
+      bytes = 2;
+      break;
+    case E_V16QImode:
+      bytes = 1;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+   return bytes;
+}
+
 /* Generate code for an "lvxl", or "lve*x" built-in for a little endian target
    with -maltivec=be specified.  Issue the load followed by an element-
    reversing permute.  */
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 35be5dead..f90554354 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -408,6 +408,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
@@ -4335,6 +4339,148 @@
   "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 = bytes_in_mode(<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 zero = gen_reg_rtx (<MODE>mode);
+
+  /* Vector with zeros in elements that correspond to zeros in operands.  */
+  emit_insn (gen_xor<mode>3 (zero, zero, zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz1_result, operands[1], zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz2_result, operands[2], zero));
+  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 = bytes_in_mode(<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 = bytes_in_mode(<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 zero = gen_reg_rtx (<MODE>mode);
+
+  /* Vector with zeros in elements that correspond to zeros in operands.  */
+  emit_insn (gen_xor<mode>3 (zero, zero, zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz1_result, operands[1], zero));
+  emit_insn (gen_vcmpne<VSX_EXTRACT_WIDTH> (cmpz2_result, operands[2], zero));
+  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 = bytes_in_mode(<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)
@@ -4514,10 +4660,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 4156291b6..f32c73a56 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -15658,6 +15658,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
+
+}
-- 
2.11.0




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

* Re: [PATCH, rs6000] Add Power 9 support for vec_first builtins
  2017-10-31 15:50   ` Carl Love
@ 2017-10-31 16:04     ` Jakub Jelinek
  2017-11-01 21:31     ` Segher Boessenkool
  1 sibling, 0 replies; 5+ messages in thread
From: Jakub Jelinek @ 2017-10-31 16:04 UTC (permalink / raw)
  To: Carl Love; +Cc: Segher Boessenkool, gcc-patches, David Edelsohn, Bill Schmidt

On Tue, Oct 31, 2017 at 08:46:09AM -0700, Carl Love wrote:
> 2017-10-31  Carl Love  <cel@us.ibm.com>
> 
> 	* config/rs6000/rs6000-c.c: Add support for builtins:
> 	unsigned int vec_first_match_index (vector signed char,
> 		     			    vector signed char);

...  The ChangeLog IMHO is not.  It should be something like:
	* config/rs6000/rs6000-c.c (altivec_overloaded_builtins): Add support
	for vec_first_{,mis}match_{,or_eos_}index builtins with
	vector {,un}signed {char,short,int} arguments.

Note (altivec_overloaded_builtins) to say what you've changed and
then just a sentence (in which IMHO wildcards are fine, but function
arguments in a way you wrote are not, because it is confusing with
what ()s mean in ChangeLog entry.

> 	* 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 extern
> 	declaration.

New declaration. ?

> 	* config/rs6000/rs6000.c (bytes_in_mode): Add function to return mode
> 	size in bytes.

New function. ? You don't need to explain what the function is for in
ChangeLog.

> 	* config/rs6000/vsx.md: (first_match_index_<mode>,

No : between filename and (what changed), please.

> 	first_match_or_eos_index_<mode>, first_mismatch_index_<mode>,
> 	first_mismatch_or_eos_index_<mode>):  Add define expand to implement
> 	the builtins.
> 	(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-10-31  Carl Love  <cel@us.ibm.com>
> 
> 	* gcc.target/powerpc/builtins-6-p9-runnable.c: Add runnable test for
> 	the new builtins.

New test.
Again, don't explain what the test is for.

For the rest I'll defer to PowerPC maintainers.

	Jakub

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

* Re: [PATCH, rs6000] Add Power 9 support for vec_first builtins
  2017-10-31 15:50   ` Carl Love
  2017-10-31 16:04     ` Jakub Jelinek
@ 2017-11-01 21:31     ` Segher Boessenkool
  1 sibling, 0 replies; 5+ messages in thread
From: Segher Boessenkool @ 2017-11-01 21:31 UTC (permalink / raw)
  To: Carl Love; +Cc: gcc-patches, David Edelsohn, Bill Schmidt

Hi Carl,

On Tue, Oct 31, 2017 at 08:46:09AM -0700, Carl Love wrote:
> gcc/ChangeLog:

See Jakub's comments (thanks!)

> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -14286,6 +14286,34 @@ swap_selector_for_mode (machine_mode mode)
>    return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode, gen_rtvec_v (16, perm)));
>  }
>  
> +/* Return bytes in type */

Dot space space.

> +int
> +bytes_in_mode (machine_mode mode)
> +{

But what do you need this for?  This is GET_MODE_SIZE (GET_MODE_INNER (mode))
(or similar).

> +;; 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")

No space in :SI please.

> +   (match_operand:VSX_EXTRACT_I 2 "register_operand")]

This should indent to the same level as the previous match_operand.

> +  UNSPEC_VSX_FIRST_MATCH_INDEX)]

(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)]

> +  emit_insn (gen_vcmpnez<VSX_EXTRACT_WIDTH> (cmp_result, operands[1],
> +                                            operands[2]));

Indent with tabs for each each spaces; the "o" should align with the "c".

> +  sh = bytes_in_mode(<MODE>mode)/2;

Spaces around binary operators please, and before the opening paren of
parameter lists.

> +  /* Vector with zeros in elements that correspond to zeros in operands.  */
> +  emit_insn (gen_xor<mode>3 (zero, zero, zero));

I think we have a helper for this?  One that avoids xor if it can.


Segher

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

end of thread, other threads:[~2017-11-01 21:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-20  2:03 [PATCH, rs6000] Add Power 9 support for vec_first builtins Carl Love
2017-10-23 23:15 ` Segher Boessenkool
2017-10-31 15:50   ` Carl Love
2017-10-31 16:04     ` Jakub Jelinek
2017-11-01 21:31     ` Segher Boessenkool

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).