public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes
@ 2022-01-28 17:50 Bill Schmidt
  2022-01-28 17:50 ` [PATCH 1/8] rs6000: More factoring of overload processing Bill Schmidt
                   ` (7 more replies)
  0 siblings, 8 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

Hi!

This is a resubmission of some patches and a new submission of others.
Patches 1, 3, and 4 finish up the pending clean-up work for the new built-in
infrastructure support.  Patches 2 and 5-8 fix a variety of bugs not specific
to the new infrastructure.  I'm submitting these as a group primarily because
5-8 are dependent on the previous patches, particularly patch 4, which
consolidates much of the built-in code in a new file.

Thanks for your consideration!

Bill


Bill Schmidt (8):
  rs6000: More factoring of overload processing
  rs6000: Don't #ifdef "short" built-in names
  rs6000: Convert <x> built-in constraints to <x,y> form
  rs6000: Consolidate target built-ins code
  rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082]
  rs6000: Remove -m[no-]fold-gimple flag [PR103686]
  rs6000: vec_neg built-ins wrongly require POWER8
  rs6000: Fix some missing built-in attributes [PR104004]

 gcc/config.gcc                                |    2 +-
 gcc/config/rs6000/rs6000-builtin.cc           | 3721 +++++++++++++++++
 gcc/config/rs6000/rs6000-builtins.def         |  578 +--
 gcc/config/rs6000/rs6000-c.cc                 |  304 +-
 gcc/config/rs6000/rs6000-call.cc              | 3524 ----------------
 gcc/config/rs6000/rs6000-overload.def         |  344 +-
 gcc/config/rs6000/rs6000.cc                   |  167 +-
 gcc/config/rs6000/rs6000.h                    |    1 -
 gcc/config/rs6000/rs6000.opt                  |    4 -
 gcc/config/rs6000/t-rs6000                    |    4 +
 .../powerpc/bfp/scalar-test-data-class-10.c   |    2 +-
 .../powerpc/bfp/scalar-test-data-class-2.c    |    2 +-
 .../powerpc/bfp/scalar-test-data-class-3.c    |    2 +-
 .../powerpc/bfp/scalar-test-data-class-4.c    |    2 +-
 .../powerpc/bfp/scalar-test-data-class-5.c    |    2 +-
 .../powerpc/bfp/scalar-test-data-class-9.c    |    2 +-
 .../powerpc/bfp/vec-test-data-class-4.c       |    2 +-
 .../powerpc/bfp/vec-test-data-class-5.c       |    2 +-
 .../powerpc/bfp/vec-test-data-class-6.c       |    2 +-
 .../powerpc/bfp/vec-test-data-class-7.c       |    2 +-
 .../gcc.target/powerpc/builtins-1-be-folded.c |    2 +-
 .../gcc.target/powerpc/builtins-1-le-folded.c |    2 +-
 gcc/testsuite/gcc.target/powerpc/builtins-1.c | 1210 ++++--
 gcc/testsuite/gcc.target/powerpc/builtins-5.c |    3 +-
 .../gcc.target/powerpc/dfp/dtstsfi-12.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-14.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-17.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-19.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-2.c        |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-22.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-24.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-27.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-29.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-32.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-34.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-37.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-39.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-4.c        |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-42.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-44.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-47.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-49.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-52.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-54.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-57.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-59.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-62.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-64.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-67.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-69.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-7.c        |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-72.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-74.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-77.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-79.c       |    2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-9.c        |    2 +-
 .../gcc.target/powerpc/p8-vec-xl-xst.c        |    3 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-1.c  |    2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-2.c  |    2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-3.c  |    2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-4.c  |    2 +-
 gcc/testsuite/gcc.target/powerpc/pr82015.c    |    4 +-
 gcc/testsuite/gcc.target/powerpc/pr83926.c    |    3 +-
 .../powerpc/pr86731-nogimplefold-longlong.c   |   32 -
 .../gcc.target/powerpc/pr86731-nogimplefold.c |   63 -
 gcc/testsuite/gcc.target/powerpc/pr91903.c    |   60 +-
 .../gcc.target/powerpc/swaps-p8-17.c          |    3 +-
 .../powerpc/test_fpscr_rn_builtin_error.c     |    8 +-
 .../gcc.target/powerpc/vec-ternarylogic-10.c  |    6 +-
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c |    2 +-
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c |    2 +-
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c |   15 +
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c |   15 +
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c |    2 +-
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c |    2 +-
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c |   15 +
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c |   15 +
 77 files changed, 5426 insertions(+), 4782 deletions(-)
 create mode 100644 gcc/config/rs6000/rs6000-builtin.cc
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold-longlong.c
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c

-- 
2.27.0


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

* [PATCH 1/8] rs6000: More factoring of overload processing
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-01-28 19:11   ` Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names Bill Schmidt
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

This patch continues the refactoring started with r12-6014.  I had previously
noted that the resolve_vec* routines can be further simplified by processing
the argument list earlier, so that all routines can use the arrays of arguments
and types.  I found that this was useful for some of the routines, but not for
all of them.

For several of the special-cased overloads, we don't specify all of the
possible type combinations in rs6000-overload.def, because the types don't
matter for the expansion we do.  For these, we can't use generic error message
handling when the number of arguments is incorrect, because the result is
misleading error messages that indicate argument types are wrong.

So this patch goes halfway and improves the factoring on the remaining special
cases, but leaves vec_splats, vec_promote, vec_extract, vec_insert, and
vec_step alone.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-18  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-c.cc (resolve_vec_mul): Accept args and types
	parameters instead of arglist and nargs.  Simplify accordingly.  Remove
	unnecessary test for argument count mismatch.
	(resolve_vec_cmpne): Likewise.
	(resolve_vec_adde_sube): Likewise.
	(resolve_vec_addec_subec): Likewise.
	(altivec_resolve_overloaded_builtin): Move overload special handling
	after the gathering of arguments into args[] and types[] and the test
	for correct number of arguments.  Don't perform the test for correct
	number of arguments for certain special cases.  Call the other special
	cases with args and types instead of arglist and nargs.
---
 gcc/config/rs6000/rs6000-c.cc | 304 ++++++++++++++--------------------
 1 file changed, 127 insertions(+), 177 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index 145421ab8f2..35c1383f059 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -939,37 +939,25 @@ altivec_build_resolved_builtin (tree *args, int n, tree fntype, tree ret_type,
 enum resolution { unresolved, resolved, resolved_bad };
 
 /* Resolve an overloaded vec_mul call and return a tree expression for the
-   resolved call if successful.  NARGS is the number of arguments to the call.
-   ARGLIST contains the arguments.  RES must be set to indicate the status of
+   resolved call if successful.  ARGS contains the arguments to the call.
+   TYPES contains their types.  RES must be set to indicate the status of
    the resolution attempt.  LOC contains statement location information.  */
 
 static tree
-resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
-		 location_t loc)
+resolve_vec_mul (resolution *res, tree *args, tree *types, location_t loc)
 {
   /* vec_mul needs to be special cased because there are no instructions for it
      for the {un}signed char, {un}signed short, and {un}signed int types.  */
-  if (nargs != 2)
-    {
-      error ("builtin %qs only accepts 2 arguments", "vec_mul");
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
 
   /* Both arguments must be vectors and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
     case E_QImode:
     case E_HImode:
@@ -978,21 +966,21 @@ resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
     case E_TImode:
       /* For scalar types just use a multiply expression.  */
       *res = resolved;
-      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0,
-			      fold_convert (TREE_TYPE (arg0), arg1));
+      return fold_build2_loc (loc, MULT_EXPR, types[0], args[0],
+			      fold_convert (types[0], args[1]));
     case E_SFmode:
       {
 	/* For floats use the xvmulsp instruction directly.  */
 	*res = resolved;
 	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULSP];
-	return build_call_expr (call, 2, arg0, arg1);
+	return build_call_expr (call, 2, args[0], args[1]);
       }
     case E_DFmode:
       {
 	/* For doubles use the xvmuldp instruction directly.  */
 	*res = resolved;
 	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULDP];
-	return build_call_expr (call, 2, arg0, arg1);
+	return build_call_expr (call, 2, args[0], args[1]);
       }
     /* Other types are errors.  */
     default:
@@ -1002,37 +990,25 @@ resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
 }
 
 /* Resolve an overloaded vec_cmpne call and return a tree expression for the
-   resolved call if successful.  NARGS is the number of arguments to the call.
-   ARGLIST contains the arguments.  RES must be set to indicate the status of
+   resolved call if successful.  ARGS contains the arguments to the call.
+   TYPES contains their types.  RES must be set to indicate the status of
    the resolution attempt.  LOC contains statement location information.  */
 
 static tree
-resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
-		   location_t loc)
+resolve_vec_cmpne (resolution *res, tree *args, tree *types, location_t loc)
 {
   /* vec_cmpne needs to be special cased because there are no instructions
      for it (prior to power 9).  */
-  if (nargs != 2)
-    {
-      error ("builtin %qs only accepts 2 arguments", "vec_cmpne");
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
 
   /* Both arguments must be vectors and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (arg0_type));
+  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (types[0]));
 
   /* Power9 instructions provide the most efficient implementation of
      ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode
@@ -1060,8 +1036,8 @@ resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
 	    /* call = vec_cmpeq (va, vb)
 	       result = vec_nor (call, call).  */
 	    vec<tree, va_gc> *params = make_tree_vector ();
-	    vec_safe_push (params, arg0);
-	    vec_safe_push (params, arg1);
+	    vec_safe_push (params, args[0]);
+	    vec_safe_push (params, args[1]);
 	    tree decl = rs6000_builtin_decls[RS6000_OVLD_VEC_CMPEQ];
 	    tree call = altivec_resolve_overloaded_builtin (loc, decl, params);
 	    /* Use save_expr to ensure that operands used more than once
@@ -1088,46 +1064,30 @@ resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
   return error_mark_node;
 }
 
-/* Resolve an overloaded vec_adde or vec_sube call and return a tree
-   expression for the resolved call if successful.  NARGS is the number of
-   arguments to the call.  ARGLIST contains the arguments.  RES must be set
-   to indicate the status of the resolution attempt.  LOC contains statement
-   location information.  */
+/* Resolve an overloaded vec_adde or vec_sube call and return a tree expression
+   for the resolved call if successful.  ARGS contains the arguments to the
+   call.  TYPES contains their arguments.  RES must be set to indicate the
+   status of the resolution attempt.  LOC contains statement location
+   information.  */
 
 static tree
 resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
-		       vec<tree, va_gc> *arglist, unsigned nargs,
-		       location_t loc)
+		       tree *args, tree *types, location_t loc)
 {
   /* vec_adde needs to be special cased because there is no instruction
      for the {un}signed int version.  */
-  if (nargs != 3)
-    {
-      const char *name;
-      name = fcode == RS6000_OVLD_VEC_ADDE ? "vec_adde" : "vec_sube";
-      error ("builtin %qs only accepts 3 arguments", name);
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
-  tree arg2 = (*arglist)[2];
-  tree arg2_type = TREE_TYPE (arg2);
 
   /* All 3 arguments must be vectors of (signed or unsigned) (int or
      __int128) and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type)
-      || !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1])
+      || !lang_hooks.types_compatible_p (types[1], types[2]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
       /* For {un}signed ints,
 	 vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
@@ -1137,8 +1097,8 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
     case E_SImode:
       {
 	vec<tree, va_gc> *params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree add_sub_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDE)
@@ -1148,10 +1108,10 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
 
 	tree call = altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
 							params);
-	tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
-	tree ones_vector = build_vector_from_val (arg0_type, const1);
-	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
-					 arg2, ones_vector);
+	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
+	tree ones_vector = build_vector_from_val (types[0], const1);
+	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
+					 args[2], ones_vector);
 	params = make_tree_vector ();
 	vec_safe_push (params, call);
 	vec_safe_push (params, and_expr);
@@ -1175,45 +1135,29 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
 }
 
 /* Resolve an overloaded vec_addec or vec_subec call and return a tree
-   expression for the resolved call if successful.  NARGS is the number of
-   arguments to the call.  ARGLIST contains the arguments.  RES must be set
-   to indicate the status of the resolution attempt.  LOC contains statement
-   location information.  */
+   expression for the resolved call if successful.  ARGS contains the arguments
+   to the call.  TYPES contains their types.  RES must be set to indicate the
+   status of the resolution attempt.  LOC contains statement location
+   information.  */
 
 static tree
 resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
-			 vec<tree, va_gc> *arglist, unsigned nargs,
-			 location_t loc)
+			 tree *args, tree *types, location_t loc)
 {
   /* vec_addec and vec_subec needs to be special cased because there is
      no instruction for the (un)signed int version.  */
-  if (nargs != 3)
-    {
-      const char *name;
-      name = fcode == RS6000_OVLD_VEC_ADDEC ? "vec_addec" : "vec_subec";
-      error ("builtin %qs only accepts 3 arguments", name);
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
-  tree arg2 = (*arglist)[2];
-  tree arg2_type = TREE_TYPE (arg2);
 
   /* All 3 arguments must be vectors of (signed or unsigned) (int or
      __int128) and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type)
-      || !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1])
+      || !lang_hooks.types_compatible_p (types[1], types[2]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
       /* For {un}signed ints,
 	   vec_addec (va, vb, carryv) ==
@@ -1224,11 +1168,11 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
       {
 	/* Use save_expr to ensure that operands used more than once that may
 	   have side effects (like calls) are only evaluated once.  */
-	arg0 = save_expr (arg0);
-	arg1 = save_expr (arg1);
+	args[0] = save_expr (args[0]);
+	args[1] = save_expr (args[1]);
 	vec<tree, va_gc> *params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree as_c_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDEC)
@@ -1239,8 +1183,8 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
 	tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
 							 params);
 	params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree as_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDEC)
@@ -1250,10 +1194,10 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
 
 	tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin,
 							 params);
-	tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
-	tree ones_vector = build_vector_from_val (arg0_type, const1);
-	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
-					 arg2, ones_vector);
+	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
+	tree ones_vector = build_vector_from_val (types[0], const1);
+	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
+					 args[2], ones_vector);
 	params = make_tree_vector ();
 	vec_safe_push (params, call2);
 	vec_safe_push (params, and_expr);
@@ -1783,78 +1727,15 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 	     "%<vec_lvsr%> is deprecated for little endian; use "
 	     "assignment for unaligned loads and stores");
 
-  /* Some overloads require special handling.  */
-  /* FIXME: Could we simplify the helper functions if we gathered arguments
-     and types into arrays first?  */
-  tree returned_expr = NULL;
-  resolution res = unresolved;
-  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
-  unsigned int nargs = vec_safe_length (arglist);
-
-  switch (fcode)
-    {
-    case RS6000_OVLD_VEC_MUL:
-      returned_expr = resolve_vec_mul (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_CMPNE:
-      returned_expr = resolve_vec_cmpne (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_ADDE:
-    case RS6000_OVLD_VEC_SUBE:
-      returned_expr = resolve_vec_adde_sube (&res, fcode, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_ADDEC:
-    case RS6000_OVLD_VEC_SUBEC:
-      returned_expr = resolve_vec_addec_subec (&res, fcode, arglist, nargs,
-					       loc);
-      break;
-
-    case RS6000_OVLD_VEC_SPLATS:
-    case RS6000_OVLD_VEC_PROMOTE:
-      returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
-      break;
-
-    case RS6000_OVLD_VEC_EXTRACT:
-      returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_INSERT:
-      returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_STEP:
-      returned_expr = resolve_vec_step (&res, arglist, nargs);
-      break;
-
-    default:
-      ;
-    }
-
-  if (res == resolved)
-    return returned_expr;
-
-  /* "Regular" built-in functions and overloaded functions share a namespace
-     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
-     only has information for the overloaded functions, so we need an
-     adjusted index for that.  */
-  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
-
-  if (res == resolved_bad)
-    {
-      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
-      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
-      return error_mark_node;
-    }
-
   /* Gather the arguments and their types into arrays for easier handling.  */
   tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   tree types[MAX_OVLD_ARGS];
   tree args[MAX_OVLD_ARGS];
   unsigned int n;
 
+  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
+  unsigned int nargs = vec_safe_length (arglist);
+
   for (n = 0;
        !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs;
        fnargs = TREE_CHAIN (fnargs), n++)
@@ -1915,10 +1796,79 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
     }
 
   /* If the number of arguments did not match the prototype, return NULL
-     and the generic code will issue the appropriate error message.  */
-  if (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs)
+     and the generic code will issue the appropriate error message.  Skip
+     this test for functions where we don't fully describe all the possible
+     overload signatures in rs6000-overload.def (because they aren't relevant
+     to the expansion here).  If we don't, we get confusing error messages.  */
+  if (fcode != RS6000_OVLD_VEC_PROMOTE
+      && fcode != RS6000_OVLD_VEC_SPLATS
+      && fcode != RS6000_OVLD_VEC_EXTRACT
+      && fcode != RS6000_OVLD_VEC_INSERT
+      && fcode != RS6000_OVLD_VEC_STEP
+      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
     return NULL;
 
+  /* Some overloads require special handling.  */
+  tree returned_expr = NULL;
+  resolution res = unresolved;
+
+  switch (fcode)
+    {
+    case RS6000_OVLD_VEC_MUL:
+      returned_expr = resolve_vec_mul (&res, args, types, loc);
+      break;
+
+    case RS6000_OVLD_VEC_CMPNE:
+      returned_expr = resolve_vec_cmpne (&res, args, types, loc);
+      break;
+
+    case RS6000_OVLD_VEC_ADDE:
+    case RS6000_OVLD_VEC_SUBE:
+      returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
+      break;
+
+    case RS6000_OVLD_VEC_ADDEC:
+    case RS6000_OVLD_VEC_SUBEC:
+      returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
+      break;
+
+    case RS6000_OVLD_VEC_SPLATS:
+    case RS6000_OVLD_VEC_PROMOTE:
+      returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
+      break;
+
+    case RS6000_OVLD_VEC_EXTRACT:
+      returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
+      break;
+
+    case RS6000_OVLD_VEC_INSERT:
+      returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
+      break;
+
+    case RS6000_OVLD_VEC_STEP:
+      returned_expr = resolve_vec_step (&res, arglist, nargs);
+      break;
+
+    default:
+      ;
+    }
+
+  if (res == resolved)
+    return returned_expr;
+
+  /* "Regular" built-in functions and overloaded functions share a namespace
+     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
+     only has information for the overloaded functions, so we need an
+     adjusted index for that.  */
+  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
+
+  if (res == resolved_bad)
+    {
+      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
+      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
+      return error_mark_node;
+    }
+
   bool unsupported_builtin = false;
   rs6000_gen_builtins instance_code;
   bool supported = false;
-- 
2.27.0


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

* [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
  2022-01-28 17:50 ` [PATCH 1/8] rs6000: More factoring of overload processing Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-01-28 20:32   ` Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

It was recently pointed out that we get anomalous behavior when using
__attribute__((target)) to select a CPU.  As an example, when building for
-mcpu=power8 but using __attribute__((target("mcpu=power10")), it is legal
to call __builtin_vec_mod, but not vec_mod, even though these are
equivalent.  This is because the equivalence is established with a #define
that is guarded by #ifdef _ARCH_PWR10.

This goofy behavior occurs with both the old builtins support and the
new.  One of the goals of the new builtins support was to make sure all
appropriate interfaces are available using __attribute__((target)), so I
failed in this respect.  This patch corrects the problem by removing the
apply.  For example, #ifdef __PPU__ is still appropriate.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-06  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-overload.def (VEC_ABSD): Remove #ifdef token.
	(VEC_BLENDV): Likewise.
	(VEC_BPERM): Likewise.
	(VEC_CFUGE): Likewise.
	(VEC_CIPHER_BE): Likewise.
	(VEC_CIPHERLAST_BE): Likewise.
	(VEC_CLRL): Likewise.
	(VEC_CLRR): Likewise.
	(VEC_CMPNEZ): Likewise.
	(VEC_CNTLZ): Likewise.
	(VEC_CNTLZM): Likewise.
	(VEC_CNTTZM): Likewise.
	(VEC_CNTLZ_LSBB): Likewise.
	(VEC_CNTM): Likewise.
	(VEC_CNTTZ): Likewise.
	(VEC_CNTTZ_LSBB): Likewise.
	(VEC_CONVERT_4F32_8F16): Likewise.
	(VEC_DIV): Likewise.
	(VEC_DIVE): Likewise.
	(VEC_EQV): Likewise.
	(VEC_EXPANDM): Likewise.
	(VEC_EXTRACT_FP_FROM_SHORTH): Likewise.
	(VEC_EXTRACT_FP_FROM_SHORTL): Likewise.
	(VEC_EXTRACTH): Likewise.
	(VEC_EXTRACTL): Likewise.
	(VEC_EXTRACTM): Likewise.
	(VEC_EXTRACT4B): Likewise.
	(VEC_EXTULX): Likewise.
	(VEC_EXTURX): Likewise.
	(VEC_FIRSTMATCHINDEX): Likewise.
	(VEC_FIRSTMACHOREOSINDEX): Likewise.
	(VEC_FIRSTMISMATCHINDEX): Likewise.
	(VEC_FIRSTMISMATCHOREOSINDEX): Likewise.
	(VEC_GB): Likewise.
	(VEC_GENBM): Likewise.
	(VEC_GENHM): Likewise.
	(VEC_GENWM): Likewise.
	(VEC_GENDM): Likewise.
	(VEC_GENQM): Likewise.
	(VEC_GENPCVM): Likewise.
	(VEC_GNB): Likewise.
	(VEC_INSERTH): Likewise.
	(VEC_INSERTL): Likewise.
	(VEC_INSERT4B): Likewise.
	(VEC_LXVL): Likewise.
	(VEC_MERGEE): Likewise.
	(VEC_MERGEO): Likewise.
	(VEC_MOD): Likewise.
	(VEC_MSUB): Likewise.
	(VEC_MULH): Likewise.
	(VEC_NAND): Likewise.
	(VEC_NCIPHER_BE): Likewise.
	(VEC_NCIPHERLAST_BE): Likewise.
	(VEC_NEARBYINT): Likewise.
	(VEC_NMADD): Likewise.
	(VEC_ORC): Likewise.
	(VEC_PDEP): Likewise.
	(VEC_PERMX): Likewise.
	(VEC_PEXT): Likewise.
	(VEC_POPCNT): Likewise.
	(VEC_PARITY_LSBB): Likewise.
	(VEC_REPLACE_ELT): Likewise.
	(VEC_REPLACE_UN): Likewise.
	(VEC_REVB): Likewise.
	(VEC_RINT): Likewise.
	(VEC_RLMI): Likewise.
	(VEC_RLNM): Likewise.
	(VEC_SBOX_BE): Likewise.
	(VEC_SIGNEXTI): Likewise.
	(VEC_SIGNEXTLL): Likewise.
	(VEC_SIGNEXTQ): Likewise.
	(VEC_SLDB): Likewise.
	(VEC_SLV): Likewise.
	(VEC_SPLATI): Likewise.
	(VEC_SPLATID): Likewise.
	(VEC_SPLATI_INS): Likewise.
	(VEC_SQRT): Likewise.
	(VEC_SRDB): Likewise.
	(VEC_SRV): Likewise.
	(VEC_STRIL): Likewise.
	(VEC_STRIL_P): Likewise.
	(VEC_STRIR): Likewise.
	(VEC_STRIR_P): Likewise.
	(VEC_STXVL): Likewise.
	(VEC_TERNARYLOGIC): Likewise.
	(VEC_TEST_LSBB_ALL_ONES): Likewise.
	(VEC_TEST_LSBB_ALL_ZEROS): Likewise.
	(VEC_VEE): Likewise.
	(VEC_VES): Likewise.
	(VEC_VIE): Likewise.
	(VEC_VPRTYB): Likewise.
	(VEC_VSCEEQ): Likewise.
	(VEC_VSCEGT): Likewise.
	(VEC_VSCELT): Likewise.
	(VEC_VSCEUO): Likewise.
	(VEC_VSEE): Likewise.
	(VEC_VSES): Likewise.
	(VEC_VSIE): Likewise.
	(VEC_VSTDC): Likewise.
	(VEC_VSTDCN): Likewise.
	(VEC_VTDC): Likewise.
	(VEC_XL): Likewise.
	(VEC_XL_BE): Likewise.
	(VEC_XL_LEN_R): Likewise.
	(VEC_XL_SEXT): Likewise.
	(VEC_XL_ZEXT): Likewise.
	(VEC_XST): Likewise.
	(VEC_XST_BE): Likewise.
	(VEC_XST_LEN_R): Likewise.
	(VEC_XST_TRUNC): Likewise.
	(VEC_XXPERMDI): Likewise.
	(VEC_XXSLDWI): Likewise.
	(VEC_TSTSFI_EQ_DD): Likewise.
	(VEC_TSTSFI_EQ_TD): Likewise.
	(VEC_TSTSFI_GT_DD): Likewise.
	(VEC_TSTSFI_GT_TD): Likewise.
	(VEC_TSTSFI_LT_DD): Likewise.
	(VEC_TSTSFI_LT_TD): Likewise.
	(VEC_TSTSFI_OV_DD): Likewise.
	(VEC_TSTSFI_OV_TD): Likewise.
	(VEC_VADDCUQ): Likewise.
	(VEC_VADDECUQ): Likewise.
	(VEC_VADDEUQM): Likewise.
	(VEC_VADDUDM): Likewise.
	(VEC_VADDUQM): Likewise.
	(VEC_VBPERMQ): Likewise.
	(VEC_VCLZB): Likewise.
	(VEC_VCLZD): Likewise.
	(VEC_VCLZH): Likewise.
	(VEC_VCLZW): Likewise.
	(VEC_VCTZB): Likewise.
	(VEC_VCTZD): Likewise.
	(VEC_VCTZH): Likewise.
	(VEC_VCTZW): Likewise.
	(VEC_VEEDP): Likewise.
	(VEC_VEESP): Likewise.
	(VEC_VESDP): Likewise.
	(VEC_VESSP): Likewise.
	(VEC_VIEDP): Likewise.
	(VEC_VIESP): Likewise.
	(VEC_VPKSDSS): Likewise.
	(VEC_VPKSDUS): Likewise.
	(VEC_VPKUDUM): Likewise.
	(VEC_VPKUDUS): Likewise.
	(VEC_VPOPCNT): Likewise.
	(VEC_VPOPCNTB): Likewise.
	(VEC_VPOPCNTD): Likewise.
	(VEC_VPOPCNTH): Likewise.
	(VEC_VPOPCNTW): Likewise.
	(VEC_VPRTYBD): Likewise.
	(VEC_VPRTYBQ): Likewise.
	(VEC_VPRTYBW): Likewise.
	(VEC_VRLD): Likewise.
	(VEC_VSLD): Likewise.
	(VEC_VSRAD): Likewise.
	(VEC_VSRD): Likewise.
	(VEC_VSTDCDP): Likewise.
	(VEC_VSTDCNDP): Likewise.
	(VEC_VSTDCNQP): Likewise.
	(VEC_VSTDCNSP): Likewise.
	(VEC_VSTDCQP): Likewise.
	(VEC_VSTDCSP): Likewise.
	(VEC_VSUBECUQ): Likewise.
	(VEC_VSUBEUQM): Likewise.
	(VEC_VSUBUDM): Likewise.
	(VEC_VSUBUQM): Likewise.
	(VEC_VTDCDP): Likewise.
	(VEC_VTDCSP): Likewise.
	(VEC_VUPKHSW): Likewise.
	(VEC_VUPKLSW): Likewise.
---
 gcc/config/rs6000/rs6000-overload.def | 344 +++++++++++++-------------
 1 file changed, 174 insertions(+), 170 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def
index 7d030abf51b..cdc703e9764 100644
--- a/gcc/config/rs6000/rs6000-overload.def
+++ b/gcc/config/rs6000/rs6000-overload.def
@@ -34,6 +34,10 @@
 ; in rs6000-vecdefines.h.  If no #define is desired, the <abi-name> should
 ; be replaced with the token SKIP.
 ;
+; The <ifdef> token should be used sparingly, because a #define can't be
+; overridden by __attribute__((target)).  It is appropriate for cases
+; where a target override isn't a possibility, like __PPU__.
+;
 ; Each function entry has two lines.  The first line is a prototype line.
 ; See rs6000-builtin-new.def for a description of the prototype line.
 ; A prototype line in this file differs in that it doesn't have an
@@ -205,7 +209,7 @@
   vd __builtin_vec_abs (vd);
     XVABSDP
 
-[VEC_ABSD, vec_absd, __builtin_vec_vadu, _ARCH_PWR9]
+[VEC_ABSD, vec_absd, __builtin_vec_vadu]
   vuc __builtin_vec_vadu (vuc, vuc);
     VADUB
   vus __builtin_vec_vadu (vus, vus);
@@ -503,7 +507,7 @@
   vui __builtin_vec_avg (vui, vui);
     VAVGUW
 
-[VEC_BLENDV, vec_blendv, __builtin_vec_xxblend, _ARCH_PWR10]
+[VEC_BLENDV, vec_blendv, __builtin_vec_xxblend]
   vsc __builtin_vec_xxblend (vsc, vsc, vuc);
     VXXBLEND_V16QI  VXXBLEND_VSC
   vuc __builtin_vec_xxblend (vuc, vuc, vuc);
@@ -525,7 +529,7 @@
   vd __builtin_vec_xxblend (vd, vd, vull);
     VXXBLEND_V2DF
 
-[VEC_BPERM, vec_bperm, __builtin_vec_vbperm_api, _ARCH_PWR8]
+[VEC_BPERM, vec_bperm, __builtin_vec_vbperm_api]
   vull __builtin_vec_vbperm_api (vull, vuc);
     VBPERMD  VBPERMD_VULL
   vull __builtin_vec_vbperm_api (vuq, vuc);
@@ -541,25 +545,25 @@
   vd __builtin_vec_ceil (vd);
     XVRDPIP
 
-[VEC_CFUGE, vec_cfuge, __builtin_vec_cfuge, _ARCH_PWR10]
+[VEC_CFUGE, vec_cfuge, __builtin_vec_cfuge]
   vull __builtin_vec_cfuge (vull, vull);
     VCFUGED
 
-[VEC_CIPHER_BE, vec_cipher_be, __builtin_vec_vcipher_be, _ARCH_PWR8]
+[VEC_CIPHER_BE, vec_cipher_be, __builtin_vec_vcipher_be]
   vuc __builtin_vec_vcipher_be (vuc, vuc);
     VCIPHER_BE
 
-[VEC_CIPHERLAST_BE, vec_cipherlast_be, __builtin_vec_vcipherlast_be, _ARCH_PWR8]
+[VEC_CIPHERLAST_BE, vec_cipherlast_be, __builtin_vec_vcipherlast_be]
   vuc __builtin_vec_vcipherlast_be (vuc, vuc);
     VCIPHERLAST_BE
 
-[VEC_CLRL, vec_clrl, __builtin_vec_clrl, _ARCH_PWR10]
+[VEC_CLRL, vec_clrl, __builtin_vec_clrl]
   vsc __builtin_vec_clrl (vsc, unsigned int);
     VCLRLB  VCLRLB_S
   vuc __builtin_vec_clrl (vuc, unsigned int);
     VCLRLB  VCLRLB_U
 
-[VEC_CLRR, vec_clrr, __builtin_vec_clrr, _ARCH_PWR10]
+[VEC_CLRR, vec_clrr, __builtin_vec_clrr]
   vsc __builtin_vec_clrr (vsc, unsigned int);
     VCLRRB  VCLRRB_S
   vuc __builtin_vec_clrr (vuc, unsigned int);
@@ -1026,7 +1030,7 @@
   signed int __builtin_vec_vcmpne_p (signed int, vbll, vsll);
     VCMPNED_P  VCMPNED_P_SB
 
-[VEC_CMPNEZ, vec_cmpnez, __builtin_vec_vcmpnez, _ARCH_PWR9]
+[VEC_CMPNEZ, vec_cmpnez, __builtin_vec_vcmpnez]
   vbc __builtin_vec_cmpnez (vsc, vsc);
     CMPNEZB  CMPNEZB_S
   vbc __builtin_vec_cmpnez (vuc, vuc);
@@ -1064,7 +1068,7 @@
   signed int __builtin_byte_in_range (unsigned int, unsigned int);
     CMPRB2
 
-[VEC_CNTLZ, vec_cntlz, __builtin_vec_vclz, _ARCH_PWR8]
+[VEC_CNTLZ, vec_cntlz, __builtin_vec_vclz]
   vsc __builtin_vec_vclz (vsc);
     VCLZB  VCLZB_S
   vuc __builtin_vec_vclz (vuc);
@@ -1082,15 +1086,15 @@
   vull __builtin_vec_vclz (vull);
     VCLZD  VCLZD_U
 
-[VEC_CNTLZM, vec_cntlzm, __builtin_vec_vclzdm, _ARCH_PWR10]
+[VEC_CNTLZM, vec_cntlzm, __builtin_vec_vclzdm]
   vull __builtin_vec_vclzdm (vull, vull);
     VCLZDM
 
-[VEC_CNTTZM, vec_cnttzm, __builtin_vec_vctzdm, _ARCH_PWR10]
+[VEC_CNTTZM, vec_cnttzm, __builtin_vec_vctzdm]
   vull __builtin_vec_vctzdm (vull, vull);
     VCTZDM
 
-[VEC_CNTLZ_LSBB, vec_cntlz_lsbb, __builtin_vec_vclzlsbb, _ARCH_PWR9]
+[VEC_CNTLZ_LSBB, vec_cntlz_lsbb, __builtin_vec_vclzlsbb]
   signed int __builtin_vec_vclzlsbb (vsc);
     VCLZLSBB_V16QI  VCLZLSBB_VSC
   signed int __builtin_vec_vclzlsbb (vuc);
@@ -1104,7 +1108,7 @@
   signed int __builtin_vec_vclzlsbb (vui);
     VCLZLSBB_V4SI  VCLZLSBB_VUI
 
-[VEC_CNTM, vec_cntm, __builtin_vec_cntm, _ARCH_PWR10]
+[VEC_CNTM, vec_cntm, __builtin_vec_cntm]
   unsigned long long __builtin_vec_cntm (vuc, const int);
     VCNTMBB
   unsigned long long __builtin_vec_cntm (vus, const int);
@@ -1114,7 +1118,7 @@
   unsigned long long __builtin_vec_cntm (vull, const int);
     VCNTMBD
 
-[VEC_CNTTZ, vec_cnttz, __builtin_vec_vctz, _ARCH_PWR9]
+[VEC_CNTTZ, vec_cnttz, __builtin_vec_vctz]
   vsc __builtin_vec_vctz (vsc);
     VCTZB  VCTZB_S
   vuc __builtin_vec_vctz (vuc);
@@ -1132,7 +1136,7 @@
   vull __builtin_vec_vctz (vull);
     VCTZD  VCTZD_U
 
-[VEC_CNTTZ_LSBB, vec_cnttz_lsbb, __builtin_vec_vctzlsbb, _ARCH_PWR9]
+[VEC_CNTTZ_LSBB, vec_cnttz_lsbb, __builtin_vec_vctzlsbb]
   signed int __builtin_vec_vctzlsbb (vsc);
     VCTZLSBB_V16QI  VCTZLSBB_VSC
   signed int __builtin_vec_vctzlsbb (vuc);
@@ -1150,7 +1154,7 @@
   vus __builtin_vec_convert_4f32_8i16 (vf, vf);
     CONVERT_4F32_8I16
 
-[VEC_CONVERT_4F32_8F16, vec_pack_to_short_fp32, __builtin_vec_convert_4f32_8f16, _ARCH_PWR9]
+[VEC_CONVERT_4F32_8F16, vec_pack_to_short_fp32, __builtin_vec_convert_4f32_8f16]
   vus __builtin_vec_convert_4f32_8f16 (vf, vf);
     CONVERT_4F32_8F16
 
@@ -1182,7 +1186,7 @@
   vull __builtin_vec_ctu (vd, const int);
     XVCVDPUXDS_SCALE
 
-[VEC_DIV, vec_div, __builtin_vec_div, __VSX__]
+[VEC_DIV, vec_div, __builtin_vec_div]
   vsi __builtin_vec_div (vsi, vsi);
     VDIVSW
   vui __builtin_vec_div (vui, vui);
@@ -1200,7 +1204,7 @@
   vd __builtin_vec_div (vd, vd);
     XVDIVDP
 
-[VEC_DIVE, vec_dive, __builtin_vec_dive, _ARCH_PWR10]
+[VEC_DIVE, vec_dive, __builtin_vec_dive]
   vsi __builtin_vec_dive (vsi, vsi);
     VDIVESW
   vui __builtin_vec_dive (vui, vui);
@@ -1436,7 +1440,7 @@
   void __builtin_vec_dstt (vf *, const int, const int);
     DSTT  DSTT_VF
 
-[VEC_EQV, vec_eqv, __builtin_vec_eqv, _ARCH_PWR8]
+[VEC_EQV, vec_eqv, __builtin_vec_eqv]
   vsc __builtin_vec_eqv (vsc, vsc);
     EQV_V16QI
   vuc __builtin_vec_eqv (vuc, vuc);
@@ -1499,7 +1503,7 @@
   vull __builtin_vec_eqv (vull, vbll);
     EQV_V2DI_UNS  EQV_VULL_VBLL
 
-[VEC_EXPANDM, vec_expandm, __builtin_vec_vexpandm, _ARCH_PWR10]
+[VEC_EXPANDM, vec_expandm, __builtin_vec_vexpandm]
   vuc __builtin_vec_vexpandm (vuc);
     VEXPANDMB
   vus __builtin_vec_vexpandm (vus);
@@ -1524,15 +1528,15 @@
   vsi __builtin_vec_extract (vsi, signed int);
     VSPLTW  EXTRACT_FAKERY
 
-[VEC_EXTRACT_FP_FROM_SHORTH, vec_extract_fp32_from_shorth, __builtin_vec_vextract_fp_from_shorth, _ARCH_PWR9]
+[VEC_EXTRACT_FP_FROM_SHORTH, vec_extract_fp32_from_shorth, __builtin_vec_vextract_fp_from_shorth]
   vf __builtin_vec_vextract_fp_from_shorth (vus);
     VEXTRACT_FP_FROM_SHORTH
 
-[VEC_EXTRACT_FP_FROM_SHORTL, vec_extract_fp32_from_shortl, __builtin_vec_vextract_fp_from_shortl, _ARCH_PWR9]
+[VEC_EXTRACT_FP_FROM_SHORTL, vec_extract_fp32_from_shortl, __builtin_vec_vextract_fp_from_shortl]
   vf __builtin_vec_vextract_fp_from_shortl (vus);
     VEXTRACT_FP_FROM_SHORTL
 
-[VEC_EXTRACTH, vec_extracth, __builtin_vec_extracth, _ARCH_PWR10]
+[VEC_EXTRACTH, vec_extracth, __builtin_vec_extracth]
   vull __builtin_vec_extracth (vuc, vuc, unsigned char);
     VEXTRACTBR
   vull __builtin_vec_extracth (vus, vus, unsigned char);
@@ -1542,7 +1546,7 @@
   vull __builtin_vec_extracth (vull, vull, unsigned char);
     VEXTRACTDR
 
-[VEC_EXTRACTL, vec_extractl, __builtin_vec_extractl, _ARCH_PWR10]
+[VEC_EXTRACTL, vec_extractl, __builtin_vec_extractl]
   vull __builtin_vec_extractl (vuc, vuc, unsigned char);
     VEXTRACTBL
   vull __builtin_vec_extractl (vus, vus, unsigned char);
@@ -1552,7 +1556,7 @@
   vull __builtin_vec_extractl (vull, vull, unsigned char);
     VEXTRACTDL
 
-[VEC_EXTRACTM, vec_extractm, __builtin_vec_vextractm, _ARCH_PWR10]
+[VEC_EXTRACTM, vec_extractm, __builtin_vec_vextractm]
   signed int __builtin_vec_vextractm (vuc);
     VEXTRACTMB
   signed int __builtin_vec_vextractm (vus);
@@ -1564,11 +1568,11 @@
   signed int __builtin_vec_vextractm (vuq);
     VEXTRACTMQ
 
-[VEC_EXTRACT4B, vec_extract4b, __builtin_vec_extract4b, _ARCH_PWR9]
+[VEC_EXTRACT4B, vec_extract4b, __builtin_vec_extract4b]
   vull __builtin_vec_extract4b (vuc, const int);
     EXTRACT4B
 
-[VEC_EXTULX, vec_xlx, __builtin_vec_vextulx, _ARCH_PWR9]
+[VEC_EXTULX, vec_xlx, __builtin_vec_vextulx]
   signed char __builtin_vec_vextulx (unsigned int, vsc);
     VEXTUBLX  VEXTUBLX_S
   unsigned char __builtin_vec_vextulx (unsigned int, vuc);
@@ -1584,7 +1588,7 @@
   float __builtin_vec_vextulx (unsigned int, vf);
     VEXTUWLX  VEXTUWLX_F
 
-[VEC_EXTURX, vec_xrx, __builtin_vec_vexturx, _ARCH_PWR9]
+[VEC_EXTURX, vec_xrx, __builtin_vec_vexturx]
   signed char __builtin_vec_vexturx (unsigned int, vsc);
     VEXTUBRX  VEXTUBRX_S
   unsigned char __builtin_vec_vexturx (unsigned int, vuc);
@@ -1600,7 +1604,7 @@
   float __builtin_vec_vexturx (unsigned int, vf);
     VEXTUWRX  VEXTUWRX_F
 
-[VEC_FIRSTMATCHINDEX, vec_first_match_index, __builtin_vec_first_match_index, _ARCH_PWR9]
+[VEC_FIRSTMATCHINDEX, vec_first_match_index, __builtin_vec_first_match_index]
   unsigned int __builtin_vec_first_match_index (vsc, vsc);
     VFIRSTMATCHINDEX_V16QI FIRSTMATCHINDEX_VSC
   unsigned int __builtin_vec_first_match_index (vuc, vuc);
@@ -1614,7 +1618,7 @@
   unsigned int __builtin_vec_first_match_index (vui, vui);
     VFIRSTMATCHINDEX_V4SI FIRSTMATCHINDEX_VUI
 
-[VEC_FIRSTMATCHOREOSINDEX, vec_first_match_or_eos_index, __builtin_vec_first_match_or_eos_index, _ARCH_PWR9]
+[VEC_FIRSTMATCHOREOSINDEX, vec_first_match_or_eos_index, __builtin_vec_first_match_or_eos_index]
   unsigned int __builtin_vec_first_match_or_eos_index (vsc, vsc);
     VFIRSTMATCHOREOSINDEX_V16QI FIRSTMATCHOREOSINDEX_VSC
   unsigned int __builtin_vec_first_match_or_eos_index (vuc, vuc);
@@ -1628,7 +1632,7 @@
   unsigned int __builtin_vec_first_match_or_eos_index (vui, vui);
     VFIRSTMATCHOREOSINDEX_V4SI FIRSTMATCHOREOSINDEX_VUI
 
-[VEC_FIRSTMISMATCHINDEX, vec_first_mismatch_index, __builtin_vec_first_mismatch_index, _ARCH_PWR9]
+[VEC_FIRSTMISMATCHINDEX, vec_first_mismatch_index, __builtin_vec_first_mismatch_index]
   unsigned int __builtin_vec_first_mismatch_index (vsc, vsc);
     VFIRSTMISMATCHINDEX_V16QI FIRSTMISMATCHINDEX_VSC
   unsigned int __builtin_vec_first_mismatch_index (vuc, vuc);
@@ -1642,7 +1646,7 @@
   unsigned int __builtin_vec_first_mismatch_index (vui, vui);
     VFIRSTMISMATCHINDEX_V4SI FIRSTMISMATCHINDEX_VUI
 
-[VEC_FIRSTMISMATCHOREOSINDEX, vec_first_mismatch_or_eos_index, __builtin_vec_first_mismatch_or_eos_index, _ARCH_PWR9]
+[VEC_FIRSTMISMATCHOREOSINDEX, vec_first_mismatch_or_eos_index, __builtin_vec_first_mismatch_or_eos_index]
   unsigned int __builtin_vec_first_mismatch_or_eos_index (vsc, vsc);
     VFIRSTMISMATCHOREOSINDEX_V16QI FIRSTMISMATCHOREOSINDEX_VSC
   unsigned int __builtin_vec_first_mismatch_or_eos_index (vuc, vuc);
@@ -1692,33 +1696,33 @@
   vd __builtin_vec_floor (vd);
     XVRDPIM
 
-[VEC_GB, vec_gb, __builtin_vec_vgbbd, _ARCH_PWR8]
+[VEC_GB, vec_gb, __builtin_vec_vgbbd]
   vsc __builtin_vec_vgbbd (vsc);
     VGBBD  VGBBD_S
   vuc __builtin_vec_vgbbd (vuc);
     VGBBD  VGBBD_U
 
-[VEC_GENBM, vec_genbm, __builtin_vec_mtvsrbm, _ARCH_PWR10]
+[VEC_GENBM, vec_genbm, __builtin_vec_mtvsrbm]
   vuc __builtin_vec_mtvsrbm (unsigned long long);
     MTVSRBM
 
-[VEC_GENHM, vec_genhm, __builtin_vec_mtvsrhm, _ARCH_PWR10]
+[VEC_GENHM, vec_genhm, __builtin_vec_mtvsrhm]
   vus __builtin_vec_mtvsrhm (unsigned long long);
     MTVSRHM
 
-[VEC_GENWM, vec_genwm, __builtin_vec_mtvsrwm, _ARCH_PWR10]
+[VEC_GENWM, vec_genwm, __builtin_vec_mtvsrwm]
   vui __builtin_vec_mtvsrwm (unsigned long long);
     MTVSRWM
 
-[VEC_GENDM, vec_gendm, __builtin_vec_mtvsrdm, _ARCH_PWR10]
+[VEC_GENDM, vec_gendm, __builtin_vec_mtvsrdm]
   vull __builtin_vec_mtvsrdm (unsigned long long);
     MTVSRDM
 
-[VEC_GENQM, vec_genqm, __builtin_vec_mtvsrqm, _ARCH_PWR10]
+[VEC_GENQM, vec_genqm, __builtin_vec_mtvsrqm]
   vuq __builtin_vec_mtvsrqm (unsigned long long);
     MTVSRQM
 
-[VEC_GENPCVM, vec_genpcvm, __builtin_vec_xxgenpcvm, _ARCH_PWR10]
+[VEC_GENPCVM, vec_genpcvm, __builtin_vec_xxgenpcvm]
   vuc __builtin_vec_xxgenpcvm (vuc, const int);
     XXGENPCVM_V16QI
   vus __builtin_vec_xxgenpcvm (vus, const int);
@@ -1728,7 +1732,7 @@
   vull __builtin_vec_xxgenpcvm (vull, const int);
     XXGENPCVM_V2DI
 
-[VEC_GNB, vec_gnb, __builtin_vec_gnb, _ARCH_PWR10]
+[VEC_GNB, vec_gnb, __builtin_vec_gnb]
   unsigned long long __builtin_vec_gnb (vuq, const int);
     VGNB
 
@@ -1740,7 +1744,7 @@
   vsi __builtin_vec_insert (vsi, vsi, signed int);
     XXPERMDI_4SI  INSERT_FAKERY
 
-[VEC_INSERTH, vec_inserth, __builtin_vec_inserth, _ARCH_PWR10]
+[VEC_INSERTH, vec_inserth, __builtin_vec_inserth]
   vuc __builtin_vec_inserth (unsigned char, vuc, unsigned int);
     VINSERTGPRBR
   vuc __builtin_vec_inserth (vuc, vuc, unsigned int);
@@ -1756,7 +1760,7 @@
   vull __builtin_vec_inserth (unsigned long long, vull, unsigned int);
     VINSERTGPRDR
 
-[VEC_INSERTL, vec_insertl, __builtin_vec_insertl, _ARCH_PWR10]
+[VEC_INSERTL, vec_insertl, __builtin_vec_insertl]
   vuc __builtin_vec_insertl (unsigned char, vuc, unsigned int);
     VINSERTGPRBL
   vuc __builtin_vec_insertl (vuc, vuc, unsigned int);
@@ -1772,7 +1776,7 @@
   vull __builtin_vec_insertl (unsigned long long, vull, unsigned int);
     VINSERTGPRDL
 
-[VEC_INSERT4B, vec_insert4b, __builtin_vec_insert4b, _ARCH_PWR9]
+[VEC_INSERT4B, vec_insert4b, __builtin_vec_insert4b]
   vuc __builtin_vec_insert4b (vsi, vuc, const int);
     INSERT4B  INSERT4B_S
   vuc __builtin_vec_insert4b (vui, vuc, const int);
@@ -2128,7 +2132,7 @@
   vuc __builtin_vec_lvsr (signed long, const double *);
     LVSR  LVSR_D
 
-[VEC_LXVL, vec_xl_len, __builtin_vec_lxvl, _ARCH_PPC64_PWR9]
+[VEC_LXVL, vec_xl_len, __builtin_vec_lxvl]
   vsc __builtin_vec_lxvl (const signed char *, unsigned int);
     LXVL  LXVL_VSC
   vuc __builtin_vec_lxvl (const unsigned char *, unsigned int);
@@ -2227,7 +2231,7 @@
   vull __builtin_vec_max (vbll, vull);
     VMAXUD  VMAXUD_BU
 
-[VEC_MERGEE, vec_mergee, __builtin_vec_vmrgew, _ARCH_PWR8]
+[VEC_MERGEE, vec_mergee, __builtin_vec_vmrgew]
   vsi __builtin_vec_vmrgew (vsi, vsi);
     VMRGEW_V4SI  VMRGEW_VSI
   vui __builtin_vec_vmrgew (vui, vui);
@@ -2327,7 +2331,7 @@
   vull __builtin_vec_mergel (vbll, vull);
     VEC_MERGEL_V2DI  VEC_MERGEL_VBLL_VULL
 
-[VEC_MERGEO, vec_mergeo, __builtin_vec_vmrgow, _ARCH_PWR8]
+[VEC_MERGEO, vec_mergeo, __builtin_vec_vmrgow]
   vsi __builtin_vec_vmrgow (vsi, vsi);
     VMRGOW_V4SI  VMRGOW_VSI
   vui __builtin_vec_vmrgow (vui, vui);
@@ -2414,7 +2418,7 @@
   vus __builtin_vec_mladd (vus, vus, vus);
     VMLADDUHM  VMLADDUHM_VUS2
 
-[VEC_MOD, vec_mod, __builtin_vec_mod, _ARCH_PWR10]
+[VEC_MOD, vec_mod, __builtin_vec_mod]
   vsi __builtin_vec_mod (vsi, vsi);
     VMODSW
   vui __builtin_vec_mod (vui, vui);
@@ -2432,7 +2436,7 @@
   vss __builtin_vec_mradds (vss, vss, vss);
     VMHRADDSHS
 
-[VEC_MSUB, vec_msub, __builtin_vec_msub, __VSX__]
+[VEC_MSUB, vec_msub, __builtin_vec_msub]
   vf __builtin_vec_msub (vf, vf, vf);
     XVMSUBSP
   vd __builtin_vec_msub (vd, vd, vd);
@@ -2511,7 +2515,7 @@
   vuq __builtin_vec_mule (vull, vull);
     VMULEUD
 
-[VEC_MULH, vec_mulh, __builtin_vec_mulh, _ARCH_PWR10]
+[VEC_MULH, vec_mulh, __builtin_vec_mulh]
   vsi __builtin_vec_mulh (vsi, vsi);
     VMULHSW
   vui __builtin_vec_mulh (vui, vui);
@@ -2553,7 +2557,7 @@
   vd __builtin_vec_nabs (vd);
     NABS_V2DF
 
-[VEC_NAND, vec_nand, __builtin_vec_nand, _ARCH_PWR8]
+[VEC_NAND, vec_nand, __builtin_vec_nand]
   vsc __builtin_vec_nand (vsc, vsc);
     NAND_V16QI
   vuc __builtin_vec_nand (vuc, vuc);
@@ -2616,15 +2620,15 @@
   vull __builtin_vec_nand (vull, vbll);
     NAND_V2DI_UNS  NAND_VULL_VBLL
 
-[VEC_NCIPHER_BE, vec_ncipher_be, __builtin_vec_vncipher_be, _ARCH_PWR8]
+[VEC_NCIPHER_BE, vec_ncipher_be, __builtin_vec_vncipher_be]
   vuc __builtin_vec_vncipher_be (vuc, vuc);
     VNCIPHER_BE
 
-[VEC_NCIPHERLAST_BE, vec_ncipherlast_be, __builtin_vec_vncipherlast_be, _ARCH_PWR8]
+[VEC_NCIPHERLAST_BE, vec_ncipherlast_be, __builtin_vec_vncipherlast_be]
   vuc __builtin_vec_vncipherlast_be (vuc, vuc);
     VNCIPHERLAST_BE
 
-[VEC_NEARBYINT, vec_nearbyint, __builtin_vec_nearbyint, __VSX__]
+[VEC_NEARBYINT, vec_nearbyint, __builtin_vec_nearbyint]
   vf __builtin_vec_nearbyint (vf);
     XVRSPI  XVRSPI_NBI
   vd __builtin_vec_nearbyint (vd);
@@ -2644,7 +2648,7 @@
   vd __builtin_vec_neg (vd);
     NEG_V2DF
 
-[VEC_NMADD, vec_nmadd, __builtin_vec_nmadd, __VSX__]
+[VEC_NMADD, vec_nmadd, __builtin_vec_nmadd]
   vf __builtin_vec_nmadd (vf, vf, vf);
     XVNMADDSP
   vd __builtin_vec_nmadd (vd, vd, vd);
@@ -2778,7 +2782,7 @@
   vd __builtin_vec_or (vbll, vd);
     VOR_V2DF  VOR_VBLL_VD
 
-[VEC_ORC, vec_orc, __builtin_vec_orc, _ARCH_PWR8]
+[VEC_ORC, vec_orc, __builtin_vec_orc]
   vsc __builtin_vec_orc (vsc, vsc);
     ORC_V16QI
   vuc __builtin_vec_orc (vuc, vuc);
@@ -2895,7 +2899,7 @@
   vui __builtin_vec_packsu (vsll, vsll);
     VPKSDUS
 
-[VEC_PDEP, vec_pdep, __builtin_vec_vpdepd, _ARCH_PWR10]
+[VEC_PDEP, vec_pdep, __builtin_vec_vpdepd]
   vull __builtin_vec_vpdepd (vull, vull);
     VPDEPD
 
@@ -2940,7 +2944,7 @@
   vbc __builtin_vec_perm (vbc, vbc, vbc);
     VPERM_16QI  VPERM_VBC_VBC_VBC
 
-[VEC_PERMX, vec_permx, __builtin_vec_xxpermx, _ARCH_PWR10]
+[VEC_PERMX, vec_permx, __builtin_vec_xxpermx]
   vsc __builtin_vec_xxpermx (vsc, vsc, vuc, const int);
     XXPERMX_UV2DI  XXPERMX_VSC
   vuc __builtin_vec_xxpermx (vuc, vuc, vuc, const int);
@@ -2970,7 +2974,7 @@
   vbc __builtin_vec_vpermxor (vbc, vbc, vbc);
     VPERMXOR  VPERMXOR_VBC
 
-[VEC_PEXT, vec_pext, __builtin_vec_vpextd, _ARCH_PWR10]
+[VEC_PEXT, vec_pext, __builtin_vec_vpextd]
   vull __builtin_vec_vpextd (vull, vull);
     VPEXTD
 
@@ -2984,7 +2988,7 @@
   vuq __builtin_vec_vpmsum (vull, vull);
     VPMSUMD  VPMSUMD_V
 
-[VEC_POPCNT, vec_popcnt, __builtin_vec_vpopcntu, _ARCH_PWR8]
+[VEC_POPCNT, vec_popcnt, __builtin_vec_vpopcntu]
   vuc __builtin_vec_vpopcntu (vsc);
     VPOPCNTB
   vuc __builtin_vec_vpopcntu (vuc);
@@ -3002,7 +3006,7 @@
   vull __builtin_vec_vpopcntu (vull);
     VPOPCNTUD
 
-[VEC_PARITY_LSBB, vec_parity_lsbb, __builtin_vec_vparity_lsbb, _ARCH_PWR9]
+[VEC_PARITY_LSBB, vec_parity_lsbb, __builtin_vec_vparity_lsbb]
   vui __builtin_vec_vparity_lsbb (vsi);
     VPRTYBW  VPRTYBW_S
   vui __builtin_vec_vparity_lsbb (vui);
@@ -3036,7 +3040,7 @@
   vd __builtin_vec_recipdiv (vd, vd);
     RECIP_V2DF
 
-[VEC_REPLACE_ELT, vec_replace_elt, __builtin_vec_replace_elt, _ARCH_PWR10]
+[VEC_REPLACE_ELT, vec_replace_elt, __builtin_vec_replace_elt]
   vui __builtin_vec_replace_elt (vui, unsigned int, const int);
     VREPLACE_ELT_UV4SI
   vsi __builtin_vec_replace_elt (vsi, signed int, const int);
@@ -3050,7 +3054,7 @@
   vd __builtin_vec_replace_elt (vd, double, const int);
     VREPLACE_ELT_V2DF
 
-[VEC_REPLACE_UN, vec_replace_unaligned, __builtin_vec_replace_un, _ARCH_PWR10]
+[VEC_REPLACE_UN, vec_replace_unaligned, __builtin_vec_replace_un]
   vui __builtin_vec_replace_un (vui, unsigned int, const int);
     VREPLACE_UN_UV4SI
   vsi __builtin_vec_replace_un (vsi, signed int, const int);
@@ -3064,7 +3068,7 @@
   vd __builtin_vec_replace_un (vd, double, const int);
     VREPLACE_UN_V2DF
 
-[VEC_REVB, vec_revb, __builtin_vec_revb, _ARCH_PWR8]
+[VEC_REVB, vec_revb, __builtin_vec_revb]
   vss __builtin_vec_revb (vss);
     REVB_V8HI  REVB_VSS
   vus __builtin_vec_revb (vus);
@@ -3129,7 +3133,7 @@
   vd __builtin_vec_vreve (vd);
     VREVE_V2DF
 
-[VEC_RINT, vec_rint, __builtin_vec_rint, __VSX__]
+[VEC_RINT, vec_rint, __builtin_vec_rint]
   vf __builtin_vec_rint (vf);
     XVRSPIC
   vd __builtin_vec_rint (vd);
@@ -3157,7 +3161,7 @@
   vuq __builtin_vec_rl (vuq, vuq);
     VRLQ  VRLQ_VUQ
 
-[VEC_RLMI, vec_rlmi, __builtin_vec_rlmi, _ARCH_PWR9]
+[VEC_RLMI, vec_rlmi, __builtin_vec_rlmi]
   vui __builtin_vec_rlmi (vui, vui, vui);
     VRLWMI
   vull __builtin_vec_rlmi (vull, vull, vull);
@@ -3167,7 +3171,7 @@
   vuq __builtin_vec_rlmi (vuq, vuq, vuq);
     VRLQMI  VRLQMI_VUQ
 
-[VEC_RLNM, vec_vrlnm, __builtin_vec_rlnm, _ARCH_PWR9]
+[VEC_RLNM, vec_vrlnm, __builtin_vec_rlnm]
   vui __builtin_vec_rlnm (vui, vui);
     VRLWNM
   vull __builtin_vec_rlnm (vull, vull);
@@ -3195,7 +3199,7 @@
   vd __builtin_vec_rsqrte (vd);
     XVRSQRTEDP
 
-[VEC_SBOX_BE, vec_sbox_be, __builtin_vec_sbox_be, _ARCH_PWR8]
+[VEC_SBOX_BE, vec_sbox_be, __builtin_vec_sbox_be]
   vuc __builtin_vec_sbox_be (vuc);
     VSBOX_BE
 
@@ -3294,13 +3298,13 @@
   vsi __builtin_vec_vsignedo (vd);
     VEC_VSIGNEDO_V2DF
 
-[VEC_SIGNEXTI, vec_signexti, __builtin_vec_signexti, _ARCH_PWR9]
+[VEC_SIGNEXTI, vec_signexti, __builtin_vec_signexti]
   vsi __builtin_vec_signexti (vsc);
     VSIGNEXTSB2W
   vsi __builtin_vec_signexti (vss);
     VSIGNEXTSH2W
 
-[VEC_SIGNEXTLL, vec_signextll, __builtin_vec_signextll, _ARCH_PWR9]
+[VEC_SIGNEXTLL, vec_signextll, __builtin_vec_signextll]
   vsll __builtin_vec_signextll (vsc);
     VSIGNEXTSB2D
   vsll __builtin_vec_signextll (vss);
@@ -3308,7 +3312,7 @@
   vsll __builtin_vec_signextll (vsi);
     VSIGNEXTSW2D
 
-[VEC_SIGNEXTQ, vec_signextq, __builtin_vec_signextq, _ARCH_PWR10]
+[VEC_SIGNEXTQ, vec_signextq, __builtin_vec_signextq]
   vsq __builtin_vec_signextq (vsll);
     VSIGNEXTSD2Q
 
@@ -3366,7 +3370,7 @@
   vd __builtin_vec_sld (vd, vd, const int);
     VSLDOI_2DF
 
-[VEC_SLDB, vec_sldb, __builtin_vec_sldb, _ARCH_PWR10]
+[VEC_SLDB, vec_sldb, __builtin_vec_sldb]
   vsc __builtin_vec_sldb (vsc, vsc, const int);
     VSLDB_V16QI  VSLDB_VSC
   vuc __builtin_vec_sldb (vuc, vuc, const int);
@@ -3521,7 +3525,7 @@
   vf __builtin_vec_slo (vf, vuc);
     VSLO  VSLO_VFU
 
-[VEC_SLV, vec_slv, __builtin_vec_vslv, _ARCH_PWR9]
+[VEC_SLV, vec_slv, __builtin_vec_vslv]
   vuc __builtin_vec_vslv (vuc, vuc);
     VSLV
 
@@ -3572,17 +3576,17 @@
 ; There are no entries for vec_splat_u{8,16,32}.  These are handled
 ; in altivec.h with a #define and a cast.
 
-[VEC_SPLATI, vec_splati, __builtin_vec_xxspltiw, _ARCH_PWR10]
+[VEC_SPLATI, vec_splati, __builtin_vec_xxspltiw]
   vsi __builtin_vec_xxspltiw (signed int);
     VXXSPLTIW_V4SI
   vf __builtin_vec_xxspltiw (float);
     VXXSPLTIW_V4SF
 
-[VEC_SPLATID, vec_splatid, __builtin_vec_xxspltid, _ARCH_PWR10]
+[VEC_SPLATID, vec_splatid, __builtin_vec_xxspltid]
   vd __builtin_vec_xxspltid (float);
     VXXSPLTIDP
 
-[VEC_SPLATI_INS, vec_splati_ins, __builtin_vec_xxsplti32dx, _ARCH_PWR10]
+[VEC_SPLATI_INS, vec_splati_ins, __builtin_vec_xxsplti32dx]
   vsi __builtin_vec_xxsplti32dx (vsi, const int, signed int);
     VXXSPLTI32DX_V4SI  VXXSPLTI32DX_VSI
   vui __builtin_vec_xxsplti32dx (vui, const int, unsigned int);
@@ -3598,7 +3602,7 @@
   vsi __builtin_vec_splats (vsi);
     ABS_V4SI SPLATS_FAKERY
 
-[VEC_SQRT, vec_sqrt, __builtin_vec_sqrt, __VSX__]
+[VEC_SQRT, vec_sqrt, __builtin_vec_sqrt]
   vf __builtin_vec_sqrt (vf);
     XVSQRTSP
   vd __builtin_vec_sqrt (vd);
@@ -3648,7 +3652,7 @@
   vuq __builtin_vec_sra (vuq, vuq);
     VSRAQ  VSRAQ_VUQ
 
-[VEC_SRDB, vec_srdb, __builtin_vec_srdb, _ARCH_PWR10]
+[VEC_SRDB, vec_srdb, __builtin_vec_srdb]
   vsc __builtin_vec_srdb (vsc, vsc, const int);
     VSRDB_V16QI  VSRDB_VSC
   vuc __builtin_vec_srdb (vuc, vuc, const int);
@@ -3775,7 +3779,7 @@
   vf __builtin_vec_sro (vf, vuc);
     VSRO  VSRO_VFU
 
-[VEC_SRV, vec_srv, __builtin_vec_vsrv, _ARCH_PWR9]
+[VEC_SRV, vec_srv, __builtin_vec_vsrv]
   vuc __builtin_vec_vsrv (vuc, vuc);
     VSRV
 
@@ -3956,7 +3960,7 @@
   void __builtin_vec_stl (vd, signed long long, double *);
     STVXL_V2DF  STVXL_D
 
-[VEC_STRIL, vec_stril, __builtin_vec_stril, _ARCH_PWR10]
+[VEC_STRIL, vec_stril, __builtin_vec_stril]
   vuc __builtin_vec_stril (vuc);
     VSTRIBL  VSTRIBL_U
   vsc __builtin_vec_stril (vsc);
@@ -3966,7 +3970,7 @@
   vss __builtin_vec_stril (vss);
     VSTRIHL  VSTRIHL_S
 
-[VEC_STRIL_P, vec_stril_p, __builtin_vec_stril_p, _ARCH_PWR10]
+[VEC_STRIL_P, vec_stril_p, __builtin_vec_stril_p]
   signed int __builtin_vec_stril_p (vuc);
     VSTRIBL_P  VSTRIBL_PU
   signed int __builtin_vec_stril_p (vsc);
@@ -3976,7 +3980,7 @@
   signed int __builtin_vec_stril_p (vss);
     VSTRIHL_P  VSTRIHL_PS
 
-[VEC_STRIR, vec_strir, __builtin_vec_strir, _ARCH_PWR10]
+[VEC_STRIR, vec_strir, __builtin_vec_strir]
   vuc __builtin_vec_strir (vuc);
     VSTRIBR  VSTRIBR_U
   vsc __builtin_vec_strir (vsc);
@@ -3986,7 +3990,7 @@
   vss __builtin_vec_strir (vss);
     VSTRIHR  VSTRIHR_S
 
-[VEC_STRIR_P, vec_strir_p, __builtin_vec_strir_p, _ARCH_PWR10]
+[VEC_STRIR_P, vec_strir_p, __builtin_vec_strir_p]
   signed int __builtin_vec_strir_p (vuc);
     VSTRIBR_P  VSTRIBR_PU
   signed int __builtin_vec_strir_p (vsc);
@@ -4148,7 +4152,7 @@
   void __builtin_vec_stvrxl (vf, signed long long, float *);
     STVRXL  STVRXL_F
 
-[VEC_STXVL, vec_xst_len, __builtin_vec_stxvl, _ARCH_PPC64_PWR9]
+[VEC_STXVL, vec_xst_len, __builtin_vec_stxvl]
   void __builtin_vec_stxvl (vsc, signed char *, unsigned int);
     STXVL  STXVL_VSC
   void __builtin_vec_stxvl (vuc, unsigned char *, unsigned int);
@@ -4316,7 +4320,7 @@
   vsi __builtin_vec_sums (vsi, vsi);
     VSUMSWS
 
-[VEC_TERNARYLOGIC, vec_ternarylogic, __builtin_vec_xxeval, _ARCH_PWR10]
+[VEC_TERNARYLOGIC, vec_ternarylogic, __builtin_vec_xxeval]
   vuc __builtin_vec_xxeval (vuc, vuc, vuc, const int);
     XXEVAL  XXEVAL_VUC
   vus __builtin_vec_xxeval (vus, vus, vus, const int);
@@ -4328,11 +4332,11 @@
   vuq __builtin_vec_xxeval (vuq, vuq, vuq, const int);
     XXEVAL  XXEVAL_VUQ
 
-[VEC_TEST_LSBB_ALL_ONES, vec_test_lsbb_all_ones, __builtin_vec_xvtlsbb_all_ones, _ARCH_PWR9]
+[VEC_TEST_LSBB_ALL_ONES, vec_test_lsbb_all_ones, __builtin_vec_xvtlsbb_all_ones]
   signed int __builtin_vec_xvtlsbb_all_ones (vuc);
     XVTLSBB_ONES
 
-[VEC_TEST_LSBB_ALL_ZEROS, vec_test_lsbb_all_zeros, __builtin_vec_xvtlsbb_all_zeros, _ARCH_PWR9]
+[VEC_TEST_LSBB_ALL_ZEROS, vec_test_lsbb_all_zeros, __builtin_vec_xvtlsbb_all_zeros]
   signed int __builtin_vec_xvtlsbb_all_zeros (vuc);
     XVTLSBB_ZEROS
 
@@ -4420,19 +4424,19 @@
   vui __builtin_vec_vunsignedo (vd);
     VEC_VUNSIGNEDO_V2DF
 
-[VEC_VEE, vec_extract_exp, __builtin_vec_extract_exp, _ARCH_PWR9]
+[VEC_VEE, vec_extract_exp, __builtin_vec_extract_exp]
   vui __builtin_vec_extract_exp (vf);
     VEESP
   vull __builtin_vec_extract_exp (vd);
     VEEDP
 
-[VEC_VES, vec_extract_sig, __builtin_vec_extract_sig, _ARCH_PWR9]
+[VEC_VES, vec_extract_sig, __builtin_vec_extract_sig]
   vui __builtin_vec_extract_sig (vf);
     VESSP
   vull __builtin_vec_extract_sig (vd);
     VESDP
 
-[VEC_VIE, vec_insert_exp, __builtin_vec_insert_exp, _ARCH_PWR9]
+[VEC_VIE, vec_insert_exp, __builtin_vec_insert_exp]
   vf __builtin_vec_insert_exp (vf, vui);
     VIESP  VIESP_VF
   vf __builtin_vec_insert_exp (vui, vui);
@@ -4444,7 +4448,7 @@
 
 ; It is truly unfortunate that vec_vprtyb has an incompatible set of
 ; interfaces with vec_parity_lsbb.  So we can't even deprecate this.
-[VEC_VPRTYB, vec_vprtyb, __builtin_vec_vprtyb, _ARCH_PWR9]
+[VEC_VPRTYB, vec_vprtyb, __builtin_vec_vprtyb]
   vsi __builtin_vec_vprtyb (vsi);
     VPRTYBW  VPRTYB_VSI
   vui __builtin_vec_vprtyb (vui);
@@ -4462,43 +4466,43 @@
   unsigned __int128 __builtin_vec_vprtyb (unsigned __int128);
     VPRTYBQ  VPRTYB_UQ
 
-[VEC_VSCEEQ, scalar_cmp_exp_eq, __builtin_vec_scalar_cmp_exp_eq, _ARCH_PWR9]
+[VEC_VSCEEQ, scalar_cmp_exp_eq, __builtin_vec_scalar_cmp_exp_eq]
   signed int __builtin_vec_scalar_cmp_exp_eq (double, double);
     VSCEDPEQ
   signed int __builtin_vec_scalar_cmp_exp_eq (_Float128, _Float128);
     VSCEQPEQ
 
-[VEC_VSCEGT, scalar_cmp_exp_gt, __builtin_vec_scalar_cmp_exp_gt, _ARCH_PWR9]
+[VEC_VSCEGT, scalar_cmp_exp_gt, __builtin_vec_scalar_cmp_exp_gt]
   signed int __builtin_vec_scalar_cmp_exp_gt (double, double);
     VSCEDPGT
   signed int __builtin_vec_scalar_cmp_exp_gt (_Float128, _Float128);
     VSCEQPGT
 
-[VEC_VSCELT, scalar_cmp_exp_lt, __builtin_vec_scalar_cmp_exp_lt, _ARCH_PWR9]
+[VEC_VSCELT, scalar_cmp_exp_lt, __builtin_vec_scalar_cmp_exp_lt]
   signed int __builtin_vec_scalar_cmp_exp_lt (double, double);
     VSCEDPLT
   signed int __builtin_vec_scalar_cmp_exp_lt (_Float128, _Float128);
     VSCEQPLT
 
-[VEC_VSCEUO, scalar_cmp_exp_unordered, __builtin_vec_scalar_cmp_exp_unordered, _ARCH_PWR9]
+[VEC_VSCEUO, scalar_cmp_exp_unordered, __builtin_vec_scalar_cmp_exp_unordered]
   signed int __builtin_vec_scalar_cmp_exp_unordered (double, double);
     VSCEDPUO
   signed int __builtin_vec_scalar_cmp_exp_unordered (_Float128, _Float128);
     VSCEQPUO
 
-[VEC_VSEE, scalar_extract_exp, __builtin_vec_scalar_extract_exp, _ARCH_PWR9]
+[VEC_VSEE, scalar_extract_exp, __builtin_vec_scalar_extract_exp]
   unsigned int __builtin_vec_scalar_extract_exp (double);
     VSEEDP
   unsigned int __builtin_vec_scalar_extract_exp (_Float128);
     VSEEQP
 
-[VEC_VSES, scalar_extract_sig, __builtin_vec_scalar_extract_sig, _ARCH_PWR9]
+[VEC_VSES, scalar_extract_sig, __builtin_vec_scalar_extract_sig]
   unsigned long long __builtin_vec_scalar_extract_sig (double);
     VSESDP
   unsigned __int128 __builtin_vec_scalar_extract_sig (_Float128);
     VSESQP
 
-[VEC_VSIE, scalar_insert_exp, __builtin_vec_scalar_insert_exp, _ARCH_PWR9]
+[VEC_VSIE, scalar_insert_exp, __builtin_vec_scalar_insert_exp]
   double __builtin_vec_scalar_insert_exp (unsigned long long, unsigned long long);
     VSIEDP
   double __builtin_vec_scalar_insert_exp (double, unsigned long long);
@@ -4508,7 +4512,7 @@
   _Float128 __builtin_vec_scalar_insert_exp (_Float128, unsigned long long);
     VSIEQPF
 
-[VEC_VSTDC, scalar_test_data_class, __builtin_vec_scalar_test_data_class, _ARCH_PWR9]
+[VEC_VSTDC, scalar_test_data_class, __builtin_vec_scalar_test_data_class]
   unsigned int __builtin_vec_scalar_test_data_class (float, const int);
     VSTDCSP
   unsigned int __builtin_vec_scalar_test_data_class (double, const int);
@@ -4516,7 +4520,7 @@
   unsigned int __builtin_vec_scalar_test_data_class (_Float128, const int);
     VSTDCQP
 
-[VEC_VSTDCN, scalar_test_neg, __builtin_vec_scalar_test_neg, _ARCH_PWR9]
+[VEC_VSTDCN, scalar_test_neg, __builtin_vec_scalar_test_neg]
   unsigned int __builtin_vec_scalar_test_neg (float);
     VSTDCNSP
   unsigned int __builtin_vec_scalar_test_neg (double);
@@ -4524,13 +4528,13 @@
   unsigned int __builtin_vec_scalar_test_neg (_Float128);
     VSTDCNQP
 
-[VEC_VTDC, vec_test_data_class, __builtin_vec_test_data_class, _ARCH_PWR9]
+[VEC_VTDC, vec_test_data_class, __builtin_vec_test_data_class]
   vbi __builtin_vec_test_data_class (vf, const int);
     VTDCSP
   vbll __builtin_vec_test_data_class (vd, const int);
     VTDCDP
 
-[VEC_XL, vec_xl, __builtin_vec_vsx_ld, __VSX__]
+[VEC_XL, vec_xl, __builtin_vec_vsx_ld]
   vsc __builtin_vec_vsx_ld (signed long long, const vsc *);
     LXVW4X_V16QI  LXVW4X_VSC
   vsc __builtin_vec_vsx_ld (signed long long, const signed char *);
@@ -4588,7 +4592,7 @@
   vd __builtin_vec_vsx_ld (signed long long, const double *);
     LXVD2X_V2DF  LXVD2X_D
 
-[VEC_XL_BE, vec_xl_be, __builtin_vec_xl_be, __VSX__]
+[VEC_XL_BE, vec_xl_be, __builtin_vec_xl_be]
   vsc __builtin_vec_xl_be (signed long long, const vsc *);
     LD_ELEMREV_V16QI  LD_ELEMREV_VSC
   vsc __builtin_vec_xl_be (signed long long, const signed char *);
@@ -4634,11 +4638,11 @@
   vd __builtin_vec_xl_be (signed long long, const double *);
     LD_ELEMREV_V2DF  LD_ELEMREV_DD
 
-[VEC_XL_LEN_R, vec_xl_len_r, __builtin_vec_xl_len_r, _ARCH_PPC64_PWR9]
+[VEC_XL_LEN_R, vec_xl_len_r, __builtin_vec_xl_len_r]
   vuc __builtin_vsx_xl_len_r (const unsigned char *, unsigned int);
     XL_LEN_R
 
-[VEC_XL_SEXT, vec_xl_sext, __builtin_vec_xl_sext, _ARCH_PWR10]
+[VEC_XL_SEXT, vec_xl_sext, __builtin_vec_xl_sext]
   vsq __builtin_vec_xl_sext (signed long long, const signed char *);
     SE_LXVRBX
   vsq __builtin_vec_xl_sext (signed long long, const signed short *);
@@ -4648,7 +4652,7 @@
   vsq __builtin_vec_xl_sext (signed long long, const signed long long *);
     SE_LXVRDX
 
-[VEC_XL_ZEXT, vec_xl_zext, __builtin_vec_xl_zext, _ARCH_PWR10]
+[VEC_XL_ZEXT, vec_xl_zext, __builtin_vec_xl_zext]
   vuq __builtin_vec_xl_zext (signed long long, const unsigned char *);
     ZE_LXVRBX
   vuq __builtin_vec_xl_zext (signed long long, const unsigned short *);
@@ -4733,7 +4737,7 @@
   vd __builtin_vec_xor (vbll, vd);
     VXOR_V2DF  VXOR_VBLL_VD
 
-[VEC_XST, vec_xst, __builtin_vec_vsx_st, __VSX__]
+[VEC_XST, vec_xst, __builtin_vec_vsx_st]
   void __builtin_vec_vsx_st (vsc, signed long long, vsc *);
     STXVW4X_V16QI  STXVW4X_VSC
   void __builtin_vec_vsx_st (vsc, signed long long, signed char *);
@@ -4801,7 +4805,7 @@
   void __builtin_vec_vsx_st (vd, signed long long, double *);
     STXVD2X_V2DF  STXVD2X_D
 
-[VEC_XST_BE, vec_xst_be, __builtin_vec_xst_be, __VSX__]
+[VEC_XST_BE, vec_xst_be, __builtin_vec_xst_be]
   void __builtin_vec_xst_be (vsc, signed long long, vsc *);
     ST_ELEMREV_V16QI  ST_ELEMREV_VSC
   void __builtin_vec_xst_be (vsc, signed long long, signed char *);
@@ -4847,11 +4851,11 @@
   void __builtin_vec_xst_be (vd, signed long long, double *);
     ST_ELEMREV_V2DF  ST_ELEMREV_D
 
-[VEC_XST_LEN_R, vec_xst_len_r, __builtin_vec_xst_len_r, _ARCH_PPC64_PWR9]
+[VEC_XST_LEN_R, vec_xst_len_r, __builtin_vec_xst_len_r]
   void __builtin_vsx_xst_len_r (vuc, unsigned char *, unsigned int);
     XST_LEN_R
 
-[VEC_XST_TRUNC, vec_xst_trunc, __builtin_vec_xst_trunc, _ARCH_PWR10]
+[VEC_XST_TRUNC, vec_xst_trunc, __builtin_vec_xst_trunc]
   void __builtin_vec_xst_trunc (vsq, signed long long, signed char *);
     TR_STXVRBX  TR_STXVRBX_S
   void __builtin_vec_xst_trunc (vuq, signed long long, unsigned char *);
@@ -4869,7 +4873,7 @@
   void __builtin_vec_xst_trunc (vuq, signed long long, unsigned long long *);
     TR_STXVRDX  TR_STXVRDX_U
 
-[VEC_XXPERMDI, vec_xxpermdi, __builtin_vsx_xxpermdi, __VSX__]
+[VEC_XXPERMDI, vec_xxpermdi, __builtin_vsx_xxpermdi]
   vsc __builtin_vsx_xxpermdi (vsc, vsc, const int);
     XXPERMDI_16QI  XXPERMDI_VSC
   vuc __builtin_vsx_xxpermdi (vuc, vuc, const int);
@@ -4891,7 +4895,7 @@
   vd __builtin_vsx_xxpermdi (vd, vd, const int);
     XXPERMDI_2DF  XXPERMDI_VD
 
-[VEC_XXSLDWI, vec_xxsldwi, __builtin_vsx_xxsldwi, __VSX__]
+[VEC_XXSLDWI, vec_xxsldwi, __builtin_vsx_xxsldwi]
   vsc __builtin_vsx_xxsldwi (vsc, vsc, const int);
     XXSLDWI_16QI  XXSLDWI_VSC2
   vuc __builtin_vsx_xxsldwi (vuc, vuc, const int);
@@ -4990,51 +4994,51 @@
   void __builtin_vec_stvewx (vui, signed long, void *);
     STVEWX  STVEWX_DEPR8
 
-[VEC_TSTSFI_EQ_DD, SKIP, __builtin_dfp_dtstsfi_eq_dd, _ARCH_PWR9]
+[VEC_TSTSFI_EQ_DD, SKIP, __builtin_dfp_dtstsfi_eq_dd]
   signed int __builtin_dfp_dtstsfi_eq_dd (const int, _Decimal64);
     TSTSFI_EQ_DD  TSTSFI_EQ_DD_DEPR1
 
-[VEC_TSTSFI_EQ_TD, SKIP, __builtin_dfp_dtstsfi_eq_td, _ARCH_PWR9]
+[VEC_TSTSFI_EQ_TD, SKIP, __builtin_dfp_dtstsfi_eq_td]
   signed int __builtin_dfp_dtstsfi_eq_td (const int, _Decimal128);
     TSTSFI_EQ_TD  TSTSFI_EQ_TD_DEPR1
 
-[VEC_TSTSFI_GT_DD, SKIP, __builtin_dfp_dtstsfi_gt_dd, _ARCH_PWR9]
+[VEC_TSTSFI_GT_DD, SKIP, __builtin_dfp_dtstsfi_gt_dd]
   signed int __builtin_dfp_dtstsfi_gt_dd (const int, _Decimal64);
     TSTSFI_GT_DD  TSTSFI_GT_DD_DEPR1
 
-[VEC_TSTSFI_GT_TD, SKIP, __builtin_dfp_dtstsfi_gt_td, _ARCH_PWR9]
+[VEC_TSTSFI_GT_TD, SKIP, __builtin_dfp_dtstsfi_gt_td]
   signed int __builtin_dfp_dtstsfi_gt_td (const int, _Decimal128);
     TSTSFI_GT_TD  TSTSFI_GT_TD_DEPR1
 
-[VEC_TSTSFI_LT_DD, SKIP, __builtin_dfp_dtstsfi_lt_dd, _ARCH_PWR9]
+[VEC_TSTSFI_LT_DD, SKIP, __builtin_dfp_dtstsfi_lt_dd]
   signed int __builtin_dfp_dtstsfi_lt_dd (const int, _Decimal64);
     TSTSFI_LT_DD  TSTSFI_LT_DD_DEPR1
 
-[VEC_TSTSFI_LT_TD, SKIP, __builtin_dfp_dtstsfi_lt_td, _ARCH_PWR9]
+[VEC_TSTSFI_LT_TD, SKIP, __builtin_dfp_dtstsfi_lt_td]
   signed int __builtin_dfp_dtstsfi_lt_td (const int, _Decimal128);
     TSTSFI_LT_TD  TSTSFI_LT_TD_DEPR1
 
-[VEC_TSTSFI_OV_DD, SKIP, __builtin_dfp_dtstsfi_ov_dd, _ARCH_PWR9]
+[VEC_TSTSFI_OV_DD, SKIP, __builtin_dfp_dtstsfi_ov_dd]
   signed int __builtin_dfp_dtstsfi_ov_dd (const int, _Decimal64);
     TSTSFI_OV_DD  TSTSFI_OV_DD_DEPR1
 
-[VEC_TSTSFI_OV_TD, SKIP, __builtin_dfp_dtstsfi_ov_td, _ARCH_PWR9]
+[VEC_TSTSFI_OV_TD, SKIP, __builtin_dfp_dtstsfi_ov_td]
   signed int __builtin_dfp_dtstsfi_ov_td (const int, _Decimal128);
     TSTSFI_OV_TD  TSTSFI_OV_TD_DEPR1
 
-[VEC_VADDCUQ, vec_vaddcuq, __builtin_vec_vaddcuq, _ARCH_PWR8]
+[VEC_VADDCUQ, vec_vaddcuq, __builtin_vec_vaddcuq]
   vsq __builtin_vec_vaddcuq (vsq, vsq);
     VADDCUQ  VADDCUQ_DEPR1
   vuq __builtin_vec_vaddcuq (vuq, vuq);
     VADDCUQ  VADDCUQ_DEPR2
 
-[VEC_VADDECUQ, vec_vaddecuq, __builtin_vec_vaddecuq, _ARCH_PWR8]
+[VEC_VADDECUQ, vec_vaddecuq, __builtin_vec_vaddecuq]
   vsq __builtin_vec_vaddecuq (vsq, vsq, vsq);
     VADDECUQ  VADDECUQ_DEPR1
   vuq __builtin_vec_vaddecuq (vuq, vuq, vuq);
     VADDECUQ  VADDECUQ_DEPR2
 
-[VEC_VADDEUQM, vec_vaddeuqm, __builtin_vec_vaddeuqm, _ARCH_PWR8]
+[VEC_VADDEUQM, vec_vaddeuqm, __builtin_vec_vaddeuqm]
   vsq __builtin_vec_vaddeuqm (vsq, vsq, vsq);
     VADDEUQM  VADDEUQM_DEPR1
   vuq __builtin_vec_vaddeuqm (vuq, vuq, vuq);
@@ -5098,7 +5102,7 @@
   vuc __builtin_vec_vaddubs (vuc, vbc);
     VADDUBS  VADDUBS_DEPR5
 
-[VEC_VADDUDM, vec_vaddudm, __builtin_vec_vaddudm, _ARCH_PWR8]
+[VEC_VADDUDM, vec_vaddudm, __builtin_vec_vaddudm]
   vsll __builtin_vec_vaddudm (vbll, vsll);
     VADDUDM  VADDUDM_DEPR1
   vsll __builtin_vec_vaddudm (vsll, vbll);
@@ -5142,7 +5146,7 @@
   vus __builtin_vec_vadduhs (vus, vbs);
     VADDUHS  VADDUHS_DEPR5
 
-[VEC_VADDUQM, vec_vadduqm, __builtin_vec_vadduqm, _ARCH_PWR8]
+[VEC_VADDUQM, vec_vadduqm, __builtin_vec_vadduqm]
   vsq __builtin_vec_vadduqm (vsq, vsq);
     VADDUQM  VADDUQM_DEPR1
   vuq __builtin_vec_vadduqm (vuq, vuq);
@@ -5214,7 +5218,7 @@
   vui __builtin_vec_vavguw (vui, vui);
     VAVGUW  VAVGUW_DEPR1
 
-[VEC_VBPERMQ, vec_vbpermq, __builtin_vec_vbpermq, _ARCH_PWR8]
+[VEC_VBPERMQ, vec_vbpermq, __builtin_vec_vbpermq]
   vull __builtin_vec_vbpermq (vull, vuc);
     VBPERMQ  VBPERMQ_DEPR1
   vsll __builtin_vec_vbpermq (vsc, vsc);
@@ -5232,25 +5236,25 @@
   vf __builtin_vec_vcfux (vui, const int);
     VCFUX  VCFUX_DEPR1
 
-[VEC_VCLZB, vec_vclzb, __builtin_vec_vclzb, _ARCH_PWR8]
+[VEC_VCLZB, vec_vclzb, __builtin_vec_vclzb]
   vsc __builtin_vec_vclzb (vsc);
     VCLZB  VCLZB_DEPR1
   vuc __builtin_vec_vclzb (vuc);
     VCLZB  VCLZB_DEPR2
 
-[VEC_VCLZD, vec_vclzd, __builtin_vec_vclzd, _ARCH_PWR8]
+[VEC_VCLZD, vec_vclzd, __builtin_vec_vclzd]
   vsll __builtin_vec_vclzd (vsll);
     VCLZD  VCLZD_DEPR1
   vull __builtin_vec_vclzd (vull);
     VCLZD  VCLZD_DEPR2
 
-[VEC_VCLZH, vec_vclzh, __builtin_vec_vclzh, _ARCH_PWR8]
+[VEC_VCLZH, vec_vclzh, __builtin_vec_vclzh]
   vss __builtin_vec_vclzh (vss);
     VCLZH  VCLZH_DEPR1
   vus __builtin_vec_vclzh (vus);
     VCLZH  VCLZH_DEPR2
 
-[VEC_VCLZW, vec_vclzw, __builtin_vec_vclzw, _ARCH_PWR8]
+[VEC_VCLZW, vec_vclzw, __builtin_vec_vclzw]
   vsi __builtin_vec_vclzw (vsi);
     VCLZW  VCLZW_DEPR1
   vui __builtin_vec_vclzw (vui);
@@ -5306,53 +5310,53 @@
   vbi __builtin_vec_vcmpgtuw (vui, vui);
     VCMPGTUW  VCMPGTUW_DEPR1
 
-[VEC_VCTZB, vec_vctzb, __builtin_vec_vctzb, _ARCH_PWR9]
+[VEC_VCTZB, vec_vctzb, __builtin_vec_vctzb]
   vsc __builtin_vec_vctzb (vsc);
     VCTZB  VCTZB_DEPR1
   vuc __builtin_vec_vctzb (vuc);
     VCTZB  VCTZB_DEPR2
 
-[VEC_VCTZD, vec_vctzd, __builtin_vec_vctzd, _ARCH_PWR9]
+[VEC_VCTZD, vec_vctzd, __builtin_vec_vctzd]
   vsll __builtin_vec_vctzd (vsll);
     VCTZD  VCTZD_DEPR1
   vull __builtin_vec_vctzd (vull);
     VCTZD  VCTZD_DEPR2
 
-[VEC_VCTZH, vec_vctzh, __builtin_vec_vctzh, _ARCH_PWR9]
+[VEC_VCTZH, vec_vctzh, __builtin_vec_vctzh]
   vss __builtin_vec_vctzh (vss);
     VCTZH  VCTZH_DEPR1
   vus __builtin_vec_vctzh (vus);
     VCTZH  VCTZH_DEPR2
 
-[VEC_VCTZW, vec_vctzw, __builtin_vec_vctzw, _ARCH_PWR9]
+[VEC_VCTZW, vec_vctzw, __builtin_vec_vctzw]
   vsi __builtin_vec_vctzw (vsi);
     VCTZW  VCTZW_DEPR1
   vui __builtin_vec_vctzw (vui);
     VCTZW  VCTZW_DEPR2
 
-[VEC_VEEDP, vec_extract_exp_dp, __builtin_vec_extract_exp_dp, _ARCH_PWR9]
+[VEC_VEEDP, vec_extract_exp_dp, __builtin_vec_extract_exp_dp]
   vull __builtin_vec_extract_exp_dp (vd);
     VEEDP  VEEDP_DEPR1
 
-[VEC_VEESP, vec_extract_exp_sp, __builtin_vec_extract_exp_sp, _ARCH_PWR9]
+[VEC_VEESP, vec_extract_exp_sp, __builtin_vec_extract_exp_sp]
   vui __builtin_vec_extract_exp_sp (vf);
     VEESP  VEESP_DEPR1
 
-[VEC_VESDP, vec_extract_sig_dp, __builtin_vec_extract_sig_dp, _ARCH_PWR9]
+[VEC_VESDP, vec_extract_sig_dp, __builtin_vec_extract_sig_dp]
   vull __builtin_vec_extract_sig_dp (vd);
     VESDP  VESDP_DEPR1
 
-[VEC_VESSP, vec_extract_sig_sp, __builtin_vec_extract_sig_sp, _ARCH_PWR9]
+[VEC_VESSP, vec_extract_sig_sp, __builtin_vec_extract_sig_sp]
   vui __builtin_vec_extract_sig_sp (vf);
     VESSP  VESSP_DEPR1
 
-[VEC_VIEDP, vec_insert_exp_dp, __builtin_vec_insert_exp_dp, _ARCH_PWR9]
+[VEC_VIEDP, vec_insert_exp_dp, __builtin_vec_insert_exp_dp]
   vd __builtin_vec_insert_exp_dp (vd, vull);
     VIEDP  VIEDP_DEPR1
   vd __builtin_vec_insert_exp_dp (vull, vull);
     VIEDP  VIEDP_DEPR2
 
-[VEC_VIESP, vec_insert_exp_sp, __builtin_vec_insert_exp_sp, _ARCH_PWR9]
+[VEC_VIESP, vec_insert_exp_sp, __builtin_vec_insert_exp_sp]
   vf __builtin_vec_insert_exp_sp (vf, vui);
     VIESP  VIESP_DEPR1
   vf __builtin_vec_insert_exp_sp (vui, vui);
@@ -5650,11 +5654,11 @@
   vull __builtin_vec_vmulouw (vui, vui);
     VMULOUW  VMULOUW_DEPR1
 
-[VEC_VPKSDSS, vec_vpksdss, __builtin_vec_vpksdss, _ARCH_PWR8]
+[VEC_VPKSDSS, vec_vpksdss, __builtin_vec_vpksdss]
   vsi __builtin_vec_vpksdss (vsll, vsll);
     VPKSDSS  VPKSDSS_DEPR1
 
-[VEC_VPKSDUS, vec_vpksdus, __builtin_vec_vpksdus, _ARCH_PWR8]
+[VEC_VPKSDUS, vec_vpksdus, __builtin_vec_vpksdus]
   vui __builtin_vec_vpksdus (vsll, vsll);
     VPKSDUS  VPKSDUS_DEPR1
 
@@ -5674,7 +5678,7 @@
   vus __builtin_vec_vpkswus (vsi, vsi);
     VPKSWUS  VPKSWUS_DEPR1
 
-[VEC_VPKUDUM, vec_vpkudum, __builtin_vec_vpkudum, _ARCH_PWR8]
+[VEC_VPKUDUM, vec_vpkudum, __builtin_vec_vpkudum]
   vsi __builtin_vec_vpkudum (vsll, vsll);
     VPKUDUM  VPKUDUM_DEPR1
   vui __builtin_vec_vpkudum (vull, vull);
@@ -5682,7 +5686,7 @@
   vbi __builtin_vec_vpkudum (vbll, vbll);
     VPKUDUM  VPKUDUM_DEPR3
 
-[VEC_VPKUDUS, vec_vpkudus, __builtin_vec_vpkudus, _ARCH_PWR8]
+[VEC_VPKUDUS, vec_vpkudus, __builtin_vec_vpkudus]
   vui __builtin_vec_vpkudus (vull, vull);
     VPKUDUS  VPKUDUS_DEPR1
 
@@ -5710,7 +5714,7 @@
   vus __builtin_vec_vpkuwus (vui, vui);
     VPKUWUS  VPKUWUS_DEPR1
 
-[VEC_VPOPCNT, vec_vpopcnt, __builtin_vec_vpopcnt, _ARCH_PWR8]
+[VEC_VPOPCNT, vec_vpopcnt, __builtin_vec_vpopcnt]
   vsc __builtin_vec_vpopcnt (vsc);
     VPOPCNTB  VPOPCNT_DEPR1
   vuc __builtin_vec_vpopcnt (vuc);
@@ -5728,37 +5732,37 @@
   vull __builtin_vec_vpopcnt (vull);
     VPOPCNTD  VPOPCNT_DEPR8
 
-[VEC_VPOPCNTB, vec_vpopcntb, __builtin_vec_vpopcntb, _ARCH_PWR8]
+[VEC_VPOPCNTB, vec_vpopcntb, __builtin_vec_vpopcntb]
   vsc __builtin_vec_vpopcntb (vsc);
     VPOPCNTB  VPOPCNTB_DEPR1
   vuc __builtin_vec_vpopcntb (vuc);
     VPOPCNTB  VPOPCNTB_DEPR2
 
-[VEC_VPOPCNTD, vec_vpopcntd, __builtin_vec_vpopcntd, _ARCH_PWR8]
+[VEC_VPOPCNTD, vec_vpopcntd, __builtin_vec_vpopcntd]
   vsll __builtin_vec_vpopcntd (vsll);
     VPOPCNTD  VPOPCNTD_DEPR1
   vull __builtin_vec_vpopcntd (vull);
     VPOPCNTD  VPOPCNTD_DEPR2
 
-[VEC_VPOPCNTH, vec_vpopcnth, __builtin_vec_vpopcnth, _ARCH_PWR8]
+[VEC_VPOPCNTH, vec_vpopcnth, __builtin_vec_vpopcnth]
   vss __builtin_vec_vpopcnth (vss);
     VPOPCNTH  VPOPCNTH_DEPR1
   vus __builtin_vec_vpopcnth (vus);
     VPOPCNTH  VPOPCNTH_DEPR2
 
-[VEC_VPOPCNTW, vec_vpopcntw, __builtin_vec_vpopcntw, _ARCH_PWR8]
+[VEC_VPOPCNTW, vec_vpopcntw, __builtin_vec_vpopcntw]
   vsi __builtin_vec_vpopcntw (vsi);
     VPOPCNTW  VPOPCNTW_DEPR1
   vui __builtin_vec_vpopcntw (vui);
     VPOPCNTW  VPOPCNTW_DEPR2
 
-[VEC_VPRTYBD, vec_vprtybd, __builtin_vec_vprtybd, _ARCH_PWR9]
+[VEC_VPRTYBD, vec_vprtybd, __builtin_vec_vprtybd]
   vsll __builtin_vec_vprtybd (vsll);
     VPRTYBD  VPRTYBD_DEPR1
   vull __builtin_vec_vprtybd (vull);
     VPRTYBD  VPRTYBD_DEPR2
 
-[VEC_VPRTYBQ, vec_vprtybq, __builtin_vec_vprtybq, _ARCH_PPC64_PWR9]
+[VEC_VPRTYBQ, vec_vprtybq, __builtin_vec_vprtybq]
   vsq __builtin_vec_vprtybq (vsq);
     VPRTYBQ  VPRTYBQ_DEPR1
   vuq __builtin_vec_vprtybq (vuq);
@@ -5768,7 +5772,7 @@
   unsigned __int128 __builtin_vec_vprtybq (unsigned __int128);
     VPRTYBQ  VPRTYBQ_DEPR4
 
-[VEC_VPRTYBW, vec_vprtybw, __builtin_vec_vprtybw, _ARCH_PWR9]
+[VEC_VPRTYBW, vec_vprtybw, __builtin_vec_vprtybw]
   vsi __builtin_vec_vprtybw (vsi);
     VPRTYBW  VPRTYBW_DEPR1
   vui __builtin_vec_vprtybw (vui);
@@ -5780,7 +5784,7 @@
   vuc __builtin_vec_vrlb (vuc, vuc);
     VRLB  VRLB_DEPR2
 
-[VEC_VRLD, SKIP, __builtin_vec_vrld, _ARCH_PWR8]
+[VEC_VRLD, SKIP, __builtin_vec_vrld]
   vsll __builtin_vec_vrld (vsll, vull);
     VRLD  VRLD_DEPR1
   vull __builtin_vec_vrld (vull, vull);
@@ -5804,7 +5808,7 @@
   vuc __builtin_vec_vslb (vuc, vuc);
     VSLB  VSLB_DEPR2
 
-[VEC_VSLD, SKIP, __builtin_vec_vsld, _ARCH_PWR8]
+[VEC_VSLD, SKIP, __builtin_vec_vsld]
   vsll __builtin_vec_vsld (vsll, vull);
     VSLD  VSLD_DEPR1
   vull __builtin_vec_vsld (vull, vull);
@@ -5856,7 +5860,7 @@
   vuc __builtin_vec_vsrab (vuc, vuc);
     VSRAB  VSRAB_DEPR2
 
-[VEC_VSRAD, SKIP, __builtin_vec_vsrad, _ARCH_PWR8]
+[VEC_VSRAD, SKIP, __builtin_vec_vsrad]
   vsll __builtin_vec_vsrad (vsll, vull);
     VSRAD  VSRAD_DEPR1
   vull __builtin_vec_vsrad (vull, vull);
@@ -5880,7 +5884,7 @@
   vuc __builtin_vec_vsrb (vuc, vuc);
     VSRB  VSRB_DEPR2
 
-[VEC_VSRD, SKIP, __builtin_vec_vsrd, _ARCH_PWR8]
+[VEC_VSRD, SKIP, __builtin_vec_vsrd]
   vsll __builtin_vec_vsrd (vsll, vull);
     VSRD  VSRD_DEPR1
   vull __builtin_vec_vsrd (vull, vull);
@@ -5898,27 +5902,27 @@
   vui __builtin_vec_vsrw (vui, vui);
     VSRW  VSRW_DEPR2
 
-[VEC_VSTDCDP, scalar_test_data_class_dp, __builtin_vec_scalar_test_data_class_dp, _ARCH_PWR9]
+[VEC_VSTDCDP, scalar_test_data_class_dp, __builtin_vec_scalar_test_data_class_dp]
   unsigned int __builtin_vec_scalar_test_data_class_dp (double, const int);
     VSTDCDP  VSTDCDP_DEPR1
 
-[VEC_VSTDCNDP, scalar_test_neg_dp, __builtin_vec_scalar_test_neg_dp, _ARCH_PWR9]
+[VEC_VSTDCNDP, scalar_test_neg_dp, __builtin_vec_scalar_test_neg_dp]
   unsigned int __builtin_vec_scalar_test_neg_dp (double);
     VSTDCNDP  VSTDCNDP_DEPR1
 
-[VEC_VSTDCNQP, scalar_test_neg_qp, __builtin_vec_scalar_test_neg_qp, _ARCH_PWR9]
+[VEC_VSTDCNQP, scalar_test_neg_qp, __builtin_vec_scalar_test_neg_qp]
   unsigned int __builtin_vec_scalar_test_neg_qp (_Float128);
     VSTDCNQP  VSTDCNQP_DEPR1
 
-[VEC_VSTDCNSP, scalar_test_neg_sp, __builtin_vec_scalar_test_neg_sp, _ARCH_PWR9]
+[VEC_VSTDCNSP, scalar_test_neg_sp, __builtin_vec_scalar_test_neg_sp]
   unsigned int __builtin_vec_scalar_test_neg_sp (float);
     VSTDCNSP  VSTDCNSP_DEPR1
 
-[VEC_VSTDCQP, scalar_test_data_class_qp, __builtin_vec_scalar_test_data_class_qp, _ARCH_PWR9]
+[VEC_VSTDCQP, scalar_test_data_class_qp, __builtin_vec_scalar_test_data_class_qp]
   unsigned int __builtin_vec_scalar_test_data_class_qp (_Float128, const int);
     VSTDCQP  VSTDCQP_DEPR1
 
-[VEC_VSTDCSP, scalar_test_data_class_sp, __builtin_vec_scalar_test_data_class_sp, _ARCH_PWR9]
+[VEC_VSTDCSP, scalar_test_data_class_sp, __builtin_vec_scalar_test_data_class_sp]
   unsigned int __builtin_vec_scalar_test_data_class_sp (float, const int);
     VSTDCSP  VSTDCSP_DEPR1
 
@@ -5928,13 +5932,13 @@
   vuq __builtin_vec_vsubcuq (vuq, vuq);
     VSUBCUQ  VSUBCUQ_DEPR2
 
-[VEC_VSUBECUQ, vec_vsubecuq, __builtin_vec_vsubecuq, ARCH_PWR8]
+[VEC_VSUBECUQ, vec_vsubecuq, __builtin_vec_vsubecuq]
   vsq __builtin_vec_vsubecuq (vsq, vsq, vsq);
     VSUBECUQ  VSUBECUQ_DEPR1
   vuq __builtin_vec_vsubecuq (vuq, vuq, vuq);
     VSUBECUQ  VSUBECUQ_DEPR2
 
-[VEC_VSUBEUQM, vec_vsubeuqm, __builtin_vec_vsubeuqm, _ARCH_PWR8]
+[VEC_VSUBEUQM, vec_vsubeuqm, __builtin_vec_vsubeuqm]
   vsq __builtin_vec_vsubeuqm (vsq, vsq, vsq);
     VSUBEUQM  VSUBEUQM_DEPR1
   vuq __builtin_vec_vsubeuqm (vuq, vuq, vuq);
@@ -6004,7 +6008,7 @@
   vuc __builtin_vec_vsububs (vuc, vbc);
     VSUBUBS  VSUBUBS_DEPR8
 
-[VEC_VSUBUDM, vec_vsubudm, __builtin_vec_vsubudm, _ARCH_PWR8]
+[VEC_VSUBUDM, vec_vsubudm, __builtin_vec_vsubudm]
   vsll __builtin_vec_vsubudm (vbll, vsll);
     VSUBUDM  VSUBUDM_DEPR1
   vsll __builtin_vec_vsubudm (vsll, vbll);
@@ -6048,7 +6052,7 @@
   vus __builtin_vec_vsubuhs (vus, vbs);
     VSUBUHS  VSUBUHS_DEPR5
 
-[VEC_VSUBUQM, vec_vsubuqm, __builtin_vec_vsubuqm, _ARCH_PWR8]
+[VEC_VSUBUQM, vec_vsubuqm, __builtin_vec_vsubuqm]
   vsq __builtin_vec_vsubuqm (vsq, vsq);
     VSUBUQM  VSUBUQM_DEPR1
   vuq __builtin_vec_vsubuqm (vuq, vuq);
@@ -6096,11 +6100,11 @@
   vui __builtin_vec_vsum4ubs (vuc, vui);
     VSUM4UBS  VSUM4UBS_DEPR1
 
-[VEC_VTDCDP, vec_test_data_class_dp, __builtin_vec_test_data_class_dp, _ARCH_PWR9]
+[VEC_VTDCDP, vec_test_data_class_dp, __builtin_vec_test_data_class_dp]
   vbll __builtin_vec_test_data_class_dp (vd, const int);
     VTDCDP  VTDCDP_DEPR1
 
-[VEC_VTDCSP, vec_test_data_class_sp, __builtin_vec_test_data_class_sp, _ARCH_PWR9]
+[VEC_VTDCSP, vec_test_data_class_sp, __builtin_vec_test_data_class_sp]
   vbi __builtin_vec_test_data_class_sp (vf, const int);
     VTDCSP  VTDCSP_DEPR1
 
@@ -6138,7 +6142,7 @@
   vbi __builtin_vec_vupkhsh (vbs);
     VUPKHSH  VUPKHSH_DEPR2
 
-[VEC_VUPKHSW, vec_vupkhsw, __builtin_vec_vupkhsw, _ARCH_PWR8]
+[VEC_VUPKHSW, vec_vupkhsw, __builtin_vec_vupkhsw]
   vsll __builtin_vec_vupkhsw (vsi);
     VUPKHSW  VUPKHSW_DEPR1
   vbll __builtin_vec_vupkhsw (vbi);
@@ -6162,7 +6166,7 @@
   vbi __builtin_vec_vupklsh (vbs);
     VUPKLSH  VUPKLSH_DEPR2
 
-[VEC_VUPKLSW, vec_vupklsw, __builtin_vec_vupklsw, _ARCH_PWR8]
+[VEC_VUPKLSW, vec_vupklsw, __builtin_vec_vupklsw]
   vsll __builtin_vec_vupklsw (vsi);
     VUPKLSW  VUPKLSW_DEPR1
   vbll __builtin_vec_vupklsw (vbi);
-- 
2.27.0


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

* [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
  2022-01-28 17:50 ` [PATCH 1/8] rs6000: More factoring of overload processing Bill Schmidt
  2022-01-28 17:50 ` [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-01-28 23:24   ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 4/8] rs6000: Consolidate target built-ins code Bill Schmidt
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

When introducing the new built-in support, I tried to match as many
existing error messages as possible.  One common form was "argument X must
be a Y-bit unsigned literal".  Another was "argument X must be a literal
between X' and  Y', inclusive".  During reviews, Segher requested that I
eventually convert all messages of the first form into the second form for
consistency.  That's what this patch does, replacing all <x>-form
constraints (first form) with <x,y>-form constraints (second form).

For the moment, the parser will still accept <x> arguments, but I've added
a note in rs6000-builtins.def that this form is deprecated in favor of
<x,y>.  I think it's harmless to leave it in, in case a desire for the
distinction comes up in the future.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-12  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-builtins.def (MTFSB0): Replace <x>-form
	constraints with <x,y>-form constraints.
	(MTFSB1): Likewise.
	(MTFSF): Likewise.
	(UNPACK_IF): Likewise.
	(UNPACK_TF): Likewise.
	(DSS): Likewise.
	(DST): Likewise.
	(DSTST): Likewise.
	(DSTSTT): Likewise.
	(DSTT): Likewise.
	(VCFSX): Likewise.
	(VCFUX): Likewise.
	(VCTSXS): Likewise.
	(VCTUXS): Likewise.
	(VSLDOI_16QI): Likewise.
	(VSLDOI_4SF): Likewise.
	(VSLDOI_4SI): Likewise.
	(VSLDOI_8HI): Likewise.
	(VSPLTB): Likewise.
	(VSPLTH): Likewise.
	(VSPLTW): Likewise.
	(VEC_SET_V16QI): Likewise.
	(VEC_SET_V4SF): Likewise.
	(VEC_SET_V4SI): Likewise.
	(VEC_SET_V8HI): Likewise.
	(VSLDOI_2DF): Likewise.
	(VSLDOI_2DI): Likewise.
	(VEC_SET_V2DF): Likewise.
	(VEC_SET_V2DI): Likewise.
	(XVCVSXDDP_SCALE): Likewise.
	(XVCVUXDDP_SCALE): Likewise.
	(XXPERMDI_16QI): Likewise.
	(XXPERMDI_1TI): Likewise.
	(XXPERMDI_2DF): Likewise.
	(XXPERMDI_2DI): Likewise.
	(XXPERMDI_4SF): Likewise.
	(XXPERMDI_4SI): Likewise.
	(XXPERMDI_8HI): Likewise.
	(XXSLDWI_16QI): Likewise.
	(XXSLDWI_2DF): Likewise.
	(XXSLDWI_2DI): Likewise.
	(XXSLDWI_4SF): Likewise.
	(XXSLDWI_4SI): Likewise.
	(XXSLDWI_8HI): Likewise.
	(XXSPLTD_V2DF): Likewise.
	(XXSPLTD_V2DI): Likewise.
	(UNPACK_V1TI): Likewise.
	(BCDADD_V1TI): Likewise.
	(BCDADD_V16QI): Likewise.
	(BCDADD_EQ_V1TI): Likewise.
	(BCDADD_EQ_V16QI): Likewise.
	(BCDADD_GT_V1TI): Likewise.
	(BCDADD_GT_V16QI): Likewise.
	(BCDADD_LT_V1TI): Likewise.
	(BCDADD_LT_V16QI): Likewise.
	(BCDADD_OV_V1TI): Likewise.
	(BCDADD_OV_V16QI): Likewise.
	(BCDSUB_V1TI): Likewise.
	(BCDSUB_V16QI): Likewise.
	(BCDSUB_EQ_V1TI): Likewise.
	(BCDSUB_EQ_V16QI): Likewise.
	(BCDSUB_GT_V1TI): Likewise.
	(BCDSUB_GT_V16QI): Likewise.
	(BCDSUB_LT_V1TI): Likewise.
	(BCDSUB_LT_V16QI): Likewise.
	(BCDSUB_OV_V1TI): Likewise.
	(BCDSUB_OV_V16QI): Likewise.
	(VSTDCDP): Likewise.
	(VSTDCSP): Likewise.
	(VTDCDP): Likewise.
	(VTDCSP): Likewise.
	(TSTSFI_EQ_DD): Likewise.
	(TSTSFI_EQ_TD): Likewise.
	(TSTSFI_GT_DD): Likewise.
	(TSTSFI_GT_TD): Likewise.
	(TSTSFI_LT_DD): Likewise.
	(TSTSFI_LT_TD): Likewise.
	(TSTSFI_OV_DD): Likewise.
	(TSTSFI_OV_TD): Likewise.
	(VSTDCQP): Likewise.
	(DDEDPD): Likewise.
	(DDEDPDQ): Likewise.
	(DENBCD): Likewise.
	(DENBCDQ): Likewise.
	(DSCLI): Likewise.
	(DSCLIQ): Likewise.
	(DSCRI): Likewise.
	(DSCRIQ): Likewise.
	(UNPACK_TD): Likewise.
	(VSHASIGMAD): Likewise.
	(VSHASIGMAW): Likewise.
	(VCNTMBB): Likewise.
	(VCNTMBD): Likewise.
	(VCNTMBH): Likewise.
	(VCNTMBW): Likewise.
	(VREPLACE_UN_UV2DI): Likewise.
	(VREPLACE_UN_UV4SI): Likewise.
	(VREPLACE_UN_V2DF): Likewise.
	(VREPLACE_UN_V2DI): Likewise.
	(VREPLACE_UN_V4SF): Likewise.
	(VREPLACE_UN_V4SI): Likewise.
	(VREPLACE_ELT_UV2DI): Likewise.
	(VREPLACE_ELT_UV4SI): Likewise.
	(VREPLACE_ELT_V2DF): Likewise.
	(VREPLACE_ELT_V2DI): Likewise.
	(VREPLACE_ELT_V4SF): Likewise.
	(VREPLACE_ELT_V4SI): Likewise.
	(VSLDB_V16QI): Likewise.
	(VSLDB_V2DI): Likewise.
	(VSLDB_V4SI): Likewise.
	(VSLDB_V8HI): Likewise.
	(VSRDB_V16QI): Likewise.
	(VSRDB_V2DI): Likewise.
	(VSRDB_V4SI): Likewise.
	(VSRDB_V8HI): Likewise.
	(VXXSPLTI32DX_V4SF): Likewise.
	(VXXSPLTI32DX_V4SI): Likewise.
	(XXEVAL): Likewise.
	(XXGENPCVM_V16QI): Likewise.
	(XXGENPCVM_V2DI): Likewise.
	(XXGENPCVM_V4SI): Likewise.
	(XXGENPCVM_V8HI): Likewise.
	(XXPERMX_UV16QI): Likewise.
	(XXPERMX_UV2DI): Likewise.
	(XXPERMX_UV4SI): Likewise.
	(XXPERMX_UV8HI): Likewise.
	(XXPERMX_V16QI): Likewise.
	(XXPERMX_V2DF): Likewise.
	(XXPERMX_V2DI): Likewise.
	(XXPERMX_V4SF): Likewise.
	(XXPERMX_V4SI): Likewise.
	(XXPERMX_V8HI): Likewise.
	(DISASSEMBLE_ACC_INTERNAL): Likewise.
	(DISASSEMBLE_PAIR_INTERNAL): Likewise.
	(PMXVBF16GER2): Likewise.
	(PMXVBF16GER2_INTERNAL): Likewise.
	(PMXVBF16GER2NN): Likewise.
	(PMXVBF16GER2NN_INTERNAL): Likewise.
	(PMXVBF16GER2NP): Likewise.
	(PMXVBF16GER2NP_INTERNAL): Likewise.
	(PMXVBF16GER2PN): Likewise.
	(PMXVBF16GER2PN_INTERNAL): Likewise.
	(PMXVBF16GER2PP): Likewise.
	(PMXVBF16GER2PP_INTERNAL): Likewise.
	(PMXVF16GER2): Likewise.
	(PMXVF16GER2_INTERNAL): Likewise.
	(PMXVF16GER2NN): Likewise.
	(PMXVF16GER2NN_INTERNAL): Likewise.
	(PMXVF16GER2NP): Likewise.
	(PMXVF16GER2NP_INTERNAL): Likewise.
	(PMXVF16GER2PN): Likewise.
	(PMXVF16GER2PN_INTERNAL): Likewise.
	(PMXVF16GER2PP): Likewise.
	(PMXVF16GER2PP_INTERNAL): Likewise.
	(PMXVF32GER): Likewise.
	(PMXVF32GER_INTERNAL): Likewise.
	(PMXVF32GERNN): Likewise.
	(PMXVF32GERNN_INTERNAL): Likewise.
	(PMXVF32GERNP): Likewise.
	(PMXVF32GERNP_INTERNAL): Likewise.
	(PMXVF32GERPN): Likewise.
	(PMXVF32GERPN_INTERNAL): Likewise.
	(PMXVF32GERPP): Likewise.
	(PMXVF32GERPP_INTERNAL): Likewise.
	(PMXVF64GER): Likewise.
	(PMXVF64GER_INTERNAL): Likewise.
	(PMXVF64GERNN): Likewise.
	(PMXVF64GERNN_INTERNAL): Likewise.
	(PMXVF64GERNP): Likewise.
	(PMXVF64GERNP_INTERNAL): Likewise.
	(PMXVF64GERPN): Likewise.
	(PMXVF64GERPN_INTERNAL): Likewise.
	(PMXVF64GERPP): Likewise.
	(PMXVF64GERPP_INTERNAL): Likewise.
	(PMXVI16GER2): Likewise.
	(PMXVI16GER2_INTERNAL): Likewise.
	(PMXVI16GER2PP): Likewise.
	(PMXVI16GER2PP_INTERNAL): Likewise.
	(PMXVI16GER2S): Likewise.
	(PMXVI16GER2S_INTERNAL): Likewise.
	(PMXVI16GER2SPP): Likewise.
	(PMXVI16GER2SPP_INTERNAL): Likewise.
	(PMXVI4GER8): Likewise.
	(PMXVI4GER8_INTERNAL): Likewise.
	(PMXVI4GER8PP): Likewise.
	(PMXVI4GER8PP_INTERNAL): Likewise.
	(PMXVI8GER4): Likewise.
	(PMXVI8GER4_INTERNAL): Likewise.
	(PMXVI8GER4PP): Likewise.
	(PMXVI8GER4PP_INTERNAL): Likewise.
	(PMXVI8GER4SPP): Likewise.
	(PMXVI8GER4SPP_INTERNAL): Likewise.
	(DISASSEMBLE_PAIR_V_INTERNAL): Likewise.

gcc/testsuite/
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c:
	Adjust error messages.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-1.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-2.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-3.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-4.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr82015.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr91903.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c: Likewise.
---
 gcc/config/rs6000/rs6000-builtins.def         | 520 +++++++++---------
 .../powerpc/bfp/scalar-test-data-class-10.c   |   2 +-
 .../powerpc/bfp/scalar-test-data-class-2.c    |   2 +-
 .../powerpc/bfp/scalar-test-data-class-3.c    |   2 +-
 .../powerpc/bfp/scalar-test-data-class-4.c    |   2 +-
 .../powerpc/bfp/scalar-test-data-class-5.c    |   2 +-
 .../powerpc/bfp/scalar-test-data-class-9.c    |   2 +-
 .../powerpc/bfp/vec-test-data-class-4.c       |   2 +-
 .../powerpc/bfp/vec-test-data-class-5.c       |   2 +-
 .../powerpc/bfp/vec-test-data-class-6.c       |   2 +-
 .../powerpc/bfp/vec-test-data-class-7.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-12.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-14.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-17.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-19.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-2.c        |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-22.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-24.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-27.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-29.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-32.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-34.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-37.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-39.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-4.c        |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-42.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-44.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-47.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-49.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-52.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-54.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-57.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-59.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-62.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-64.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-67.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-69.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-7.c        |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-72.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-74.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-77.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-79.c       |   2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-9.c        |   2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-1.c  |   2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-2.c  |   2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-3.c  |   2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-4.c  |   2 +-
 gcc/testsuite/gcc.target/powerpc/pr82015.c    |   4 +-
 gcc/testsuite/gcc.target/powerpc/pr91903.c    |  60 +-
 .../powerpc/test_fpscr_rn_builtin_error.c     |   8 +-
 .../gcc.target/powerpc/vec-ternarylogic-10.c  |   6 +-
 51 files changed, 351 insertions(+), 339 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index a8ebb4af239..cfe31c2e7de 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -175,6 +175,7 @@
 ; indicated by one of the following occurring after the "int" token:
 ;
 ;    <x>   restricts the constant to x bits, interpreted as unsigned
+;          (supported, but now deprecated in favor of <x,y>)
 ;    <x,y> restricts the constant to the inclusive range [x,y]
 ;    [x,y] restricts the constant to the inclusive range [x,y],
 ;	   but only applies if the argument is constant.
@@ -224,13 +225,13 @@
   unsigned long __builtin_ppc_mftb ();
     MFTB rs6000_mftb_di {32bit}
 
-  void __builtin_mtfsb0 (const int<5>);
+  void __builtin_mtfsb0 (const int<0,31>);
     MTFSB0 rs6000_mtfsb0 {}
 
-  void __builtin_mtfsb1 (const int<5>);
+  void __builtin_mtfsb1 (const int<0,31>);
     MTFSB1 rs6000_mtfsb1 {}
 
-  void __builtin_mtfsf (const int<8>, double);
+  void __builtin_mtfsf (const int<0,255>, double);
     MTFSF rs6000_mtfsf {}
 
   const __ibm128 __builtin_pack_ibm128 (double, double);
@@ -239,12 +240,12 @@
   void __builtin_set_fpscr_rn (const int[0,3]);
     SET_FPSCR_RN rs6000_set_fpscr_rn {}
 
-  const double __builtin_unpack_ibm128 (__ibm128, const int<1>);
+  const double __builtin_unpack_ibm128 (__ibm128, const int<0,1>);
     UNPACK_IF unpackif {}
 
 ; This is redundant with __builtin_unpack_ibm128, as it requires long
 ; double to be __ibm128.  Should probably be deprecated.
-  const double __builtin_unpack_longdouble (long double, const int<1>);
+  const double __builtin_unpack_longdouble (long double, const int<0,1>);
     UNPACK_TF unpacktf {ibmld}
 
 
@@ -301,22 +302,22 @@
   const vf __builtin_altivec_copysignfp (vf, vf);
     COPYSIGN_V4SF vector_copysignv4sf3 {}
 
-  void __builtin_altivec_dss (const int<2>);
+  void __builtin_altivec_dss (const int<0,3>);
     DSS altivec_dss {}
 
   void __builtin_altivec_dssall ();
     DSSALL altivec_dssall {}
 
-  void __builtin_altivec_dst (void *, const int, const int<2>);
+  void __builtin_altivec_dst (void *, const int, const int<0,3>);
     DST altivec_dst {}
 
-  void __builtin_altivec_dstst (void *, const int, const int<2>);
+  void __builtin_altivec_dstst (void *, const int, const int<0,3>);
     DSTST altivec_dstst {}
 
-  void __builtin_altivec_dststt (void *, const int, const int<2>);
+  void __builtin_altivec_dststt (void *, const int, const int<0,3>);
     DSTSTT altivec_dststt {}
 
-  void __builtin_altivec_dstt (void *, const int, const int<2>);
+  void __builtin_altivec_dstt (void *, const int, const int<0,3>);
     DSTT altivec_dstt {}
 
   fpmath vsi __builtin_altivec_fix_sfsi (vf);
@@ -544,10 +545,10 @@
   const vui __builtin_altivec_vavguw (vui, vui);
     VAVGUW uavgv4si3_ceil {}
 
-  const vf __builtin_altivec_vcfsx (vsi, const int<5>);
+  const vf __builtin_altivec_vcfsx (vsi, const int<0,31>);
     VCFSX altivec_vcfsx {}
 
-  const vf __builtin_altivec_vcfux (vui, const int<5>);
+  const vf __builtin_altivec_vcfux (vui, const int<0,31>);
     VCFUX altivec_vcfux {}
 
   const vsi __builtin_altivec_vcmpbfp (vf, vf);
@@ -628,10 +629,10 @@
   const int __builtin_altivec_vcmpgtuw_p (int, vsi, vsi);
     VCMPGTUW_P vector_gtu_v4si_p {pred}
 
-  const vsi __builtin_altivec_vctsxs (vf, const int<5>);
+  const vsi __builtin_altivec_vctsxs (vf, const int<0,31>);
     VCTSXS altivec_vctsxs {}
 
-  const vui __builtin_altivec_vctuxs (vf, const int<5>);
+  const vui __builtin_altivec_vctuxs (vf, const int<0,31>);
     VCTUXS altivec_vctuxs {}
 
   fpmath vf __builtin_altivec_vexptefp (vf);
@@ -931,16 +932,16 @@
   const vsc __builtin_altivec_vslb (vsc, vuc);
     VSLB vashlv16qi3 {}
 
-  const vsc __builtin_altivec_vsldoi_16qi (vsc, vsc, const int<4>);
+  const vsc __builtin_altivec_vsldoi_16qi (vsc, vsc, const int<0,15>);
     VSLDOI_16QI altivec_vsldoi_v16qi {}
 
-  const vf __builtin_altivec_vsldoi_4sf (vf, vf, const int<4>);
+  const vf __builtin_altivec_vsldoi_4sf (vf, vf, const int<0,15>);
     VSLDOI_4SF altivec_vsldoi_v4sf {}
 
-  const vsi __builtin_altivec_vsldoi_4si (vsi, vsi, const int<4>);
+  const vsi __builtin_altivec_vsldoi_4si (vsi, vsi, const int<0,15>);
     VSLDOI_4SI altivec_vsldoi_v4si {}
 
-  const vss __builtin_altivec_vsldoi_8hi (vss, vss, const int<4>);
+  const vss __builtin_altivec_vsldoi_8hi (vss, vss, const int<0,15>);
     VSLDOI_8HI altivec_vsldoi_v8hi {}
 
   const vss __builtin_altivec_vslh (vss, vus);
@@ -952,10 +953,10 @@
   const vsi __builtin_altivec_vslw (vsi, vui);
     VSLW vashlv4si3 {}
 
-  const vsc __builtin_altivec_vspltb (vsc, const int<4>);
+  const vsc __builtin_altivec_vspltb (vsc, const int<0,15>);
     VSPLTB altivec_vspltb {}
 
-  const vss __builtin_altivec_vsplth (vss, const int<3>);
+  const vss __builtin_altivec_vsplth (vss, const int<0,7>);
     VSPLTH altivec_vsplth {}
 
   const vsc __builtin_altivec_vspltisb (const int<-16,15>);
@@ -967,7 +968,7 @@
   const vsi __builtin_altivec_vspltisw (const int<-16,15>);
     VSPLTISW altivec_vspltisw {}
 
-  const vsi __builtin_altivec_vspltw (vsi, const int<2>);
+  const vsi __builtin_altivec_vspltw (vsi, const int<0,3>);
     VSPLTW altivec_vspltw {}
 
   const vsi __builtin_altivec_vsr (vsi, vsi);
@@ -1114,16 +1115,16 @@
              signed short);
     VEC_INIT_V8HI nothing {init}
 
-  const vsc __builtin_vec_set_v16qi (vsc, signed char, const int<4>);
+  const vsc __builtin_vec_set_v16qi (vsc, signed char, const int<0,15>);
     VEC_SET_V16QI nothing {set}
 
-  const vf __builtin_vec_set_v4sf (vf, float, const int<2>);
+  const vf __builtin_vec_set_v4sf (vf, float, const int<0,3>);
     VEC_SET_V4SF nothing {set}
 
-  const vsi __builtin_vec_set_v4si (vsi, signed int, const int<2>);
+  const vsi __builtin_vec_set_v4si (vsi, signed int, const int<0,3>);
     VEC_SET_V4SI nothing {set}
 
-  const vss __builtin_vec_set_v8hi (vss, signed short, const int<3>);
+  const vss __builtin_vec_set_v8hi (vss, signed short, const int<0,7>);
     VEC_SET_V8HI nothing {set}
 
 
@@ -1246,10 +1247,10 @@
   const vull __builtin_altivec_vsel_2di_uns (vull, vull, vull);
     VSEL_2DI_UNS vector_select_v2di_uns {}
 
-  const vd __builtin_altivec_vsldoi_2df (vd, vd, const int<4>);
+  const vd __builtin_altivec_vsldoi_2df (vd, vd, const int<0,15>);
     VSLDOI_2DF altivec_vsldoi_v2df {}
 
-  const vsll __builtin_altivec_vsldoi_2di (vsll, vsll, const int<4>);
+  const vsll __builtin_altivec_vsldoi_2di (vsll, vsll, const int<0,15>);
     VSLDOI_2DI altivec_vsldoi_v2di {}
 
   const vd __builtin_altivec_vxor_v2df (vd, vd);
@@ -1282,10 +1283,10 @@
   const vsq __builtin_vec_set_v1ti (vsq, signed __int128, const int<0,0>);
     VEC_SET_V1TI nothing {set}
 
-  const vd __builtin_vec_set_v2df (vd, double, const int<1>);
+  const vd __builtin_vec_set_v2df (vd, double, const int<0,1>);
     VEC_SET_V2DF nothing {set}
 
-  const vsll __builtin_vec_set_v2di (vsll, signed long long, const int<1>);
+  const vsll __builtin_vec_set_v2di (vsll, signed long long, const int<0,1>);
     VEC_SET_V2DI nothing {set}
 
   const vsc __builtin_vsx_cmpge_16qi (vsc, vsc);
@@ -1719,7 +1720,7 @@
   const vd __builtin_vsx_xvcvsxddp (vsll);
     XVCVSXDDP vsx_floatv2div2df2 {}
 
-  const vd __builtin_vsx_xvcvsxddp_scale (vsll, const int<5>);
+  const vd __builtin_vsx_xvcvsxddp_scale (vsll, const int<0,31>);
     XVCVSXDDP_SCALE vsx_xvcvsxddp_scale {}
 
   const vf __builtin_vsx_xvcvsxdsp (vsll);
@@ -1734,7 +1735,7 @@
   const vd __builtin_vsx_xvcvuxddp (vsll);
     XVCVUXDDP vsx_floatunsv2div2df2 {}
 
-  const vd __builtin_vsx_xvcvuxddp_scale (vsll, const int<5>);
+  const vd __builtin_vsx_xvcvuxddp_scale (vsll, const int<0,31>);
     XVCVUXDDP_SCALE vsx_xvcvuxddp_scale {}
 
   const vd __builtin_vsx_xvcvuxddp_uns (vull);
@@ -1911,25 +1912,25 @@
   const vsi __builtin_vsx_xxmrglw_4si (vsi, vsi);
     XXMRGLW_4SI vsx_xxmrglw_v4si {}
 
-  const vsc __builtin_vsx_xxpermdi_16qi (vsc, vsc, const int<2>);
+  const vsc __builtin_vsx_xxpermdi_16qi (vsc, vsc, const int<0,3>);
     XXPERMDI_16QI vsx_xxpermdi_v16qi {}
 
-  const vsq __builtin_vsx_xxpermdi_1ti (vsq, vsq, const int<2>);
+  const vsq __builtin_vsx_xxpermdi_1ti (vsq, vsq, const int<0,3>);
     XXPERMDI_1TI vsx_xxpermdi_v1ti {}
 
-  const vd __builtin_vsx_xxpermdi_2df (vd, vd, const int<2>);
+  const vd __builtin_vsx_xxpermdi_2df (vd, vd, const int<0,3>);
     XXPERMDI_2DF vsx_xxpermdi_v2df {}
 
-  const vsll __builtin_vsx_xxpermdi_2di (vsll, vsll, const int<2>);
+  const vsll __builtin_vsx_xxpermdi_2di (vsll, vsll, const int<0,3>);
     XXPERMDI_2DI vsx_xxpermdi_v2di {}
 
-  const vf __builtin_vsx_xxpermdi_4sf (vf, vf, const int<2>);
+  const vf __builtin_vsx_xxpermdi_4sf (vf, vf, const int<0,3>);
     XXPERMDI_4SF vsx_xxpermdi_v4sf {}
 
-  const vsi __builtin_vsx_xxpermdi_4si (vsi, vsi, const int<2>);
+  const vsi __builtin_vsx_xxpermdi_4si (vsi, vsi, const int<0,3>);
     XXPERMDI_4SI vsx_xxpermdi_v4si {}
 
-  const vss __builtin_vsx_xxpermdi_8hi (vss, vss, const int<2>);
+  const vss __builtin_vsx_xxpermdi_8hi (vss, vss, const int<0,3>);
     XXPERMDI_8HI vsx_xxpermdi_v8hi {}
 
   const vsc __builtin_vsx_xxsel_16qi (vsc, vsc, vsc);
@@ -1968,28 +1969,28 @@
   const vus __builtin_vsx_xxsel_8hi_uns (vus, vus, vus);
     XXSEL_8HI_UNS vector_select_v8hi_uns {}
 
-  const vsc __builtin_vsx_xxsldwi_16qi (vsc, vsc, const int<2>);
+  const vsc __builtin_vsx_xxsldwi_16qi (vsc, vsc, const int<0,3>);
     XXSLDWI_16QI vsx_xxsldwi_v16qi {}
 
-  const vd __builtin_vsx_xxsldwi_2df (vd, vd, const int<2>);
+  const vd __builtin_vsx_xxsldwi_2df (vd, vd, const int<0,3>);
     XXSLDWI_2DF vsx_xxsldwi_v2df {}
 
-  const vsll __builtin_vsx_xxsldwi_2di (vsll, vsll, const int<2>);
+  const vsll __builtin_vsx_xxsldwi_2di (vsll, vsll, const int<0,3>);
     XXSLDWI_2DI vsx_xxsldwi_v2di {}
 
-  const vf __builtin_vsx_xxsldwi_4sf (vf, vf, const int<2>);
+  const vf __builtin_vsx_xxsldwi_4sf (vf, vf, const int<0,3>);
     XXSLDWI_4SF vsx_xxsldwi_v4sf {}
 
-  const vsi __builtin_vsx_xxsldwi_4si (vsi, vsi, const int<2>);
+  const vsi __builtin_vsx_xxsldwi_4si (vsi, vsi, const int<0,3>);
     XXSLDWI_4SI vsx_xxsldwi_v4si {}
 
-  const vss __builtin_vsx_xxsldwi_8hi (vss, vss, const int<2>);
+  const vss __builtin_vsx_xxsldwi_8hi (vss, vss, const int<0,3>);
     XXSLDWI_8HI vsx_xxsldwi_v8hi {}
 
-  const vd __builtin_vsx_xxspltd_2df (vd, const int<1>);
+  const vd __builtin_vsx_xxspltd_2df (vd, const int<0,1>);
     XXSPLTD_V2DF vsx_xxspltd_v2df {}
 
-  const vsll __builtin_vsx_xxspltd_2di (vsll, const int<1>);
+  const vsll __builtin_vsx_xxspltd_2di (vsll, const int<0,1>);
     XXSPLTD_V2DI vsx_xxspltd_v2di {}
 
 
@@ -2020,7 +2021,7 @@
   void __builtin_ppc_speculation_barrier ();
     SPECBARR speculation_barrier {}
 
-  const unsigned long __builtin_unpack_vector_int128 (vsq, const int<1>);
+  const unsigned long __builtin_unpack_vector_int128 (vsq, const int<0,1>);
     UNPACK_V1TI unpackv1ti {}
 
 
@@ -2345,34 +2346,34 @@
   const vsll __builtin_altivec_vupklsw (vsi);
     VUPKLSW altivec_vupklsw {}
 
-  const vsq __builtin_bcdadd_v1ti (vsq, vsq, const int<1>);
+  const vsq __builtin_bcdadd_v1ti (vsq, vsq, const int<0,1>);
     BCDADD_V1TI bcdadd_v1ti {}
 
-  const vsc __builtin_bcdadd_v16qi (vsc, vsc, const int<1>);
+  const vsc __builtin_bcdadd_v16qi (vsc, vsc, const int<0,1>);
     BCDADD_V16QI bcdadd_v16qi {}
 
-  const signed int __builtin_bcdadd_eq_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdadd_eq_v1ti (vsq, vsq, const int<0,1>);
     BCDADD_EQ_V1TI bcdadd_eq_v1ti {}
 
-  const signed int __builtin_bcdadd_eq_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdadd_eq_v16qi (vsc, vsc, const int<0,1>);
     BCDADD_EQ_V16QI bcdadd_eq_v16qi {}
 
-  const signed int __builtin_bcdadd_gt_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdadd_gt_v1ti (vsq, vsq, const int<0,1>);
     BCDADD_GT_V1TI bcdadd_gt_v1ti {}
 
-  const signed int __builtin_bcdadd_gt_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdadd_gt_v16qi (vsc, vsc, const int<0,1>);
     BCDADD_GT_V16QI bcdadd_gt_v16qi {}
 
-  const signed int __builtin_bcdadd_lt_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdadd_lt_v1ti (vsq, vsq, const int<0,1>);
     BCDADD_LT_V1TI bcdadd_lt_v1ti {}
 
-  const signed int __builtin_bcdadd_lt_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdadd_lt_v16qi (vsc, vsc, const int<0,1>);
     BCDADD_LT_V16QI bcdadd_lt_v16qi {}
 
-  const signed int __builtin_bcdadd_ov_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdadd_ov_v1ti (vsq, vsq, const int<0,1>);
     BCDADD_OV_V1TI bcdadd_unordered_v1ti {}
 
-  const signed int __builtin_bcdadd_ov_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdadd_ov_v16qi (vsc, vsc, const int<0,1>);
     BCDADD_OV_V16QI bcdadd_unordered_v16qi {}
 
   const signed int __builtin_bcdinvalid_v1ti (vsq);
@@ -2381,46 +2382,46 @@
   const signed int __builtin_bcdinvalid_v16qi (vsc);
     BCDINVALID_V16QI bcdinvalid_v16qi {}
 
-  const vsq __builtin_bcdsub_v1ti (vsq, vsq, const int<1>);
+  const vsq __builtin_bcdsub_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_V1TI bcdsub_v1ti {}
 
-  const vsc __builtin_bcdsub_v16qi (vsc, vsc, const int<1>);
+  const vsc __builtin_bcdsub_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_V16QI bcdsub_v16qi {}
 
-  const signed int __builtin_bcdsub_eq_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdsub_eq_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_EQ_V1TI bcdsub_eq_v1ti {}
 
-  const signed int __builtin_bcdsub_eq_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdsub_eq_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_EQ_V16QI bcdsub_eq_v16qi {}
 
-  const signed int __builtin_bcdsub_ge_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdsub_ge_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_GE_V1TI bcdsub_ge_v1ti {}
 
-  const signed int __builtin_bcdsub_ge_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdsub_ge_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_GE_V16QI bcdsub_ge_v16qi {}
 
-  const signed int __builtin_bcdsub_gt_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdsub_gt_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_GT_V1TI bcdsub_gt_v1ti {}
 
-  const signed int __builtin_bcdsub_gt_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdsub_gt_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_GT_V16QI bcdsub_gt_v16qi {}
 
-  const signed int __builtin_bcdsub_le_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdsub_le_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_LE_V1TI bcdsub_le_v1ti {}
 
-  const signed int __builtin_bcdsub_le_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdsub_le_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_LE_V16QI bcdsub_le_v16qi {}
 
-  const signed int __builtin_bcdsub_lt_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdsub_lt_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_LT_V1TI bcdsub_lt_v1ti {}
 
-  const signed int __builtin_bcdsub_lt_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdsub_lt_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_LT_V16QI bcdsub_lt_v16qi {}
 
-  const signed int __builtin_bcdsub_ov_v1ti (vsq, vsq, const int<1>);
+  const signed int __builtin_bcdsub_ov_v1ti (vsq, vsq, const int<0,1>);
     BCDSUB_OV_V1TI bcdsub_unordered_v1ti {}
 
-  const signed int __builtin_bcdsub_ov_v16qi (vsc, vsc, const int<1>);
+  const signed int __builtin_bcdsub_ov_v16qi (vsc, vsc, const int<0,1>);
     BCDSUB_OV_V16QI bcdsub_unordered_v16qi {}
 
   const vuc __builtin_crypto_vpermxor_v16qi (vuc, vuc, vuc);
@@ -2749,11 +2750,11 @@
     VSCEDPUO xscmpexpdp_unordered {}
 
   const signed int \
-      __builtin_vsx_scalar_test_data_class_dp (double, const int<7>);
+      __builtin_vsx_scalar_test_data_class_dp (double, const int<0,127>);
     VSTDCDP xststdcdp {}
 
   const signed int \
-      __builtin_vsx_scalar_test_data_class_sp (float, const int<7>);
+      __builtin_vsx_scalar_test_data_class_sp (float, const int<0,127>);
     VSTDCSP xststdcsp {}
 
   const signed int __builtin_vsx_scalar_test_neg_dp (double);
@@ -2762,10 +2763,10 @@
   const signed int __builtin_vsx_scalar_test_neg_sp (float);
     VSTDCNSP xststdcnegsp {}
 
-  const vsll __builtin_vsx_test_data_class_dp (vd, const int<7>);
+  const vsll __builtin_vsx_test_data_class_dp (vd, const int<0,127>);
     VTDCDP xvtstdcdp {}
 
-  const vsi __builtin_vsx_test_data_class_sp (vf, const int<7>);
+  const vsi __builtin_vsx_test_data_class_sp (vf, const int<0,127>);
     VTDCSP xvtstdcsp {}
 
   const vf __builtin_vsx_vextract_fp_from_shorth (vss);
@@ -2807,28 +2808,28 @@
   signed long __builtin_darn_raw ();
     DARN_RAW darn_raw_di {32bit}
 
-  const signed int __builtin_dtstsfi_eq_dd (const int<6>, _Decimal64);
+  const signed int __builtin_dtstsfi_eq_dd (const int<0,63>, _Decimal64);
     TSTSFI_EQ_DD dfptstsfi_eq_dd {}
 
-  const signed int __builtin_dtstsfi_eq_td (const int<6>, _Decimal128);
+  const signed int __builtin_dtstsfi_eq_td (const int<0,63>, _Decimal128);
     TSTSFI_EQ_TD dfptstsfi_eq_td {}
 
-  const signed int __builtin_dtstsfi_gt_dd (const int<6>, _Decimal64);
+  const signed int __builtin_dtstsfi_gt_dd (const int<0,63>, _Decimal64);
     TSTSFI_GT_DD dfptstsfi_gt_dd {}
 
-  const signed int __builtin_dtstsfi_gt_td (const int<6>, _Decimal128);
+  const signed int __builtin_dtstsfi_gt_td (const int<0,63>, _Decimal128);
     TSTSFI_GT_TD dfptstsfi_gt_td {}
 
-  const signed int __builtin_dtstsfi_lt_dd (const int<6>, _Decimal64);
+  const signed int __builtin_dtstsfi_lt_dd (const int<0,63>, _Decimal64);
     TSTSFI_LT_DD dfptstsfi_lt_dd {}
 
-  const signed int __builtin_dtstsfi_lt_td (const int<6>, _Decimal128);
+  const signed int __builtin_dtstsfi_lt_td (const int<0,63>, _Decimal128);
     TSTSFI_LT_TD dfptstsfi_lt_td {}
 
-  const signed int __builtin_dtstsfi_ov_dd (const int<6>, _Decimal64);
+  const signed int __builtin_dtstsfi_ov_dd (const int<0,63>, _Decimal64);
     TSTSFI_OV_DD dfptstsfi_unordered_dd {}
 
-  const signed int __builtin_dtstsfi_ov_td (const int<6>, _Decimal128);
+  const signed int __builtin_dtstsfi_ov_td (const int<0,63>, _Decimal128);
     TSTSFI_OV_TD dfptstsfi_unordered_td {}
 
 
@@ -2914,7 +2915,7 @@
     VSIEQPF xsiexpqpf_kf {}
 
   const signed int __builtin_vsx_scalar_test_data_class_qp (_Float128, \
-                                                            const int<7>);
+                                                            const int<0,127>);
     VSTDCQP xststdcqp_kf {}
 
   const signed int __builtin_vsx_scalar_test_neg_qp (_Float128);
@@ -2924,16 +2925,16 @@
 
 ; Decimal floating-point builtins.
 [dfp]
-  const _Decimal64 __builtin_ddedpd (const int<2>, _Decimal64);
+  const _Decimal64 __builtin_ddedpd (const int<0,3>, _Decimal64);
     DDEDPD dfp_ddedpd_dd {}
 
-  const _Decimal128 __builtin_ddedpdq (const int<2>, _Decimal128);
+  const _Decimal128 __builtin_ddedpdq (const int<0,3>, _Decimal128);
     DDEDPDQ dfp_ddedpd_td {}
 
-  const _Decimal64 __builtin_denbcd (const int<1>, _Decimal64);
+  const _Decimal64 __builtin_denbcd (const int<0,1>, _Decimal64);
     DENBCD dfp_denbcd_dd {}
 
-  const _Decimal128 __builtin_denbcdq (const int<1>, _Decimal128);
+  const _Decimal128 __builtin_denbcdq (const int<0,1>, _Decimal128);
     DENBCDQ dfp_denbcd_td {}
 
   const _Decimal128 __builtin_denb2dfp_v16qi (vsc);
@@ -2945,16 +2946,16 @@
   const _Decimal128 __builtin_diexq (signed long long, _Decimal128);
     DIEXQ dfp_diex_td {}
 
-  const _Decimal64 __builtin_dscli (_Decimal64, const int<6>);
+  const _Decimal64 __builtin_dscli (_Decimal64, const int<0,63>);
     DSCLI dfp_dscli_dd {}
 
-  const _Decimal128 __builtin_dscliq (_Decimal128, const int<6>);
+  const _Decimal128 __builtin_dscliq (_Decimal128, const int<0,63>);
     DSCLIQ dfp_dscli_td {}
 
-  const _Decimal64 __builtin_dscri (_Decimal64, const int<6>);
+  const _Decimal64 __builtin_dscri (_Decimal64, const int<0,63>);
     DSCRI dfp_dscri_dd {}
 
-  const _Decimal128 __builtin_dscriq (_Decimal128, const int<6>);
+  const _Decimal128 __builtin_dscriq (_Decimal128, const int<0,63>);
     DSCRIQ dfp_dscri_td {}
 
   const signed long long __builtin_dxex (_Decimal64);
@@ -2970,7 +2971,8 @@
   void __builtin_set_fpscr_drn (const int[0,7]);
     SET_FPSCR_DRN rs6000_set_fpscr_drn {}
 
-  const unsigned long long __builtin_unpack_dec128 (_Decimal128, const int<1>);
+  const unsigned long long __builtin_unpack_dec128 (_Decimal128, \
+                                                    const int<0,1>);
     UNPACK_TD unpacktd {}
 
 
@@ -3005,10 +3007,12 @@
   const vuc __builtin_crypto_vsbox_be (vuc);
     VSBOX_BE crypto_vsbox_v16qi {}
 
-  const vull __builtin_crypto_vshasigmad (vull, const int<1>, const int<4>);
+  const vull __builtin_crypto_vshasigmad (vull, const int<0,1>, \
+                                          const int<0,15>);
     VSHASIGMAD crypto_vshasigmad {}
 
-  const vui __builtin_crypto_vshasigmaw (vui, const int<1>, const int<4>);
+  const vui __builtin_crypto_vshasigmaw (vui, const int<0,1>, \
+                                         const int<0,15>);
     VSHASIGMAW crypto_vshasigmaw {}
 
 
@@ -3098,16 +3102,16 @@
   const vbq __builtin_altivec_cmple_u1ti (vuq, vuq);
     CMPLE_U1TI vector_ngtuv1ti {}
 
-  const unsigned long long __builtin_altivec_cntmbb (vuc, const int<1>);
+  const unsigned long long __builtin_altivec_cntmbb (vuc, const int<0,1>);
     VCNTMBB vec_cntmb_v16qi {}
 
-  const unsigned long long __builtin_altivec_cntmbd (vull, const int<1>);
+  const unsigned long long __builtin_altivec_cntmbd (vull, const int<0,1>);
     VCNTMBD vec_cntmb_v2di {}
 
-  const unsigned long long __builtin_altivec_cntmbh (vus, const int<1>);
+  const unsigned long long __builtin_altivec_cntmbh (vus, const int<0,1>);
     VCNTMBH vec_cntmb_v8hi {}
 
-  const unsigned long long __builtin_altivec_cntmbw (vui, const int<1>);
+  const unsigned long long __builtin_altivec_cntmbw (vui, const int<0,1>);
     VCNTMBW vec_cntmb_v4si {}
 
   const vsq __builtin_altivec_div_v1ti (vsq, vsq);
@@ -3388,44 +3392,46 @@
     VPEXTD vpextd {}
 
   const vull __builtin_altivec_vreplace_un_uv2di (vull, unsigned long long, \
-                                                  const int<4>);
+                                                  const int<0,15>);
     VREPLACE_UN_UV2DI vreplace_un_v2di {}
 
   const vui __builtin_altivec_vreplace_un_uv4si (vui, unsigned int, \
-                                                 const int<4>);
+                                                 const int<0,15>);
     VREPLACE_UN_UV4SI vreplace_un_v4si {}
 
-  const vd __builtin_altivec_vreplace_un_v2df (vd, double, const int<4>);
+  const vd __builtin_altivec_vreplace_un_v2df (vd, double, const int<0,15>);
     VREPLACE_UN_V2DF vreplace_un_v2df {}
 
   const vsll __builtin_altivec_vreplace_un_v2di (vsll, signed long long, \
-                                                 const int<4>);
+                                                 const int<0,15>);
     VREPLACE_UN_V2DI vreplace_un_v2di {}
 
-  const vf __builtin_altivec_vreplace_un_v4sf (vf, float, const int<4>);
+  const vf __builtin_altivec_vreplace_un_v4sf (vf, float, const int<0,15>);
     VREPLACE_UN_V4SF vreplace_un_v4sf {}
 
-  const vsi __builtin_altivec_vreplace_un_v4si (vsi, signed int, const int<4>);
+  const vsi __builtin_altivec_vreplace_un_v4si (vsi, signed int, \
+                                                const int<0,15>);
     VREPLACE_UN_V4SI vreplace_un_v4si {}
 
   const vull __builtin_altivec_vreplace_uv2di (vull, unsigned long long, \
-                                               const int<1>);
+                                               const int<0,1>);
     VREPLACE_ELT_UV2DI vreplace_elt_v2di {}
 
-  const vui __builtin_altivec_vreplace_uv4si (vui, unsigned int, const int<2>);
+  const vui __builtin_altivec_vreplace_uv4si (vui, unsigned int, \
+                                              const int<0,3>);
     VREPLACE_ELT_UV4SI vreplace_elt_v4si {}
 
-  const vd __builtin_altivec_vreplace_v2df (vd, double, const int<1>);
+  const vd __builtin_altivec_vreplace_v2df (vd, double, const int<0,1>);
     VREPLACE_ELT_V2DF vreplace_elt_v2df {}
 
   const vsll __builtin_altivec_vreplace_v2di (vsll, signed long long, \
-                                              const int<1>);
+                                              const int<0,1>);
     VREPLACE_ELT_V2DI vreplace_elt_v2di {}
 
-  const vf __builtin_altivec_vreplace_v4sf (vf, float, const int<2>);
+  const vf __builtin_altivec_vreplace_v4sf (vf, float, const int<0,3>);
     VREPLACE_ELT_V4SF vreplace_elt_v4sf {}
 
-  const vsi __builtin_altivec_vreplace_v4si (vsi, signed int, const int<2>);
+  const vsi __builtin_altivec_vreplace_v4si (vsi, signed int, const int<0,3>);
     VREPLACE_ELT_V4SI vreplace_elt_v4si {}
 
   const vsq __builtin_altivec_vrlq (vsq, vuq);
@@ -3440,16 +3446,16 @@
   const vsq __builtin_altivec_vsignext (vsll);
     VSIGNEXTSD2Q vsignextend_v2di_v1ti {}
 
-  const vsc __builtin_altivec_vsldb_v16qi (vsc, vsc, const int<3>);
+  const vsc __builtin_altivec_vsldb_v16qi (vsc, vsc, const int<0,7>);
     VSLDB_V16QI vsldb_v16qi {}
 
-  const vsll __builtin_altivec_vsldb_v2di (vsll, vsll, const int<3>);
+  const vsll __builtin_altivec_vsldb_v2di (vsll, vsll, const int<0,7>);
     VSLDB_V2DI vsldb_v2di {}
 
-  const vsi __builtin_altivec_vsldb_v4si (vsi, vsi, const int<3>);
+  const vsi __builtin_altivec_vsldb_v4si (vsi, vsi, const int<0,7>);
     VSLDB_V4SI vsldb_v4si {}
 
-  const vss __builtin_altivec_vsldb_v8hi (vss, vss, const int<3>);
+  const vss __builtin_altivec_vsldb_v8hi (vss, vss, const int<0,7>);
     VSLDB_V8HI vsldb_v8hi {}
 
   const vsq __builtin_altivec_vslq (vsq, vuq);
@@ -3458,16 +3464,16 @@
   const vsq __builtin_altivec_vsraq (vsq, vuq);
     VSRAQ vashrv1ti3 {}
 
-  const vsc __builtin_altivec_vsrdb_v16qi (vsc, vsc, const int<3>);
+  const vsc __builtin_altivec_vsrdb_v16qi (vsc, vsc, const int<0,7>);
     VSRDB_V16QI vsrdb_v16qi {}
 
-  const vsll __builtin_altivec_vsrdb_v2di (vsll, vsll, const int<3>);
+  const vsll __builtin_altivec_vsrdb_v2di (vsll, vsll, const int<0,7>);
     VSRDB_V2DI vsrdb_v2di {}
 
-  const vsi __builtin_altivec_vsrdb_v4si (vsi, vsi, const int<3>);
+  const vsi __builtin_altivec_vsrdb_v4si (vsi, vsi, const int<0,7>);
     VSRDB_V4SI vsrdb_v4si {}
 
-  const vss __builtin_altivec_vsrdb_v8hi (vss, vss, const int<3>);
+  const vss __builtin_altivec_vsrdb_v8hi (vss, vss, const int<0,7>);
     VSRDB_V8HI vsrdb_v8hi {}
 
   const vsq __builtin_altivec_vsrq (vsq, vuq);
@@ -3503,10 +3509,10 @@
   const signed int __builtin_vsx_xvtlsbb_all_zeros (vsc);
     XVTLSBB_ZEROS xvtlsbbz {}
 
-  const vf __builtin_vsx_vxxsplti32dx_v4sf (vf, const int<1>, float);
+  const vf __builtin_vsx_vxxsplti32dx_v4sf (vf, const int<0,1>, float);
     VXXSPLTI32DX_V4SF xxsplti32dx_v4sf {}
 
-  const vsi __builtin_vsx_vxxsplti32dx_v4si (vsi, const int<1>, signed int);
+  const vsi __builtin_vsx_vxxsplti32dx_v4si (vsi, const int<0,1>, signed int);
     VXXSPLTI32DX_V4SI xxsplti32dx_v4si {}
 
   const vd __builtin_vsx_vxxspltidp (float);
@@ -3542,49 +3548,49 @@
   const vus __builtin_vsx_xxblend_v8hi (vus, vus, vus);
     VXXBLEND_V8HI xxblend_v8hi {}
 
-  const vull __builtin_vsx_xxeval (vull, vull, vull, const int <8>);
+  const vull __builtin_vsx_xxeval (vull, vull, vull, const int <0,255>);
     XXEVAL xxeval {}
 
-  const vuc __builtin_vsx_xxgenpcvm_v16qi (vuc, const int <2>);
+  const vuc __builtin_vsx_xxgenpcvm_v16qi (vuc, const int <0,3>);
     XXGENPCVM_V16QI xxgenpcvm_v16qi {}
 
-  const vull __builtin_vsx_xxgenpcvm_v2di (vull, const int <2>);
+  const vull __builtin_vsx_xxgenpcvm_v2di (vull, const int <0,3>);
     XXGENPCVM_V2DI xxgenpcvm_v2di {}
 
-  const vui __builtin_vsx_xxgenpcvm_v4si (vui, const int <2>);
+  const vui __builtin_vsx_xxgenpcvm_v4si (vui, const int <0,3>);
     XXGENPCVM_V4SI xxgenpcvm_v4si {}
 
-  const vus __builtin_vsx_xxgenpcvm_v8hi (vus, const int <2>);
+  const vus __builtin_vsx_xxgenpcvm_v8hi (vus, const int <0,3>);
     XXGENPCVM_V8HI xxgenpcvm_v8hi {}
 
-  const vuc __builtin_vsx_xxpermx_uv16qi (vuc, vuc, vuc, const int<3>);
+  const vuc __builtin_vsx_xxpermx_uv16qi (vuc, vuc, vuc, const int<0,7>);
     XXPERMX_UV16QI xxpermx {}
 
-  const vull __builtin_vsx_xxpermx_uv2di (vull, vull, vuc, const int<3>);
+  const vull __builtin_vsx_xxpermx_uv2di (vull, vull, vuc, const int<0,7>);
     XXPERMX_UV2DI xxpermx {}
 
-  const vui __builtin_vsx_xxpermx_uv4si (vui, vui, vuc, const int<3>);
+  const vui __builtin_vsx_xxpermx_uv4si (vui, vui, vuc, const int<0,7>);
     XXPERMX_UV4SI xxpermx {}
 
-  const vus __builtin_vsx_xxpermx_uv8hi (vus, vus, vuc, const int<3>);
+  const vus __builtin_vsx_xxpermx_uv8hi (vus, vus, vuc, const int<0,7>);
     XXPERMX_UV8HI xxpermx {}
 
-  const vsc __builtin_vsx_xxpermx_v16qi (vsc, vsc, vuc, const int<3>);
+  const vsc __builtin_vsx_xxpermx_v16qi (vsc, vsc, vuc, const int<0,7>);
     XXPERMX_V16QI xxpermx {}
 
-  const vd __builtin_vsx_xxpermx_v2df (vd, vd, vuc, const int<3>);
+  const vd __builtin_vsx_xxpermx_v2df (vd, vd, vuc, const int<0,7>);
     XXPERMX_V2DF xxpermx {}
 
-  const vsll __builtin_vsx_xxpermx_v2di (vsll, vsll, vuc, const int<3>);
+  const vsll __builtin_vsx_xxpermx_v2di (vsll, vsll, vuc, const int<0,7>);
     XXPERMX_V2DI xxpermx {}
 
-  const vf __builtin_vsx_xxpermx_v4sf (vf, vf, vuc, const int<3>);
+  const vf __builtin_vsx_xxpermx_v4sf (vf, vf, vuc, const int<0,7>);
     XXPERMX_V4SF xxpermx {}
 
-  const vsi __builtin_vsx_xxpermx_v4si (vsi, vsi, vuc, const int<3>);
+  const vsi __builtin_vsx_xxpermx_v4si (vsi, vsi, vuc, const int<0,7>);
     XXPERMX_V4SI xxpermx {}
 
-  const vss __builtin_vsx_xxpermx_v8hi (vss, vss, vuc, const int<3>);
+  const vss __builtin_vsx_xxpermx_v8hi (vss, vss, vuc, const int<0,7>);
     XXPERMX_V8HI xxpermx {}
 
   pure unsigned __int128 __builtin_altivec_ze_lxvrbx (signed long, \
@@ -3648,244 +3654,250 @@
   void __builtin_mma_disassemble_acc (void *, v512 *);
     DISASSEMBLE_ACC nothing {mma,quad,mmaint}
 
-  vuc __builtin_mma_disassemble_acc_internal (v512, const int<2>);
+  vuc __builtin_mma_disassemble_acc_internal (v512, const int<0,3>);
     DISASSEMBLE_ACC_INTERNAL mma_disassemble_acc {mma}
 
   void __builtin_mma_disassemble_pair (void *, v256 *);
     DISASSEMBLE_PAIR nothing {mma,pair,mmaint}
 
-  vuc __builtin_mma_disassemble_pair_internal (v256, const int<2>);
+  vuc __builtin_mma_disassemble_pair_internal (v256, const int<0,3>);
     DISASSEMBLE_PAIR_INTERNAL vsx_disassemble_pair {mma}
 
-  void __builtin_mma_pmxvbf16ger2 (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>, const int<2>);
+  void __builtin_mma_pmxvbf16ger2 (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>, const int<0,3>);
     PMXVBF16GER2 nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvbf16ger2_internal (vuc, vuc, const int<4>, \
-                                            const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvbf16ger2_internal (vuc, vuc, const int<0,15>, \
+                                            const int<0,15>, const int<0,3>);
     PMXVBF16GER2_INTERNAL mma_pmxvbf16ger2 {mma}
 
-  void __builtin_mma_pmxvbf16ger2nn (v512 *, vuc, vuc, const int<4>, \
-                                     const int<4>, const int<2>);
+  void __builtin_mma_pmxvbf16ger2nn (v512 *, vuc, vuc, const int<0,15>, \
+                                     const int<0,15>, const int<0,3>);
     PMXVBF16GER2NN nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvbf16ger2nn_internal (v512, vuc, vuc, const int<4>, \
-                                              const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvbf16ger2nn_internal (v512, vuc, vuc, \
+                                              const int<0,15>, \
+                                              const int<0,15>, const int<0,3>);
     PMXVBF16GER2NN_INTERNAL mma_pmxvbf16ger2nn {mma,quad}
 
-  void __builtin_mma_pmxvbf16ger2np (v512 *, vuc, vuc, const int<4>, \
-                                     const int<4>, const int<2>);
+  void __builtin_mma_pmxvbf16ger2np (v512 *, vuc, vuc, const int<0,15>, \
+                                     const int<0,15>, const int<0,3>);
     PMXVBF16GER2NP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvbf16ger2np_internal (v512, vuc, vuc, const int<4>, \
-                                              const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvbf16ger2np_internal (v512, vuc, vuc, \
+                                              const int<0,15>, \
+                                              const int<0,15>, const int<0,3>);
     PMXVBF16GER2NP_INTERNAL mma_pmxvbf16ger2np {mma,quad}
 
-  void __builtin_mma_pmxvbf16ger2pn (v512 *, vuc, vuc, const int<4>, \
-                                     const int<4>, const int<2>);
+  void __builtin_mma_pmxvbf16ger2pn (v512 *, vuc, vuc, const int<0,15>, \
+                                     const int<0,15>, const int<0,3>);
     PMXVBF16GER2PN nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvbf16ger2pn_internal (v512, vuc, vuc, const int<4>, \
-                                              const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvbf16ger2pn_internal (v512, vuc, vuc, \
+                                              const int<0,15>, \
+                                              const int<0,15>, const int<0,3>);
     PMXVBF16GER2PN_INTERNAL mma_pmxvbf16ger2pn {mma,quad}
 
-  void __builtin_mma_pmxvbf16ger2pp (v512 *, vuc, vuc, const int<4>, \
-                                     const int<4>, const int<2>);
+  void __builtin_mma_pmxvbf16ger2pp (v512 *, vuc, vuc, const int<0,15>, \
+                                     const int<0,15>, const int<0,3>);
     PMXVBF16GER2PP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvbf16ger2pp_internal (v512, vuc, vuc, const int<4>, \
-                                              const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvbf16ger2pp_internal (v512, vuc, vuc, \
+                                              const int<0,15>, \
+                                              const int<0,15>, const int<0,3>);
     PMXVBF16GER2PP_INTERNAL mma_pmxvbf16ger2pp {mma,quad}
 
-  void __builtin_mma_pmxvf16ger2 (v512 *, vuc, vuc, const int<4>, \
-                                  const int<4>, const int<2>);
+  void __builtin_mma_pmxvf16ger2 (v512 *, vuc, vuc, const int<0,15>, \
+                                  const int<0,15>, const int<0,3>);
     PMXVF16GER2 nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvf16ger2_internal (vuc, vuc, const int<4>, \
-                                           const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvf16ger2_internal (vuc, vuc, const int<0,15>, \
+                                           const int<0,15>, const int<0,3>);
     PMXVF16GER2_INTERNAL mma_pmxvf16ger2 {mma}
 
-  void __builtin_mma_pmxvf16ger2nn (v512 *, vuc, vuc, const int<4>, \
-                                    const int<4>, const int<2>);
+  void __builtin_mma_pmxvf16ger2nn (v512 *, vuc, vuc, const int<0,15>, \
+                                    const int<0,15>, const int<0,3>);
     PMXVF16GER2NN nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf16ger2nn_internal (v512, vuc, vuc, const int<4>, \
-                                             const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvf16ger2nn_internal (v512, vuc, vuc, const int<0,15>, \
+                                             const int<0,15>, const int<0,3>);
     PMXVF16GER2NN_INTERNAL mma_pmxvf16ger2nn {mma,quad}
 
-  void __builtin_mma_pmxvf16ger2np (v512 *, vuc, vuc, const int<4>, \
-                                    const int<4>, const int<2>);
+  void __builtin_mma_pmxvf16ger2np (v512 *, vuc, vuc, const int<0,15>, \
+                                    const int<0,15>, const int<0,3>);
     PMXVF16GER2NP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf16ger2np_internal (v512, vuc, vuc, const int<4>, \
-                                             const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvf16ger2np_internal (v512, vuc, vuc, const int<0,15>, \
+                                             const int<0,15>, const int<0,3>);
     PMXVF16GER2NP_INTERNAL mma_pmxvf16ger2np {mma,quad}
 
-  void __builtin_mma_pmxvf16ger2pn (v512 *, vuc, vuc, const int<4>, \
-                                    const int<4>, const int<2>);
+  void __builtin_mma_pmxvf16ger2pn (v512 *, vuc, vuc, const int<0,15>, \
+                                    const int<0,15>, const int<0,3>);
     PMXVF16GER2PN nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf16ger2pn_internal (v512, vuc, vuc, const int<4>, \
-                                             const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvf16ger2pn_internal (v512, vuc, vuc, const int<0,15>, \
+                                             const int<0,15>, const int<0,3>);
     PMXVF16GER2PN_INTERNAL mma_pmxvf16ger2pn {mma,quad}
 
-  void __builtin_mma_pmxvf16ger2pp (v512 *, vuc, vuc, const int<4>, \
-                                    const int<4>, const int<2>);
+  void __builtin_mma_pmxvf16ger2pp (v512 *, vuc, vuc, const int<0,15>, \
+                                    const int<0,15>, const int<0,3>);
     PMXVF16GER2PP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf16ger2pp_internal (v512, vuc, vuc, const int<4>, \
-                                             const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvf16ger2pp_internal (v512, vuc, vuc, const int<0,15>, \
+                                             const int<0,15>, const int<0,3>);
     PMXVF16GER2PP_INTERNAL mma_pmxvf16ger2pp {mma,quad}
 
-  void __builtin_mma_pmxvf32ger (v512 *, vuc, vuc, const int<4>, const int<4>);
+  void __builtin_mma_pmxvf32ger (v512 *, vuc, vuc, const int<0,15>, \
+                                 const int<0,15>);
     PMXVF32GER nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvf32ger_internal (vuc, vuc, const int<4>, \
-                                          const int<4>);
+  v512 __builtin_mma_pmxvf32ger_internal (vuc, vuc, const int<0,15>, \
+                                          const int<0,15>);
     PMXVF32GER_INTERNAL mma_pmxvf32ger {mma}
 
-  void __builtin_mma_pmxvf32gernn (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>);
+  void __builtin_mma_pmxvf32gernn (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>);
     PMXVF32GERNN nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf32gernn_internal (v512, vuc, vuc, const int<4>, \
-                                            const int<4>);
+  v512 __builtin_mma_pmxvf32gernn_internal (v512, vuc, vuc, const int<0,15>, \
+                                            const int<0,15>);
     PMXVF32GERNN_INTERNAL mma_pmxvf32gernn {mma,quad}
 
-  void __builtin_mma_pmxvf32gernp (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>);
+  void __builtin_mma_pmxvf32gernp (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>);
     PMXVF32GERNP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf32gernp_internal (v512, vuc, vuc, const int<4>, \
-                                            const int<4>);
+  v512 __builtin_mma_pmxvf32gernp_internal (v512, vuc, vuc, const int<0,15>, \
+                                            const int<0,15>);
     PMXVF32GERNP_INTERNAL mma_pmxvf32gernp {mma,quad}
 
-  void __builtin_mma_pmxvf32gerpn (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>);
+  void __builtin_mma_pmxvf32gerpn (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>);
     PMXVF32GERPN nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf32gerpn_internal (v512, vuc, vuc, const int<4>, \
-                                            const int<4>);
+  v512 __builtin_mma_pmxvf32gerpn_internal (v512, vuc, vuc, const int<0,15>, \
+                                            const int<0,15>);
     PMXVF32GERPN_INTERNAL mma_pmxvf32gerpn {mma,quad}
 
-  void __builtin_mma_pmxvf32gerpp (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>);
+  void __builtin_mma_pmxvf32gerpp (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>);
     PMXVF32GERPP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf32gerpp_internal (v512, vuc, vuc, const int<4>, \
-                                            const int<4>);
+  v512 __builtin_mma_pmxvf32gerpp_internal (v512, vuc, vuc, const int<0,15>, \
+                                            const int<0,15>);
     PMXVF32GERPP_INTERNAL mma_pmxvf32gerpp {mma,quad}
 
-  void __builtin_mma_pmxvf64ger (v512 *, v256, vuc, const int<4>, \
-                                 const int<2>);
+  void __builtin_mma_pmxvf64ger (v512 *, v256, vuc, const int<0,15>, \
+                                 const int<0,3>);
     PMXVF64GER nothing {mma,pair,mmaint}
 
-  v512 __builtin_mma_pmxvf64ger_internal (v256, vuc, const int<4>, \
-                                          const int<2>);
+  v512 __builtin_mma_pmxvf64ger_internal (v256, vuc, const int<0,15>, \
+                                          const int<0,3>);
     PMXVF64GER_INTERNAL mma_pmxvf64ger {mma,pair}
 
-  void __builtin_mma_pmxvf64gernn (v512 *, v256, vuc, const int<4>, \
-                                   const int<2>);
+  void __builtin_mma_pmxvf64gernn (v512 *, v256, vuc, const int<0,15>, \
+                                   const int<0,3>);
     PMXVF64GERNN nothing {mma,pair,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf64gernn_internal (v512, v256, vuc, const int<4>, \
-                                            const int<2>);
+  v512 __builtin_mma_pmxvf64gernn_internal (v512, v256, vuc, const int<0,15>, \
+                                            const int<0,3>);
     PMXVF64GERNN_INTERNAL mma_pmxvf64gernn {mma,pair,quad}
 
-  void __builtin_mma_pmxvf64gernp (v512 *, v256, vuc, const int<4>, \
-                                   const int<2>);
+  void __builtin_mma_pmxvf64gernp (v512 *, v256, vuc, const int<0,15>, \
+                                   const int<0,3>);
     PMXVF64GERNP nothing {mma,pair,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf64gernp_internal (v512, v256, vuc, const int<4>, \
-                                            const int<2>);
+  v512 __builtin_mma_pmxvf64gernp_internal (v512, v256, vuc, const int<0,15>, \
+                                            const int<0,3>);
     PMXVF64GERNP_INTERNAL mma_pmxvf64gernp {mma,pair,quad}
 
-  void __builtin_mma_pmxvf64gerpn (v512 *, v256, vuc, const int<4>, \
-                                   const int<2>);
+  void __builtin_mma_pmxvf64gerpn (v512 *, v256, vuc, const int<0,15>, \
+                                   const int<0,3>);
     PMXVF64GERPN nothing {mma,pair,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf64gerpn_internal (v512, v256, vuc, const int<4>, \
-                                            const int<2>);
+  v512 __builtin_mma_pmxvf64gerpn_internal (v512, v256, vuc, const int<0,15>, \
+                                            const int<0,3>);
     PMXVF64GERPN_INTERNAL mma_pmxvf64gerpn {mma,pair,quad}
 
-  void __builtin_mma_pmxvf64gerpp (v512 *, v256, vuc, const int<4>, \
-                                   const int<2>);
+  void __builtin_mma_pmxvf64gerpp (v512 *, v256, vuc, const int<0,15>, \
+                                   const int<0,3>);
     PMXVF64GERPP nothing {mma,pair,quad,mmaint}
 
-  v512 __builtin_mma_pmxvf64gerpp_internal (v512, v256, vuc, const int<4>, \
-                                            const int<2>);
+  v512 __builtin_mma_pmxvf64gerpp_internal (v512, v256, vuc, const int<0,15>, \
+                                            const int<0,3>);
     PMXVF64GERPP_INTERNAL mma_pmxvf64gerpp {mma,pair,quad}
 
-  void __builtin_mma_pmxvi16ger2 (v512 *, vuc, vuc, const int<4>, \
-                                  const int<4>, const int<2>);
+  void __builtin_mma_pmxvi16ger2 (v512 *, vuc, vuc, const int<0,15>, \
+                                  const int<0,15>, const int<0,3>);
     PMXVI16GER2 nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvi16ger2_internal (vuc, vuc, const int<4>, \
-                                           const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvi16ger2_internal (vuc, vuc, const int<0,15>, \
+                                           const int<0,15>, const int<0,3>);
     PMXVI16GER2_INTERNAL mma_pmxvi16ger2 {mma}
 
-  void __builtin_mma_pmxvi16ger2pp (v512 *, vuc, vuc, const int<4>, \
-                                    const int<4>, const int<2>);
+  void __builtin_mma_pmxvi16ger2pp (v512 *, vuc, vuc, const int<0,15>, \
+                                    const int<0,15>, const int<0,3>);
     PMXVI16GER2PP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvi16ger2pp_internal (v512, vuc, vuc, const int<4>, \
-                                             const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvi16ger2pp_internal (v512, vuc, vuc, const int<0,15>, \
+                                             const int<0,15>, const int<0,3>);
     PMXVI16GER2PP_INTERNAL mma_pmxvi16ger2pp {mma,quad}
 
-  void __builtin_mma_pmxvi16ger2s (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>, const int<2>);
+  void __builtin_mma_pmxvi16ger2s (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>, const int<0,3>);
     PMXVI16GER2S nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvi16ger2s_internal (vuc, vuc, const int<4>, \
-                                            const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvi16ger2s_internal (vuc, vuc, const int<0,15>, \
+                                            const int<0,15>, const int<0,3>);
     PMXVI16GER2S_INTERNAL mma_pmxvi16ger2s {mma}
 
-  void __builtin_mma_pmxvi16ger2spp (v512 *, vuc, vuc, const int<4>, \
-                                     const int<4>, const int<2>);
+  void __builtin_mma_pmxvi16ger2spp (v512 *, vuc, vuc, const int<0,15>, \
+                                     const int<0,15>, const int<0,3>);
     PMXVI16GER2SPP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvi16ger2spp_internal (v512, vuc, vuc, const int<4>, \
-                                              const int<4>, const int<2>);
+  v512 __builtin_mma_pmxvi16ger2spp_internal (v512, vuc, vuc, \
+                                              const int<0,15>, \
+                                              const int<0,15>, const int<0,3>);
     PMXVI16GER2SPP_INTERNAL mma_pmxvi16ger2spp {mma,quad}
 
-  void __builtin_mma_pmxvi4ger8 (v512 *, vuc, vuc, const int<4>, \
-                                 const int<4>, const int<8>);
+  void __builtin_mma_pmxvi4ger8 (v512 *, vuc, vuc, const int<0,15>, \
+                                 const int<0,15>, const int<0,255>);
     PMXVI4GER8 nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvi4ger8_internal (vuc, vuc, const int<4>, \
-                                          const int<4>, const int<8>);
+  v512 __builtin_mma_pmxvi4ger8_internal (vuc, vuc, const int<0,15>, \
+                                          const int<0,15>, const int<0,255>);
     PMXVI4GER8_INTERNAL mma_pmxvi4ger8 {mma}
 
-  void __builtin_mma_pmxvi4ger8pp (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>, const int<4>);
+  void __builtin_mma_pmxvi4ger8pp (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>, const int<0,15>);
     PMXVI4GER8PP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvi4ger8pp_internal (v512, vuc, vuc, const int<4>, \
-                                            const int<4>, const int<4>);
+  v512 __builtin_mma_pmxvi4ger8pp_internal (v512, vuc, vuc, const int<0,15>, \
+                                            const int<0,15>, const int<0,15>);
     PMXVI4GER8PP_INTERNAL mma_pmxvi4ger8pp {mma,quad}
 
-  void __builtin_mma_pmxvi8ger4 (v512 *, vuc, vuc, const int<4>, \
-                                 const int<4>, const int<4>);
+  void __builtin_mma_pmxvi8ger4 (v512 *, vuc, vuc, const int<0,15>, \
+                                 const int<0,15>, const int<0,15>);
     PMXVI8GER4 nothing {mma,mmaint}
 
-  v512 __builtin_mma_pmxvi8ger4_internal (vuc, vuc, const int<4>, \
-                                          const int<4>, const int<4>);
+  v512 __builtin_mma_pmxvi8ger4_internal (vuc, vuc, const int<0,15>, \
+                                          const int<0,15>, const int<0,15>);
     PMXVI8GER4_INTERNAL mma_pmxvi8ger4 {mma}
 
-  void __builtin_mma_pmxvi8ger4pp (v512 *, vuc, vuc, const int<4>, \
-                                   const int<4>, const int<4>);
+  void __builtin_mma_pmxvi8ger4pp (v512 *, vuc, vuc, const int<0,15>, \
+                                   const int<0,15>, const int<0,15>);
     PMXVI8GER4PP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvi8ger4pp_internal (v512, vuc, vuc, const int<4>, \
-                                            const int<4>, const int<4>);
+  v512 __builtin_mma_pmxvi8ger4pp_internal (v512, vuc, vuc, const int<0,15>, \
+                                            const int<0,15>, const int<0,15>);
     PMXVI8GER4PP_INTERNAL mma_pmxvi8ger4pp {mma,quad}
 
-  void __builtin_mma_pmxvi8ger4spp (v512 *, vuc, vuc, const int<4>, \
-                                    const int<4>, const int<4>);
+  void __builtin_mma_pmxvi8ger4spp (v512 *, vuc, vuc, const int<0,15>, \
+                                    const int<0,15>, const int<0,15>);
     PMXVI8GER4SPP nothing {mma,quad,mmaint}
 
-  v512 __builtin_mma_pmxvi8ger4spp_internal (v512, vuc, vuc, const int<4>, \
-                                             const int<4>, const int<4>);
+  v512 __builtin_mma_pmxvi8ger4spp_internal (v512, vuc, vuc, const int<0,15>, \
+                                             const int<0,15>, const int<0,15>);
     PMXVI8GER4SPP_INTERNAL mma_pmxvi8ger4spp {mma,quad}
 
   void __builtin_mma_xvbf16ger2 (v512 *, vuc, vuc);
@@ -4095,7 +4107,7 @@
   void __builtin_vsx_disassemble_pair (void *, v256 *);
     DISASSEMBLE_PAIR_V nothing {mma,pair,mmaint}
 
-  vuc __builtin_vsx_disassemble_pair_internal (v256, const int<2>);
+  vuc __builtin_vsx_disassemble_pair_internal (v256, const int<0,3>);
     DISASSEMBLE_PAIR_V_INTERNAL vsx_disassemble_pair {mma}
 
   v256 __builtin_vsx_lxvp (unsigned long, const v256 *);
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
index 2e3643c6c09..fcf6a9dca79 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
@@ -13,6 +13,6 @@ test_data_class (__ieee128 *p, const int condition_flag)
 {
   __ieee128 source = *p;
 
-  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
index 59f03a30484..9130c9714bf 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
@@ -10,6 +10,6 @@ test_data_class (double *p)
 {
   double source = *p;
 
-  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
index d3d94261d28..b863bb2bc27 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
@@ -10,6 +10,6 @@ test_data_class (float *p)
 {
   float source = *p;
 
-  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
index 210fa411f9e..83ddffa77a3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
@@ -10,6 +10,6 @@ test_data_class (double *p, const int condition_flag)
 {
   double source = *p;
 
-  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
index b66f0a27e8c..101a919c9e4 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
@@ -10,6 +10,6 @@ test_data_class (float *p, const int condition_flag)
 {
   float source = *p;
 
-  return scalar_test_data_class (source, condition_flag);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, condition_flag);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
index cfa9a9c3939..f87851c2c5f 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
@@ -13,6 +13,6 @@ test_data_class (__ieee128 *p)
 
   /* IEEE 128-bit floating point operations are only supported
      on 64-bit targets.  */
-  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
index 56ce5f9ebe7..448406c0d47 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector float *p)
 {
   __vector float source = *p;
 
-  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
index 11624c98a38..64a52a15439 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector double *p)
 {
   __vector double source = *p;
 
-  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
index 2c7e9deb7a2..5f35e0e368a 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector float *p, int condition_flag)
 {
   __vector float source = *p;
 
-  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
index 86eff8d66ba..bda2c6d9db3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector double *p, int condition_flag)
 {
   __vector double source = *p;
 
-  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
index 350b4c10205..4feb3918767 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
index 011d20039d0..ef4d6ad707b 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
index 28033dbac18..5a9ab5126fc 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
index 092b9c0f7c5..f1918a251c2 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
index 4b72fa8edc3..b353d63f5a5 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
index 15d7a352fdf..464dc66d457 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
index f6ed00a73dd..6e5e07b1c88 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
index 8e3954d6b93..d8760cefc94 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
index f6c0ede46cc..fed06bbbb6c 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
index d24f3982ee9..868146c8f53 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
index b6620c51f2a..de174998d21 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
index dc4c8ecdd00..1e5ff356ceb 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
index 1aee9efe919..b5f886d861a 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
index 6397aae3e56..ad840bf5465 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
index fc6b3568d09..586c86f2ab7 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
index b896865e6bb..dc01b7fc614 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
index edfac68b0e8..9ff41263531 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
index e7b50dc108e..5040ac87ed6 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
index c9431b5ea1a..a79e6b5dbb1 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
index 2fdb58f6748..5e9a93fd05e 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
index 275bf8d0ac2..ec2abc6499f 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
index e1da3d810ef..6f63d0f831f 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
index 44aaab201f9..4786be7bb48 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
index fb3331162c7..c406d4d1ca8 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
index 59471cfb645..d7b3b6f01ac 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
index c9e1721b3d6..bc9ced3ceb0 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
index d0d3f23c853..dcfe162c832 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
index 725cc5432b9..04d950e3df5 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
index c6ffd51d9f4..369312d84ea 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
index d279bfb5751..ca6c739a045 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
index b88b5a86bcb..9ee60cfe8e2 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
index b2073f56b05..9a9ff3899f2 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-1.c b/gcc/testsuite/gcc.target/powerpc/pr80315-1.c
index f37f1f169a2..7198611258f 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-1.c
@@ -10,6 +10,6 @@ main()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = __builtin_crypto_vshasigmaw (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = __builtin_crypto_vshasigmaw (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-2.c b/gcc/testsuite/gcc.target/powerpc/pr80315-2.c
index 0819a0511b7..0f77f775ad3 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-2.c
@@ -10,6 +10,6 @@ main ()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = __builtin_crypto_vshasigmad (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = __builtin_crypto_vshasigmad (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-3.c b/gcc/testsuite/gcc.target/powerpc/pr80315-3.c
index cc2e46cf5cb..398c512274d 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-3.c
@@ -12,6 +12,6 @@ main ()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return res;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-4.c b/gcc/testsuite/gcc.target/powerpc/pr80315-4.c
index ac12910741b..4326ff64c18 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-4.c
@@ -12,6 +12,6 @@ main ()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return res;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr82015.c b/gcc/testsuite/gcc.target/powerpc/pr82015.c
index ec939e96bb8..40f1c7d2a5c 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr82015.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr82015.c
@@ -5,10 +5,10 @@
 
 unsigned long foo_11(__vector __int128_t *p)
 {
-  return __builtin_unpack_vector_int128(*p, 11); /* { dg-error "argument 2 must be a 1-bit unsigned literal" } */
+  return __builtin_unpack_vector_int128(*p, 11); /* { dg-error "argument 2 must be a literal between 0 and 1, inclusive" } */
 }
 
 unsigned long foo_n(__vector __int128_t *p, unsigned long n)
 {
-  return __builtin_unpack_vector_int128(*p, n);	/* { dg-error "argument 2 must be a 1-bit unsigned literal" } */
+  return __builtin_unpack_vector_int128(*p, n);	/* { dg-error "argument 2 must be a literal between 0 and 1, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr91903.c b/gcc/testsuite/gcc.target/powerpc/pr91903.c
index 3045d07da7d..7f9470ee905 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr91903.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr91903.c
@@ -12,62 +12,62 @@ vector signed int retsi;
 
 void test_int(vector signed int a, const int b)
 {
-	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retf = vec_ctf(a,1);
 	retf = vec_ctf(a,31);
-	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 void test_uint(vector unsigned int a, const int b)
 {
-	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retf = vec_ctf(a,1);
 	retf = vec_ctf(a,31);
-	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 void test_longlong(vector signed long long a, const int b,int x)
 {
-	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal"  } */
-	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive"  } */
+	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retd = vec_ctf(a,1);
 	retd = vec_ctf(a,31);
-	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 void test_ulonglong(vector unsigned long long a, const int b,int x)
 {
-	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retd = vec_ctf(a,1);
 	retd = vec_ctf(a,31);
-	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 
 void test_cts_1(vector float a, const int b)
 {
-	retsi = vec_cts(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retsi = vec_cts(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retsi = vec_cts(a,1);
 	retsi = vec_cts(a,31);
-	retsi = vec_cts(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retsi = vec_cts(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c
index 10391b71008..62152c677ec 100644
--- a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c
+++ b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c
@@ -8,11 +8,11 @@ int main ()
      int arguments.  The builtins __builtin_set_fpscr_rn() also supports a
      variable as an argument but can't test variable value at compile time.  */
 
-  __builtin_mtfsb0(-1);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */
-  __builtin_mtfsb0(32);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */
+  __builtin_mtfsb0(-1);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */
+  __builtin_mtfsb0(32);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */
 
-  __builtin_mtfsb1(-1);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */
-  __builtin_mtfsb1(32);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */ 
+  __builtin_mtfsb1(-1);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */
+  __builtin_mtfsb1(32);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */ 
 
   __builtin_set_fpscr_rn(-1);  /* { dg-error "argument 1 must be a variable or a literal between 0 and 3, inclusive" } */ 
   __builtin_set_fpscr_rn(4);   /* { dg-error "argument 1 must be a variable or a literal between 0 and 3, inclusive" } */ 
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c
index 35700fcb364..d5ec14cf4ba 100644
--- a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c
+++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c
@@ -28,7 +28,7 @@ doTests00000001 (vector unsigned __int128 a_sources [],
 	  vector unsigned __int128 b = b_sources [j];
 	  vector unsigned __int128 c = c_sources [k];
 	  vector unsigned __int128 result;
-	  result = vec_ternarylogic (a, b, c, 0xfff); /* { dg-error "8-bit unsigned literal" } */
+	  result = vec_ternarylogic (a, b, c, 0xfff); /* { dg-error "literal between 0 and 255, inclusive" } */
 	  vector unsigned __int128 intended = (a & b & c);
 	  if (!vector_equal (result, intended))
 	    abort ();
@@ -47,7 +47,7 @@ doTests11100101 (vector unsigned __int128 a_sources [],
 	  vector unsigned __int128 b = b_sources [j];
 	  vector unsigned __int128 c = c_sources [k];
 	  vector unsigned __int128 result;
-	  result = vec_ternarylogic (a, b, c, -1); /* { dg-error "8-bit unsigned literal" } */
+	  result = vec_ternarylogic (a, b, c, -1); /* { dg-error "literal between 0 and 255, inclusive" } */
 	  vector unsigned __int128 intended = { 0 };
 	  // Supposed to be a ? c: nand (b,c)
 	  for (int l = 0; l < 1; l++)
@@ -80,7 +80,7 @@ doTests11110011 (vector unsigned __int128 a_sources [],
 	  vector unsigned __int128 b = b_sources [j];
 	  vector unsigned __int128 c = c_sources [k];
 	  vector unsigned __int128 result;
-	  result = vec_ternarylogic (a, b, c, i);  /* { dg-error "8-bit unsigned literal" } */
+	  result = vec_ternarylogic (a, b, c, i);  /* { dg-error "literal between 0 and 255, inclusive" } */
 	  vector unsigned __int128 intended = { 0 };
 	  for (int i = 0; i < 1; i++)
 	    intended [i] = b [i] | ~(a [i] & c [i]);
-- 
2.27.0


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

* [PATCH 4/8] rs6000: Consolidate target built-ins code
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
                   ` (2 preceding siblings ...)
  2022-01-28 17:50 ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-01-31 21:32   ` Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 5/8] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082] Bill Schmidt
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

Continuing with the refactoring effort, this patch moves as much of the
target-specific built-in support code into a new file, rs6000-builtin.cc.
However, we can't easily move the overloading support code out of
rs6000-c.cc, because the build machinery understands that as a special file
to be included with the C and C++ front ends.

This patch is just a straightforward move, with one exception.  I found
that the builtin_mode_to_type[] array is no longer used, so I also removed
all code having to do with it.

The code in rs6000-builtin.cc is organized in related sections:
 - General support functions
 - Initialization support
 - GIMPLE folding support
 - Expansion support

Overloading support remains in rs6000-c.cc.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-22  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config.gcc (powerpc*-*-*): Add rs6000-builtin.o to extra_objs.
	* config/rs6000/rs6000-builtin.cc: New file, containing code moved
	from other files.
	* config/rs6000/rs6000-call.cc (cpu_is_info): Move to
	rs6000-builtin.cc.
	(cpu_supports_info): Likewise.
	(rs6000_type_string): Likewise.
	(altivec_expand_predicate_builtin): Likewise.
	(rs6000_htm_spr_icode): Likewise.
	(altivec_expand_vec_init_builtin): Likewise.
	(get_element_number): Likewise.
	(altivec_expand_vec_set_builtin): Likewise.
	(altivec_expand_vec_ext_builtin): Likewise.
	(rs6000_invalid_builtin): Likewise.
	(rs6000_fold_builtin): Likewise.
	(fold_build_vec_cmp): Likewise.
	(fold_compare_helper): Likewise.
	(map_to_integral_tree_type): Likewise.
	(fold_mergehl_helper): Likewise.
	(fold_mergeeo_helper): Likewise.
	(rs6000_builtin_valid_without_lhs): Likewise.
	(rs6000_builtin_is_supported): Likewise.
	(rs6000_gimple_fold_mma_builtin): Likewise.
	(rs6000_gimple_fold_builtin): Likewise.
	(rs6000_expand_ldst_mask): Likewise.
	(cpu_expand_builtin): Likewise.
	(elemrev_icode): Likewise.
	(ldv_expand_builtin): Likewise.
	(lxvrse_expand_builtin): Likewise.
	(lxvrze_expand_builtin): Likewise.
	(stv_expand_builtin): Likewise.
	(mma_expand_builtin): Likewise.
	(htm_spr_num): Likewise.
	(htm_expand_builtin): Likewise.
	(rs6000_expand_builtin): Likewise.
	(rs6000_vector_type): Likewise.
	(rs6000_init_builtins): Likewise.  Remove initialization of
	builtin_mode_to_type entries.
	(rs6000_builtin_decl): Move to rs6000-builtin.cc.
	* config/rs6000/rs6000.cc (rs6000_builtin_mask_for_load): New
	external declaration.
	(rs6000_builtin_md_vectorized_function): Likewise.
	(rs6000_builtin_reciprocal): Likewise.
	(altivec_builtin_mask_for_load): Move to rs6000-builtin.cc.
	(rs6000_builtin_types): Likewise.
	(builtin_mode_to_type): Remove.
	(rs6000_builtin_mask_for_load): Move to rs6000-builtin.cc.  Remove
	static qualifier.
	(rs6000_builtin_md_vectorized_function): Likewise.
	(rs6000_builtin_reciprocal): Likewise.
	* config/rs6000/rs6000.h (builtin_mode_to_type): Remove.
	* config/rs6000/t-rs6000 (rs6000-builtin.o): New target.
---
 gcc/config.gcc                      |    2 +-
 gcc/config/rs6000/rs6000-builtin.cc | 3712 +++++++++++++++++++++++++++
 gcc/config/rs6000/rs6000-call.cc    | 3524 -------------------------
 gcc/config/rs6000/rs6000.cc         |  163 +-
 gcc/config/rs6000/rs6000.h          |    1 -
 gcc/config/rs6000/t-rs6000          |    4 +
 6 files changed, 3721 insertions(+), 3685 deletions(-)
 create mode 100644 gcc/config/rs6000/rs6000-builtin.cc

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 2c4266ce7b0..b7fdcbc148e 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -485,7 +485,7 @@ powerpc*-*-*)
 	cpu_type=rs6000
 	extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
 	extra_objs="${extra_objs} rs6000-call.o rs6000-pcrel-opt.o"
-	extra_objs="${extra_objs} rs6000-builtins.o"
+	extra_objs="${extra_objs} rs6000-builtins.o rs6000-builtin.o"
 	extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h"
 	extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h"
 	extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h"
diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
new file mode 100644
index 00000000000..191a6108a5e
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -0,0 +1,3712 @@
+/* Target-specific built-in function support for the Power architecture.
+   See also rs6000-c.c, rs6000-gen-builtins.c, rs6000-builtins.def, and
+   rs6000-overloads.def.
+   Note that "normal" builtins (generic math functions, etc.) are handled
+   in rs6000.c.
+
+   Copyright (C) 2002-2022 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "backend.h"
+#include "rtl.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "gimple.h"
+#include "tm_p.h"
+#include "optabs.h"
+#include "recog.h"
+#include "diagnostic-core.h"
+#include "fold-const.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "varasm.h"
+#include "explow.h"
+#include "expr.h"
+#include "langhooks.h"
+#include "gimplify.h"
+#include "gimple-fold.h"
+#include "gimple-iterator.h"
+#include "ssa.h"
+#include "tree-ssa-propagate.h"
+#include "builtins.h"
+#include "tree-vector-builder.h"
+#if TARGET_XCOFF
+#include "xcoffout.h"  /* get declarations of xcoff_*_section_name */
+#endif
+#include "ppc-auxv.h"
+#include "rs6000-internal.h"
+
+/* Built in types.  */
+tree rs6000_builtin_types[RS6000_BTI_MAX];
+
+/* Support targetm.vectorize.builtin_mask_for_load.  */
+tree altivec_builtin_mask_for_load;
+
+/* **** General support functions. **** */
+
+/* Raise an error message for a builtin function that is called without the
+   appropriate target options being set.  */
+
+void
+rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
+{
+  size_t j = (size_t) fncode;
+  const char *name = rs6000_builtin_info[j].bifname;
+
+  switch (rs6000_builtin_info[j].enable)
+    {
+    case ENB_P5:
+      error ("%qs requires the %qs option", name, "-mcpu=power5");
+      break;
+    case ENB_P6:
+      error ("%qs requires the %qs option", name, "-mcpu=power6");
+      break;
+    case ENB_P6_64:
+      error ("%qs requires the %qs option and either the %qs or %qs option",
+	     name, "-mcpu=power6", "-m64", "-mpowerpc64");
+      break;
+    case ENB_ALTIVEC:
+      error ("%qs requires the %qs option", name, "-maltivec");
+      break;
+    case ENB_CELL:
+      error ("%qs requires the %qs option", name, "-mcpu=cell");
+      break;
+    case ENB_VSX:
+      error ("%qs requires the %qs option", name, "-mvsx");
+      break;
+    case ENB_P7:
+      error ("%qs requires the %qs option", name, "-mcpu=power7");
+      break;
+    case ENB_P7_64:
+      error ("%qs requires the %qs option and either the %qs or %qs option",
+	     name, "-mcpu=power7", "-m64", "-mpowerpc64");
+      break;
+    case ENB_P8:
+      error ("%qs requires the %qs option", name, "-mcpu=power8");
+      break;
+    case ENB_P8V:
+      error ("%qs requires the %qs and %qs options", name, "-mcpu=power8",
+	     "-mvsx");
+      break;
+    case ENB_P9:
+      error ("%qs requires the %qs option", name, "-mcpu=power9");
+      break;
+    case ENB_P9_64:
+      error ("%qs requires the %qs option and either the %qs or %qs option",
+	     name, "-mcpu=power9", "-m64", "-mpowerpc64");
+      break;
+    case ENB_P9V:
+      error ("%qs requires the %qs and %qs options", name, "-mcpu=power9",
+	     "-mvsx");
+      break;
+    case ENB_IEEE128_HW:
+      error ("%qs requires quad-precision floating-point arithmetic", name);
+      break;
+    case ENB_DFP:
+      error ("%qs requires the %qs option", name, "-mhard-dfp");
+      break;
+    case ENB_CRYPTO:
+      error ("%qs requires the %qs option", name, "-mcrypto");
+      break;
+    case ENB_HTM:
+      error ("%qs requires the %qs option", name, "-mhtm");
+      break;
+    case ENB_P10:
+      error ("%qs requires the %qs option", name, "-mcpu=power10");
+      break;
+    case ENB_P10_64:
+      error ("%qs requires the %qs option and either the %qs or %qs option",
+	     name, "-mcpu=power10", "-m64", "-mpowerpc64");
+      break;
+    case ENB_MMA:
+      error ("%qs requires the %qs option", name, "-mmma");
+      break;
+    default:
+    case ENB_ALWAYS:
+      gcc_unreachable ();
+    }
+}
+
+/* Check whether a builtin function is supported in this target
+   configuration.  */
+bool
+rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
+{
+  switch (rs6000_builtin_info[(size_t) fncode].enable)
+    {
+    case ENB_ALWAYS:
+      return true;
+    case ENB_P5:
+      return TARGET_POPCNTB;
+    case ENB_P6:
+      return TARGET_CMPB;
+    case ENB_P6_64:
+      return TARGET_CMPB && TARGET_POWERPC64;
+    case ENB_P7:
+      return TARGET_POPCNTD;
+    case ENB_P7_64:
+      return TARGET_POPCNTD && TARGET_POWERPC64;
+    case ENB_P8:
+      return TARGET_DIRECT_MOVE;
+    case ENB_P8V:
+      return TARGET_P8_VECTOR;
+    case ENB_P9:
+      return TARGET_MODULO;
+    case ENB_P9_64:
+      return TARGET_MODULO && TARGET_POWERPC64;
+    case ENB_P9V:
+      return TARGET_P9_VECTOR;
+    case ENB_P10:
+      return TARGET_POWER10;
+    case ENB_P10_64:
+      return TARGET_POWER10 && TARGET_POWERPC64;
+    case ENB_ALTIVEC:
+      return TARGET_ALTIVEC;
+    case ENB_VSX:
+      return TARGET_VSX;
+    case ENB_CELL:
+      return TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL;
+    case ENB_IEEE128_HW:
+      return TARGET_FLOAT128_HW;
+    case ENB_DFP:
+      return TARGET_DFP;
+    case ENB_CRYPTO:
+      return TARGET_CRYPTO;
+    case ENB_HTM:
+      return TARGET_HTM;
+    case ENB_MMA:
+      return TARGET_MMA;
+    default:
+      gcc_unreachable ();
+    }
+  gcc_unreachable ();
+}
+
+/* Target hook for early folding of built-ins, shamelessly stolen
+   from ia64.cc.  */
+
+tree
+rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
+		     int n_args ATTRIBUTE_UNUSED,
+		     tree *args ATTRIBUTE_UNUSED,
+		     bool ignore ATTRIBUTE_UNUSED)
+{
+#ifdef SUBTARGET_FOLD_BUILTIN
+  return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
+#else
+  return NULL_TREE;
+#endif
+}
+
+tree
+rs6000_builtin_decl (unsigned code, bool /* initialize_p */)
+{
+  rs6000_gen_builtins fcode = (rs6000_gen_builtins) code;
+
+  if (fcode >= RS6000_OVLD_MAX)
+    return error_mark_node;
+
+  return rs6000_builtin_decls[code];
+}
+
+/* Implement targetm.vectorize.builtin_mask_for_load.  */
+tree
+rs6000_builtin_mask_for_load (void)
+{
+  /* Don't use lvsl/vperm for P8 and similarly efficient machines.  */
+  if ((TARGET_ALTIVEC && !TARGET_VSX)
+      || (TARGET_VSX && !TARGET_EFFICIENT_UNALIGNED_VSX))
+    return altivec_builtin_mask_for_load;
+  else
+    return 0;
+}
+
+/* Implement targetm.vectorize.builtin_md_vectorized_function.  */
+
+tree
+rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
+				       tree type_in)
+{
+  machine_mode in_mode, out_mode;
+  int in_n, out_n;
+
+  if (TARGET_DEBUG_BUILTIN)
+    fprintf (stderr,
+	     "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n",
+	     IDENTIFIER_POINTER (DECL_NAME (fndecl)),
+	     GET_MODE_NAME (TYPE_MODE (type_out)),
+	     GET_MODE_NAME (TYPE_MODE (type_in)));
+
+  /* TODO: Should this be gcc_assert?  */
+  if (TREE_CODE (type_out) != VECTOR_TYPE
+      || TREE_CODE (type_in) != VECTOR_TYPE)
+    return NULL_TREE;
+
+  out_mode = TYPE_MODE (TREE_TYPE (type_out));
+  out_n = TYPE_VECTOR_SUBPARTS (type_out);
+  in_mode = TYPE_MODE (TREE_TYPE (type_in));
+  in_n = TYPE_VECTOR_SUBPARTS (type_in);
+
+  enum rs6000_gen_builtins fn
+    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
+  switch (fn)
+    {
+    case RS6000_BIF_RSQRTF:
+      if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
+	  && out_mode == SFmode && out_n == 4
+	  && in_mode == SFmode && in_n == 4)
+	return rs6000_builtin_decls[RS6000_BIF_VRSQRTFP];
+      break;
+    case RS6000_BIF_RSQRT:
+      if (VECTOR_UNIT_VSX_P (V2DFmode)
+	  && out_mode == DFmode && out_n == 2
+	  && in_mode == DFmode && in_n == 2)
+	return rs6000_builtin_decls[RS6000_BIF_RSQRT_2DF];
+      break;
+    case RS6000_BIF_RECIPF:
+      if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
+	  && out_mode == SFmode && out_n == 4
+	  && in_mode == SFmode && in_n == 4)
+	return rs6000_builtin_decls[RS6000_BIF_VRECIPFP];
+      break;
+    case RS6000_BIF_RECIP:
+      if (VECTOR_UNIT_VSX_P (V2DFmode)
+	  && out_mode == DFmode && out_n == 2
+	  && in_mode == DFmode && in_n == 2)
+	return rs6000_builtin_decls[RS6000_BIF_RECIP_V2DF];
+      break;
+    default:
+      break;
+    }
+
+  machine_mode in_vmode = TYPE_MODE (type_in);
+  machine_mode out_vmode = TYPE_MODE (type_out);
+
+  /* Power10 supported vectorized built-in functions.  */
+  if (TARGET_POWER10
+      && in_vmode == out_vmode
+      && VECTOR_UNIT_ALTIVEC_OR_VSX_P (in_vmode))
+    {
+      machine_mode exp_mode = DImode;
+      machine_mode exp_vmode = V2DImode;
+      enum rs6000_gen_builtins bif;
+      switch (fn)
+	{
+	case RS6000_BIF_DIVWE:
+	case RS6000_BIF_DIVWEU:
+	  exp_mode = SImode;
+	  exp_vmode = V4SImode;
+	  if (fn == RS6000_BIF_DIVWE)
+	    bif = RS6000_BIF_VDIVESW;
+	  else
+	    bif = RS6000_BIF_VDIVEUW;
+	  break;
+	case RS6000_BIF_DIVDE:
+	case RS6000_BIF_DIVDEU:
+	  if (fn == RS6000_BIF_DIVDE)
+	    bif = RS6000_BIF_VDIVESD;
+	  else
+	    bif = RS6000_BIF_VDIVEUD;
+	  break;
+	case RS6000_BIF_CFUGED:
+	  bif = RS6000_BIF_VCFUGED;
+	  break;
+	case RS6000_BIF_CNTLZDM:
+	  bif = RS6000_BIF_VCLZDM;
+	  break;
+	case RS6000_BIF_CNTTZDM:
+	  bif = RS6000_BIF_VCTZDM;
+	  break;
+	case RS6000_BIF_PDEPD:
+	  bif = RS6000_BIF_VPDEPD;
+	  break;
+	case RS6000_BIF_PEXTD:
+	  bif = RS6000_BIF_VPEXTD;
+	  break;
+	default:
+	  return NULL_TREE;
+	}
+
+      if (in_mode == exp_mode && in_vmode == exp_vmode)
+	return rs6000_builtin_decls[bif];
+    }
+
+  return NULL_TREE;
+}
+
+/* Returns a code for a target-specific builtin that implements
+   reciprocal of the function, or NULL_TREE if not available.  */
+
+tree
+rs6000_builtin_reciprocal (tree fndecl)
+{
+  switch (DECL_MD_FUNCTION_CODE (fndecl))
+    {
+    case RS6000_BIF_XVSQRTDP:
+      if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
+	return NULL_TREE;
+
+      return rs6000_builtin_decls[RS6000_BIF_RSQRT_2DF];
+
+    case RS6000_BIF_XVSQRTSP:
+      if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
+	return NULL_TREE;
+
+      return rs6000_builtin_decls[RS6000_BIF_RSQRT_4SF];
+
+    default:
+      return NULL_TREE;
+    }
+}
+
+/* **** Initialization support. **** */
+
+/* Create a builtin vector type with a name.  Taking care not to give
+   the canonical type a name.  */
+
+static tree
+rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts)
+{
+  tree result = build_vector_type (elt_type, num_elts);
+
+  /* Copy so we don't give the canonical type a name.  */
+  result = build_variant_type_copy (result);
+
+  add_builtin_type (name, result);
+
+  return result;
+}
+
+/* Debug utility to translate a type node to a single textual token.  */
+static
+const char *rs6000_type_string (tree type_node)
+{
+  if (type_node == void_type_node)
+    return "void";
+  else if (type_node == long_integer_type_node)
+    return "long";
+  else if (type_node == long_unsigned_type_node)
+    return "ulong";
+  else if (type_node == long_long_integer_type_node)
+    return "longlong";
+  else if (type_node == long_long_unsigned_type_node)
+    return "ulonglong";
+  else if (type_node == bool_V2DI_type_node)
+    return "vbll";
+  else if (type_node == bool_V4SI_type_node)
+    return "vbi";
+  else if (type_node == bool_V8HI_type_node)
+    return "vbs";
+  else if (type_node == bool_V16QI_type_node)
+    return "vbc";
+  else if (type_node == bool_int_type_node)
+    return "bool";
+  else if (type_node == dfloat64_type_node)
+    return "_Decimal64";
+  else if (type_node == double_type_node)
+    return "double";
+  else if (type_node == intDI_type_node)
+    return "sll";
+  else if (type_node == intHI_type_node)
+    return "ss";
+  else if (type_node == ibm128_float_type_node)
+    return "__ibm128";
+  else if (type_node == opaque_V4SI_type_node)
+    return "opaque";
+  else if (POINTER_TYPE_P (type_node))
+    return "void*";
+  else if (type_node == intQI_type_node || type_node == char_type_node)
+    return "sc";
+  else if (type_node == dfloat32_type_node)
+    return "_Decimal32";
+  else if (type_node == float_type_node)
+    return "float";
+  else if (type_node == intSI_type_node || type_node == integer_type_node)
+    return "si";
+  else if (type_node == dfloat128_type_node)
+    return "_Decimal128";
+  else if (type_node == long_double_type_node)
+    return "longdouble";
+  else if (type_node == intTI_type_node)
+    return "sq";
+  else if (type_node == unsigned_intDI_type_node)
+    return "ull";
+  else if (type_node == unsigned_intHI_type_node)
+    return "us";
+  else if (type_node == unsigned_intQI_type_node)
+    return "uc";
+  else if (type_node == unsigned_intSI_type_node)
+    return "ui";
+  else if (type_node == unsigned_intTI_type_node)
+    return "uq";
+  else if (type_node == unsigned_V1TI_type_node)
+    return "vuq";
+  else if (type_node == unsigned_V2DI_type_node)
+    return "vull";
+  else if (type_node == unsigned_V4SI_type_node)
+    return "vui";
+  else if (type_node == unsigned_V8HI_type_node)
+    return "vus";
+  else if (type_node == unsigned_V16QI_type_node)
+    return "vuc";
+  else if (type_node == V16QI_type_node)
+    return "vsc";
+  else if (type_node == V1TI_type_node)
+    return "vsq";
+  else if (type_node == V2DF_type_node)
+    return "vd";
+  else if (type_node == V2DI_type_node)
+    return "vsll";
+  else if (type_node == V4SF_type_node)
+    return "vf";
+  else if (type_node == V4SI_type_node)
+    return "vsi";
+  else if (type_node == V8HI_type_node)
+    return "vss";
+  else if (type_node == pixel_V8HI_type_node)
+    return "vp";
+  else if (type_node == pcvoid_type_node)
+    return "voidc*";
+  else if (type_node == float128_type_node)
+    return "_Float128";
+  else if (type_node == vector_pair_type_node)
+    return "__vector_pair";
+  else if (type_node == vector_quad_type_node)
+    return "__vector_quad";
+
+  return "unknown";
+}
+
+void
+rs6000_init_builtins (void)
+{
+  tree tdecl;
+  tree t;
+
+  if (TARGET_DEBUG_BUILTIN)
+    fprintf (stderr, "rs6000_init_builtins%s%s\n",
+	     (TARGET_ALTIVEC)	   ? ", altivec" : "",
+	     (TARGET_VSX)	   ? ", vsx"	 : "");
+
+  V2DI_type_node = rs6000_vector_type ("__vector long long",
+				       long_long_integer_type_node, 2);
+  ptr_V2DI_type_node
+    = build_pointer_type (build_qualified_type (V2DI_type_node,
+						TYPE_QUAL_CONST));
+
+  V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2);
+  ptr_V2DF_type_node
+    = build_pointer_type (build_qualified_type (V2DF_type_node,
+						TYPE_QUAL_CONST));
+
+  V4SI_type_node = rs6000_vector_type ("__vector signed int",
+				       intSI_type_node, 4);
+  ptr_V4SI_type_node
+    = build_pointer_type (build_qualified_type (V4SI_type_node,
+						TYPE_QUAL_CONST));
+
+  V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4);
+  ptr_V4SF_type_node
+    = build_pointer_type (build_qualified_type (V4SF_type_node,
+						TYPE_QUAL_CONST));
+
+  V8HI_type_node = rs6000_vector_type ("__vector signed short",
+				       intHI_type_node, 8);
+  ptr_V8HI_type_node
+    = build_pointer_type (build_qualified_type (V8HI_type_node,
+						TYPE_QUAL_CONST));
+
+  V16QI_type_node = rs6000_vector_type ("__vector signed char",
+					intQI_type_node, 16);
+  ptr_V16QI_type_node
+    = build_pointer_type (build_qualified_type (V16QI_type_node,
+						TYPE_QUAL_CONST));
+
+  unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char",
+					unsigned_intQI_type_node, 16);
+  ptr_unsigned_V16QI_type_node
+    = build_pointer_type (build_qualified_type (unsigned_V16QI_type_node,
+						TYPE_QUAL_CONST));
+
+  unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short",
+				       unsigned_intHI_type_node, 8);
+  ptr_unsigned_V8HI_type_node
+    = build_pointer_type (build_qualified_type (unsigned_V8HI_type_node,
+						TYPE_QUAL_CONST));
+
+  unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int",
+				       unsigned_intSI_type_node, 4);
+  ptr_unsigned_V4SI_type_node
+    = build_pointer_type (build_qualified_type (unsigned_V4SI_type_node,
+						TYPE_QUAL_CONST));
+
+  unsigned_V2DI_type_node
+    = rs6000_vector_type ("__vector unsigned long long",
+			  long_long_unsigned_type_node, 2);
+
+  ptr_unsigned_V2DI_type_node
+    = build_pointer_type (build_qualified_type (unsigned_V2DI_type_node,
+						TYPE_QUAL_CONST));
+
+  opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
+
+  const_str_type_node
+    = build_pointer_type (build_qualified_type (char_type_node,
+						TYPE_QUAL_CONST));
+
+  /* We use V1TI mode as a special container to hold __int128_t items that
+     must live in VSX registers.  */
+  if (intTI_type_node)
+    {
+      V1TI_type_node = rs6000_vector_type ("__vector __int128",
+					   intTI_type_node, 1);
+      ptr_V1TI_type_node
+	= build_pointer_type (build_qualified_type (V1TI_type_node,
+						    TYPE_QUAL_CONST));
+      unsigned_V1TI_type_node
+	= rs6000_vector_type ("__vector unsigned __int128",
+			      unsigned_intTI_type_node, 1);
+      ptr_unsigned_V1TI_type_node
+	= build_pointer_type (build_qualified_type (unsigned_V1TI_type_node,
+						    TYPE_QUAL_CONST));
+    }
+
+  /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
+     types, especially in C++ land.  Similarly, 'vector pixel' is distinct from
+     'vector unsigned short'.  */
+
+  bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
+  bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+  bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
+  bool_long_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
+  pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+
+  long_integer_type_internal_node = long_integer_type_node;
+  long_unsigned_type_internal_node = long_unsigned_type_node;
+  long_long_integer_type_internal_node = long_long_integer_type_node;
+  long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
+  intQI_type_internal_node = intQI_type_node;
+  uintQI_type_internal_node = unsigned_intQI_type_node;
+  intHI_type_internal_node = intHI_type_node;
+  uintHI_type_internal_node = unsigned_intHI_type_node;
+  intSI_type_internal_node = intSI_type_node;
+  uintSI_type_internal_node = unsigned_intSI_type_node;
+  intDI_type_internal_node = intDI_type_node;
+  uintDI_type_internal_node = unsigned_intDI_type_node;
+  intTI_type_internal_node = intTI_type_node;
+  uintTI_type_internal_node = unsigned_intTI_type_node;
+  float_type_internal_node = float_type_node;
+  double_type_internal_node = double_type_node;
+  long_double_type_internal_node = long_double_type_node;
+  dfloat64_type_internal_node = dfloat64_type_node;
+  dfloat128_type_internal_node = dfloat128_type_node;
+  void_type_internal_node = void_type_node;
+
+  ptr_intQI_type_node
+    = build_pointer_type (build_qualified_type (intQI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_uintQI_type_node
+    = build_pointer_type (build_qualified_type (uintQI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_intHI_type_node
+    = build_pointer_type (build_qualified_type (intHI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_uintHI_type_node
+    = build_pointer_type (build_qualified_type (uintHI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_intSI_type_node
+    = build_pointer_type (build_qualified_type (intSI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_uintSI_type_node
+    = build_pointer_type (build_qualified_type (uintSI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_intDI_type_node
+    = build_pointer_type (build_qualified_type (intDI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_uintDI_type_node
+    = build_pointer_type (build_qualified_type (uintDI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_intTI_type_node
+    = build_pointer_type (build_qualified_type (intTI_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_uintTI_type_node
+    = build_pointer_type (build_qualified_type (uintTI_type_internal_node,
+						TYPE_QUAL_CONST));
+
+  t = build_qualified_type (long_integer_type_internal_node, TYPE_QUAL_CONST);
+  ptr_long_integer_type_node = build_pointer_type (t);
+
+  t = build_qualified_type (long_unsigned_type_internal_node, TYPE_QUAL_CONST);
+  ptr_long_unsigned_type_node = build_pointer_type (t);
+
+  ptr_float_type_node
+    = build_pointer_type (build_qualified_type (float_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_double_type_node
+    = build_pointer_type (build_qualified_type (double_type_internal_node,
+						TYPE_QUAL_CONST));
+  ptr_long_double_type_node
+    = build_pointer_type (build_qualified_type (long_double_type_internal_node,
+						TYPE_QUAL_CONST));
+  if (dfloat64_type_node)
+    {
+      t = build_qualified_type (dfloat64_type_internal_node, TYPE_QUAL_CONST);
+      ptr_dfloat64_type_node = build_pointer_type (t);
+    }
+  else
+    ptr_dfloat64_type_node = NULL;
+
+  if (dfloat128_type_node)
+    {
+      t = build_qualified_type (dfloat128_type_internal_node, TYPE_QUAL_CONST);
+      ptr_dfloat128_type_node = build_pointer_type (t);
+    }
+  else
+    ptr_dfloat128_type_node = NULL;
+
+  t = build_qualified_type (long_long_integer_type_internal_node,
+			    TYPE_QUAL_CONST);
+  ptr_long_long_integer_type_node  = build_pointer_type (t);
+
+  t = build_qualified_type (long_long_unsigned_type_internal_node,
+			    TYPE_QUAL_CONST);
+  ptr_long_long_unsigned_type_node = build_pointer_type (t);
+
+  /* 128-bit floating point support.  KFmode is IEEE 128-bit floating point.
+     IFmode is the IBM extended 128-bit format that is a pair of doubles.
+     TFmode will be either IEEE 128-bit floating point or the IBM double-double
+     format that uses a pair of doubles, depending on the switches and
+     defaults.
+
+     If we don't support for either 128-bit IBM double double or IEEE 128-bit
+     floating point, we need make sure the type is non-zero or else self-test
+     fails during bootstrap.
+
+     Always create __ibm128 as a separate type, even if the current long double
+     format is IBM extended double.
+
+     For IEEE 128-bit floating point, always create the type __ieee128.  If the
+     user used -mfloat128, rs6000-c.cc will create a define from __float128 to
+     __ieee128.  */
+  if (TARGET_FLOAT128_TYPE)
+    {
+      if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
+	ibm128_float_type_node = long_double_type_node;
+      else
+	{
+	  ibm128_float_type_node = make_node (REAL_TYPE);
+	  TYPE_PRECISION (ibm128_float_type_node) = 128;
+	  SET_TYPE_MODE (ibm128_float_type_node, IFmode);
+	  layout_type (ibm128_float_type_node);
+	}
+      t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST);
+      ptr_ibm128_float_type_node = build_pointer_type (t);
+      lang_hooks.types.register_builtin_type (ibm128_float_type_node,
+					      "__ibm128");
+
+      if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
+	ieee128_float_type_node = long_double_type_node;
+      else
+	ieee128_float_type_node = float128_type_node;
+      t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST);
+      ptr_ieee128_float_type_node = build_pointer_type (t);
+      lang_hooks.types.register_builtin_type (ieee128_float_type_node,
+					      "__ieee128");
+    }
+
+  else
+    ieee128_float_type_node = ibm128_float_type_node = long_double_type_node;
+
+  /* Vector pair and vector quad support.  */
+  vector_pair_type_node = make_node (OPAQUE_TYPE);
+  SET_TYPE_MODE (vector_pair_type_node, OOmode);
+  TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE (OOmode));
+  TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode);
+  TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE (OOmode));
+  SET_TYPE_ALIGN (vector_pair_type_node, 256);
+  TYPE_USER_ALIGN (vector_pair_type_node) = 0;
+  lang_hooks.types.register_builtin_type (vector_pair_type_node,
+					  "__vector_pair");
+  t = build_qualified_type (vector_pair_type_node, TYPE_QUAL_CONST);
+  ptr_vector_pair_type_node = build_pointer_type (t);
+
+  vector_quad_type_node = make_node (OPAQUE_TYPE);
+  SET_TYPE_MODE (vector_quad_type_node, XOmode);
+  TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE (XOmode));
+  TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode);
+  TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE (XOmode));
+  SET_TYPE_ALIGN (vector_quad_type_node, 512);
+  TYPE_USER_ALIGN (vector_quad_type_node) = 0;
+  lang_hooks.types.register_builtin_type (vector_quad_type_node,
+					  "__vector_quad");
+  t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST);
+  ptr_vector_quad_type_node = build_pointer_type (t);
+
+  tdecl = add_builtin_type ("__bool char", bool_char_type_node);
+  TYPE_NAME (bool_char_type_node) = tdecl;
+
+  tdecl = add_builtin_type ("__bool short", bool_short_type_node);
+  TYPE_NAME (bool_short_type_node) = tdecl;
+
+  tdecl = add_builtin_type ("__bool int", bool_int_type_node);
+  TYPE_NAME (bool_int_type_node) = tdecl;
+
+  tdecl = add_builtin_type ("__pixel", pixel_type_node);
+  TYPE_NAME (pixel_type_node) = tdecl;
+
+  bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char",
+					     bool_char_type_node, 16);
+  ptr_bool_V16QI_type_node
+    = build_pointer_type (build_qualified_type (bool_V16QI_type_node,
+						TYPE_QUAL_CONST));
+
+  bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short",
+					    bool_short_type_node, 8);
+  ptr_bool_V8HI_type_node
+    = build_pointer_type (build_qualified_type (bool_V8HI_type_node,
+						TYPE_QUAL_CONST));
+
+  bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int",
+					    bool_int_type_node, 4);
+  ptr_bool_V4SI_type_node
+    = build_pointer_type (build_qualified_type (bool_V4SI_type_node,
+						TYPE_QUAL_CONST));
+
+  bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
+					    ? "__vector __bool long"
+					    : "__vector __bool long long",
+					    bool_long_long_type_node, 2);
+  ptr_bool_V2DI_type_node
+    = build_pointer_type (build_qualified_type (bool_V2DI_type_node,
+						TYPE_QUAL_CONST));
+
+  bool_V1TI_type_node = rs6000_vector_type ("__vector __bool __int128",
+					    intTI_type_node, 1);
+  ptr_bool_V1TI_type_node
+    = build_pointer_type (build_qualified_type (bool_V1TI_type_node,
+						TYPE_QUAL_CONST));
+
+  pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel",
+					     pixel_type_node, 8);
+  ptr_pixel_V8HI_type_node
+    = build_pointer_type (build_qualified_type (pixel_V8HI_type_node,
+						TYPE_QUAL_CONST));
+  pcvoid_type_node
+    = build_pointer_type (build_qualified_type (void_type_node,
+						TYPE_QUAL_CONST));
+
+  /* Execute the autogenerated initialization code for builtins.  */
+  rs6000_init_generated_builtins ();
+
+  if (TARGET_DEBUG_BUILTIN)
+    {
+      fprintf (stderr, "\nAutogenerated built-in functions:\n\n");
+      for (int i = 1; i < (int) RS6000_BIF_MAX; i++)
+	{
+	  bif_enable e = rs6000_builtin_info[i].enable;
+	  if (e == ENB_P5 && !TARGET_POPCNTB)
+	    continue;
+	  if (e == ENB_P6 && !TARGET_CMPB)
+	    continue;
+	  if (e == ENB_P6_64 && !(TARGET_CMPB && TARGET_POWERPC64))
+	    continue;
+	  if (e == ENB_ALTIVEC && !TARGET_ALTIVEC)
+	    continue;
+	  if (e == ENB_VSX && !TARGET_VSX)
+	    continue;
+	  if (e == ENB_P7 && !TARGET_POPCNTD)
+	    continue;
+	  if (e == ENB_P7_64 && !(TARGET_POPCNTD && TARGET_POWERPC64))
+	    continue;
+	  if (e == ENB_P8 && !TARGET_DIRECT_MOVE)
+	    continue;
+	  if (e == ENB_P8V && !TARGET_P8_VECTOR)
+	    continue;
+	  if (e == ENB_P9 && !TARGET_MODULO)
+	    continue;
+	  if (e == ENB_P9_64 && !(TARGET_MODULO && TARGET_POWERPC64))
+	    continue;
+	  if (e == ENB_P9V && !TARGET_P9_VECTOR)
+	    continue;
+	  if (e == ENB_IEEE128_HW && !TARGET_FLOAT128_HW)
+	    continue;
+	  if (e == ENB_DFP && !TARGET_DFP)
+	    continue;
+	  if (e == ENB_CRYPTO && !TARGET_CRYPTO)
+	    continue;
+	  if (e == ENB_HTM && !TARGET_HTM)
+	    continue;
+	  if (e == ENB_P10 && !TARGET_POWER10)
+	    continue;
+	  if (e == ENB_P10_64 && !(TARGET_POWER10 && TARGET_POWERPC64))
+	    continue;
+	  if (e == ENB_MMA && !TARGET_MMA)
+	    continue;
+	  tree fntype = rs6000_builtin_info[i].fntype;
+	  tree t = TREE_TYPE (fntype);
+	  fprintf (stderr, "%s %s (", rs6000_type_string (t),
+		   rs6000_builtin_info[i].bifname);
+	  t = TYPE_ARG_TYPES (fntype);
+	  while (t && TREE_VALUE (t) != void_type_node)
+	    {
+	      fprintf (stderr, "%s",
+		       rs6000_type_string (TREE_VALUE (t)));
+	      t = TREE_CHAIN (t);
+	      if (t && TREE_VALUE (t) != void_type_node)
+		fprintf (stderr, ", ");
+	    }
+	  fprintf (stderr, "); %s [%4d]\n",
+		   rs6000_builtin_info[i].attr_string, (int) i);
+	}
+      fprintf (stderr, "\nEnd autogenerated built-in functions.\n\n\n");
+     }
+
+  if (TARGET_XCOFF)
+    {
+      /* AIX libm provides clog as __clog.  */
+      if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
+	set_user_assembler_name (tdecl, "__clog");
+
+      /* When long double is 64 bit, some long double builtins of libc
+	 functions (like __builtin_frexpl) must call the double version
+	 (frexp) not the long double version (frexpl) that expects a 128 bit
+	 argument.  */
+      if (! TARGET_LONG_DOUBLE_128)
+	{
+	  if ((tdecl = builtin_decl_explicit (BUILT_IN_FMODL)) != NULL_TREE)
+	    set_user_assembler_name (tdecl, "fmod");
+	  if ((tdecl = builtin_decl_explicit (BUILT_IN_FREXPL)) != NULL_TREE)
+	    set_user_assembler_name (tdecl, "frexp");
+	  if ((tdecl = builtin_decl_explicit (BUILT_IN_LDEXPL)) != NULL_TREE)
+	    set_user_assembler_name (tdecl, "ldexp");
+	  if ((tdecl = builtin_decl_explicit (BUILT_IN_MODFL)) != NULL_TREE)
+	    set_user_assembler_name (tdecl, "modf");
+	}
+    }
+
+  altivec_builtin_mask_for_load
+    = rs6000_builtin_decls[RS6000_BIF_MASK_FOR_LOAD];
+
+#ifdef SUBTARGET_INIT_BUILTINS
+  SUBTARGET_INIT_BUILTINS;
+#endif
+
+  return;
+}
+
+/* **** GIMPLE folding support. **** */
+
+/* Helper function to handle the gimple folding of a vector compare
+   operation.  This sets up true/false vectors, and uses the
+   VEC_COND_EXPR operation.
+   CODE indicates which comparison is to be made. (EQ, GT, ...).
+   TYPE indicates the type of the result.
+   Code is inserted before GSI.  */
+static tree
+fold_build_vec_cmp (tree_code code, tree type, tree arg0, tree arg1,
+		    gimple_stmt_iterator *gsi)
+{
+  tree cmp_type = truth_type_for (type);
+  tree zero_vec = build_zero_cst (type);
+  tree minus_one_vec = build_minus_one_cst (type);
+  tree temp = create_tmp_reg_or_ssa_name (cmp_type);
+  gimple *g = gimple_build_assign (temp, code, arg0, arg1);
+  gsi_insert_before (gsi, g, GSI_SAME_STMT);
+  return fold_build3 (VEC_COND_EXPR, type, temp, minus_one_vec, zero_vec);
+}
+
+/* Helper function to handle the in-between steps for the
+   vector compare built-ins.  */
+static void
+fold_compare_helper (gimple_stmt_iterator *gsi, tree_code code, gimple *stmt)
+{
+  tree arg0 = gimple_call_arg (stmt, 0);
+  tree arg1 = gimple_call_arg (stmt, 1);
+  tree lhs = gimple_call_lhs (stmt);
+  tree cmp = fold_build_vec_cmp (code, TREE_TYPE (lhs), arg0, arg1, gsi);
+  gimple *g = gimple_build_assign (lhs, cmp);
+  gimple_set_location (g, gimple_location (stmt));
+  gsi_replace (gsi, g, true);
+}
+
+/* Helper function to map V2DF and V4SF types to their
+ integral equivalents (V2DI and V4SI).  */
+tree map_to_integral_tree_type (tree input_tree_type)
+{
+  if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type)))
+    return input_tree_type;
+  else
+    {
+      if (types_compatible_p (TREE_TYPE (input_tree_type),
+			      TREE_TYPE (V2DF_type_node)))
+	return V2DI_type_node;
+      else if (types_compatible_p (TREE_TYPE (input_tree_type),
+				   TREE_TYPE (V4SF_type_node)))
+	return V4SI_type_node;
+      else
+	gcc_unreachable ();
+    }
+}
+
+/* Helper function to handle the vector merge[hl] built-ins.  The
+   implementation difference between h and l versions for this code are in
+   the values used when building of the permute vector for high word versus
+   low word merge.  The variance is keyed off the use_high parameter.  */
+static void
+fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high)
+{
+  tree arg0 = gimple_call_arg (stmt, 0);
+  tree arg1 = gimple_call_arg (stmt, 1);
+  tree lhs = gimple_call_lhs (stmt);
+  tree lhs_type = TREE_TYPE (lhs);
+  int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
+  int midpoint = n_elts / 2;
+  int offset = 0;
+
+  if (use_high == 1)
+    offset = midpoint;
+
+  /* The permute_type will match the lhs for integral types.  For double and
+     float types, the permute type needs to map to the V2 or V4 type that
+     matches size.  */
+  tree permute_type;
+  permute_type = map_to_integral_tree_type (lhs_type);
+  tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
+
+  for (int i = 0; i < midpoint; i++)
+    {
+      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+				     offset + i));
+      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+				     offset + n_elts + i));
+    }
+
+  tree permute = elts.build ();
+
+  gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
+  gimple_set_location (g, gimple_location (stmt));
+  gsi_replace (gsi, g, true);
+}
+
+/* Helper function to handle the vector merge[eo] built-ins.  */
+static void
+fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_odd)
+{
+  tree arg0 = gimple_call_arg (stmt, 0);
+  tree arg1 = gimple_call_arg (stmt, 1);
+  tree lhs = gimple_call_lhs (stmt);
+  tree lhs_type = TREE_TYPE (lhs);
+  int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
+
+  /* The permute_type will match the lhs for integral types.  For double and
+     float types, the permute type needs to map to the V2 or V4 type that
+     matches size.  */
+  tree permute_type;
+  permute_type = map_to_integral_tree_type (lhs_type);
+
+  tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
+
+ /* Build the permute vector.  */
+  for (int i = 0; i < n_elts / 2; i++)
+    {
+      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+				     2*i + use_odd));
+      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+				     2*i + use_odd + n_elts));
+    }
+
+  tree permute = elts.build ();
+
+  gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
+  gimple_set_location (g, gimple_location (stmt));
+  gsi_replace (gsi, g, true);
+}
+
+/*  Helper function to sort out which built-ins may be valid without having
+    a LHS.  */
+static bool
+rs6000_builtin_valid_without_lhs (enum rs6000_gen_builtins fn_code,
+				  tree fndecl)
+{
+  if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
+    return true;
+
+  switch (fn_code)
+    {
+    case RS6000_BIF_STVX_V16QI:
+    case RS6000_BIF_STVX_V8HI:
+    case RS6000_BIF_STVX_V4SI:
+    case RS6000_BIF_STVX_V4SF:
+    case RS6000_BIF_STVX_V2DI:
+    case RS6000_BIF_STVX_V2DF:
+    case RS6000_BIF_STXVW4X_V16QI:
+    case RS6000_BIF_STXVW4X_V8HI:
+    case RS6000_BIF_STXVW4X_V4SF:
+    case RS6000_BIF_STXVW4X_V4SI:
+    case RS6000_BIF_STXVD2X_V2DF:
+    case RS6000_BIF_STXVD2X_V2DI:
+      return true;
+    default:
+      return false;
+    }
+}
+
+/* Expand the MMA built-ins early, so that we can convert the pass-by-reference
+   __vector_quad arguments into pass-by-value arguments, leading to more
+   efficient code generation.  */
+static bool
+rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
+				rs6000_gen_builtins fn_code)
+{
+  gimple *stmt = gsi_stmt (*gsi);
+  size_t fncode = (size_t) fn_code;
+
+  if (!bif_is_mma (rs6000_builtin_info[fncode]))
+    return false;
+
+  /* Each call that can be gimple-expanded has an associated built-in
+     function that it will expand into.  If this one doesn't, we have
+     already expanded it!  Exceptions: lxvp and stxvp.  */
+  if (rs6000_builtin_info[fncode].assoc_bif == RS6000_BIF_NONE
+      && fncode != RS6000_BIF_LXVP
+      && fncode != RS6000_BIF_STXVP)
+    return false;
+
+  bifdata *bd = &rs6000_builtin_info[fncode];
+  unsigned nopnds = bd->nargs;
+  gimple_seq new_seq = NULL;
+  gimple *new_call;
+  tree new_decl;
+
+  /* Compatibility built-ins; we used to call these
+     __builtin_mma_{dis,}assemble_pair, but now we call them
+     __builtin_vsx_{dis,}assemble_pair.  Handle the old versions.  */
+  if (fncode == RS6000_BIF_ASSEMBLE_PAIR)
+    fncode = RS6000_BIF_ASSEMBLE_PAIR_V;
+  else if (fncode == RS6000_BIF_DISASSEMBLE_PAIR)
+    fncode = RS6000_BIF_DISASSEMBLE_PAIR_V;
+
+  if (fncode == RS6000_BIF_DISASSEMBLE_ACC
+      || fncode == RS6000_BIF_DISASSEMBLE_PAIR_V)
+    {
+      /* This is an MMA disassemble built-in function.  */
+      push_gimplify_context (true);
+      unsigned nvec = (fncode == RS6000_BIF_DISASSEMBLE_ACC) ? 4 : 2;
+      tree dst_ptr = gimple_call_arg (stmt, 0);
+      tree src_ptr = gimple_call_arg (stmt, 1);
+      tree src_type = TREE_TYPE (src_ptr);
+      tree src = create_tmp_reg_or_ssa_name (TREE_TYPE (src_type));
+      gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq);
+
+      /* If we are not disassembling an accumulator/pair or our destination is
+	 another accumulator/pair, then just copy the entire thing as is.  */
+      if ((fncode == RS6000_BIF_DISASSEMBLE_ACC
+	   && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node)
+	  || (fncode == RS6000_BIF_DISASSEMBLE_PAIR_V
+	      && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_pair_type_node))
+	{
+	  tree dst = build_simple_mem_ref (build1 (VIEW_CONVERT_EXPR,
+						   src_type, dst_ptr));
+	  gimplify_assign (dst, src, &new_seq);
+	  pop_gimplify_context (NULL);
+	  gsi_replace_with_seq (gsi, new_seq, true);
+	  return true;
+	}
+
+      /* If we're disassembling an accumulator into a different type, we need
+	 to emit a xxmfacc instruction now, since we cannot do it later.  */
+      if (fncode == RS6000_BIF_DISASSEMBLE_ACC)
+	{
+	  new_decl = rs6000_builtin_decls[RS6000_BIF_XXMFACC_INTERNAL];
+	  new_call = gimple_build_call (new_decl, 1, src);
+	  src = create_tmp_reg_or_ssa_name (vector_quad_type_node);
+	  gimple_call_set_lhs (new_call, src);
+	  gimple_seq_add_stmt (&new_seq, new_call);
+	}
+
+      /* Copy the accumulator/pair vector by vector.  */
+      new_decl
+	= rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif];
+      tree dst_type = build_pointer_type_for_mode (unsigned_V16QI_type_node,
+						   ptr_mode, true);
+      tree dst_base = build1 (VIEW_CONVERT_EXPR, dst_type, dst_ptr);
+      for (unsigned i = 0; i < nvec; i++)
+	{
+	  unsigned index = WORDS_BIG_ENDIAN ? i : nvec - 1 - i;
+	  tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base,
+			     build_int_cst (dst_type, index * 16));
+	  tree dstssa = create_tmp_reg_or_ssa_name (unsigned_V16QI_type_node);
+	  new_call = gimple_build_call (new_decl, 2, src,
+					build_int_cstu (uint16_type_node, i));
+	  gimple_call_set_lhs (new_call, dstssa);
+	  gimple_seq_add_stmt (&new_seq, new_call);
+	  gimplify_assign (dst, dstssa, &new_seq);
+	}
+      pop_gimplify_context (NULL);
+      gsi_replace_with_seq (gsi, new_seq, true);
+      return true;
+    }
+
+  /* TODO: Do some factoring on these two chunks.  */
+  if (fncode == RS6000_BIF_LXVP)
+    {
+      push_gimplify_context (true);
+      tree offset = gimple_call_arg (stmt, 0);
+      tree ptr = gimple_call_arg (stmt, 1);
+      tree lhs = gimple_call_lhs (stmt);
+      if (TREE_TYPE (TREE_TYPE (ptr)) != vector_pair_type_node)
+	ptr = build1 (VIEW_CONVERT_EXPR,
+		      build_pointer_type (vector_pair_type_node), ptr);
+      tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR,
+					       TREE_TYPE (ptr), ptr, offset));
+      gimplify_assign (lhs, mem, &new_seq);
+      pop_gimplify_context (NULL);
+      gsi_replace_with_seq (gsi, new_seq, true);
+      return true;
+    }
+
+  if (fncode == RS6000_BIF_STXVP)
+    {
+      push_gimplify_context (true);
+      tree src = gimple_call_arg (stmt, 0);
+      tree offset = gimple_call_arg (stmt, 1);
+      tree ptr = gimple_call_arg (stmt, 2);
+      if (TREE_TYPE (TREE_TYPE (ptr)) != vector_pair_type_node)
+	ptr = build1 (VIEW_CONVERT_EXPR,
+		      build_pointer_type (vector_pair_type_node), ptr);
+      tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR,
+					       TREE_TYPE (ptr), ptr, offset));
+      gimplify_assign (mem, src, &new_seq);
+      pop_gimplify_context (NULL);
+      gsi_replace_with_seq (gsi, new_seq, true);
+      return true;
+    }
+
+  /* Convert this built-in into an internal version that uses pass-by-value
+     arguments.  The internal built-in is found in the assoc_bif field.  */
+  new_decl = rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif];
+  tree lhs, op[MAX_MMA_OPERANDS];
+  tree acc = gimple_call_arg (stmt, 0);
+  push_gimplify_context (true);
+
+  if (bif_is_quad (*bd))
+    {
+      /* This built-in has a pass-by-reference accumulator input, so load it
+	 into a temporary accumulator for use as a pass-by-value input.  */
+      op[0] = create_tmp_reg_or_ssa_name (vector_quad_type_node);
+      for (unsigned i = 1; i < nopnds; i++)
+	op[i] = gimple_call_arg (stmt, i);
+      gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq);
+    }
+  else
+    {
+      /* This built-in does not use its pass-by-reference accumulator argument
+	 as an input argument, so remove it from the input list.  */
+      nopnds--;
+      for (unsigned i = 0; i < nopnds; i++)
+	op[i] = gimple_call_arg (stmt, i + 1);
+    }
+
+  switch (nopnds)
+    {
+    case 0:
+      new_call = gimple_build_call (new_decl, 0);
+      break;
+    case 1:
+      new_call = gimple_build_call (new_decl, 1, op[0]);
+      break;
+    case 2:
+      new_call = gimple_build_call (new_decl, 2, op[0], op[1]);
+      break;
+    case 3:
+      new_call = gimple_build_call (new_decl, 3, op[0], op[1], op[2]);
+      break;
+    case 4:
+      new_call = gimple_build_call (new_decl, 4, op[0], op[1], op[2], op[3]);
+      break;
+    case 5:
+      new_call = gimple_build_call (new_decl, 5, op[0], op[1], op[2], op[3],
+				    op[4]);
+      break;
+    case 6:
+      new_call = gimple_build_call (new_decl, 6, op[0], op[1], op[2], op[3],
+				    op[4], op[5]);
+      break;
+    case 7:
+      new_call = gimple_build_call (new_decl, 7, op[0], op[1], op[2], op[3],
+				    op[4], op[5], op[6]);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  if (fncode == RS6000_BIF_BUILD_PAIR || fncode == RS6000_BIF_ASSEMBLE_PAIR_V)
+    lhs = create_tmp_reg_or_ssa_name (vector_pair_type_node);
+  else
+    lhs = create_tmp_reg_or_ssa_name (vector_quad_type_node);
+  gimple_call_set_lhs (new_call, lhs);
+  gimple_seq_add_stmt (&new_seq, new_call);
+  gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq);
+  pop_gimplify_context (NULL);
+  gsi_replace_with_seq (gsi, new_seq, true);
+
+  return true;
+}
+
+/* Fold a machine-dependent built-in in GIMPLE.  (For folding into
+   a constant, use rs6000_fold_builtin.)  */
+bool
+rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
+{
+  gimple *stmt = gsi_stmt (*gsi);
+  tree fndecl = gimple_call_fndecl (stmt);
+  gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
+  enum rs6000_gen_builtins fn_code
+    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
+  tree arg0, arg1, lhs, temp;
+  enum tree_code bcode;
+  gimple *g;
+
+  size_t uns_fncode = (size_t) fn_code;
+  enum insn_code icode = rs6000_builtin_info[uns_fncode].icode;
+  const char *fn_name1 = rs6000_builtin_info[uns_fncode].bifname;
+  const char *fn_name2 = (icode != CODE_FOR_nothing)
+			  ? get_insn_name ((int) icode)
+			  : "nothing";
+
+  if (TARGET_DEBUG_BUILTIN)
+      fprintf (stderr, "rs6000_gimple_fold_builtin %d %s %s\n",
+	       fn_code, fn_name1, fn_name2);
+
+  if (!rs6000_fold_gimple)
+    return false;
+
+  /* Prevent gimple folding for code that does not have a LHS, unless it is
+     allowed per the rs6000_builtin_valid_without_lhs helper function.  */
+  if (!gimple_call_lhs (stmt)
+      && !rs6000_builtin_valid_without_lhs (fn_code, fndecl))
+    return false;
+
+  /* Don't fold invalid builtins, let rs6000_expand_builtin diagnose it.  */
+  if (!rs6000_builtin_is_supported (fn_code))
+    return false;
+
+  if (rs6000_gimple_fold_mma_builtin (gsi, fn_code))
+    return true;
+
+  switch (fn_code)
+    {
+    /* Flavors of vec_add.  We deliberately don't expand
+       RS6000_BIF_VADDUQM as it gets lowered from V1TImode to
+       TImode, resulting in much poorer code generation.  */
+    case RS6000_BIF_VADDUBM:
+    case RS6000_BIF_VADDUHM:
+    case RS6000_BIF_VADDUWM:
+    case RS6000_BIF_VADDUDM:
+    case RS6000_BIF_VADDFP:
+    case RS6000_BIF_XVADDDP:
+    case RS6000_BIF_XVADDSP:
+      bcode = PLUS_EXPR;
+    do_binary:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
+	  && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
+	{
+	  /* Ensure the binary operation is performed in a type
+	     that wraps if it is integral type.  */
+	  gimple_seq stmts = NULL;
+	  tree type = unsigned_type_for (TREE_TYPE (lhs));
+	  tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+				     type, arg0);
+	  tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+				     type, arg1);
+	  tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
+				   type, uarg0, uarg1);
+	  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	  g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
+				   build1 (VIEW_CONVERT_EXPR,
+					   TREE_TYPE (lhs), res));
+	  gsi_replace (gsi, g, true);
+	  return true;
+	}
+      g = gimple_build_assign (lhs, bcode, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_sub.  We deliberately don't expand
+       RS6000_BIF_VSUBUQM. */
+    case RS6000_BIF_VSUBUBM:
+    case RS6000_BIF_VSUBUHM:
+    case RS6000_BIF_VSUBUWM:
+    case RS6000_BIF_VSUBUDM:
+    case RS6000_BIF_VSUBFP:
+    case RS6000_BIF_XVSUBDP:
+    case RS6000_BIF_XVSUBSP:
+      bcode = MINUS_EXPR;
+      goto do_binary;
+    case RS6000_BIF_XVMULSP:
+    case RS6000_BIF_XVMULDP:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, MULT_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Even element flavors of vec_mul (signed). */
+    case RS6000_BIF_VMULESB:
+    case RS6000_BIF_VMULESH:
+    case RS6000_BIF_VMULESW:
+    /* Even element flavors of vec_mul (unsigned).  */
+    case RS6000_BIF_VMULEUB:
+    case RS6000_BIF_VMULEUH:
+    case RS6000_BIF_VMULEUW:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, VEC_WIDEN_MULT_EVEN_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Odd element flavors of vec_mul (signed).  */
+    case RS6000_BIF_VMULOSB:
+    case RS6000_BIF_VMULOSH:
+    case RS6000_BIF_VMULOSW:
+    /* Odd element flavors of vec_mul (unsigned). */
+    case RS6000_BIF_VMULOUB:
+    case RS6000_BIF_VMULOUH:
+    case RS6000_BIF_VMULOUW:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, VEC_WIDEN_MULT_ODD_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_div (Integer).  */
+    case RS6000_BIF_DIV_V2DI:
+    case RS6000_BIF_UDIV_V2DI:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, TRUNC_DIV_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_div (Float).  */
+    case RS6000_BIF_XVDIVSP:
+    case RS6000_BIF_XVDIVDP:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, RDIV_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_and.  */
+    case RS6000_BIF_VAND_V16QI_UNS:
+    case RS6000_BIF_VAND_V16QI:
+    case RS6000_BIF_VAND_V8HI_UNS:
+    case RS6000_BIF_VAND_V8HI:
+    case RS6000_BIF_VAND_V4SI_UNS:
+    case RS6000_BIF_VAND_V4SI:
+    case RS6000_BIF_VAND_V2DI_UNS:
+    case RS6000_BIF_VAND_V2DI:
+    case RS6000_BIF_VAND_V4SF:
+    case RS6000_BIF_VAND_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_andc.  */
+    case RS6000_BIF_VANDC_V16QI_UNS:
+    case RS6000_BIF_VANDC_V16QI:
+    case RS6000_BIF_VANDC_V8HI_UNS:
+    case RS6000_BIF_VANDC_V8HI:
+    case RS6000_BIF_VANDC_V4SI_UNS:
+    case RS6000_BIF_VANDC_V4SI:
+    case RS6000_BIF_VANDC_V2DI_UNS:
+    case RS6000_BIF_VANDC_V2DI:
+    case RS6000_BIF_VANDC_V4SF:
+    case RS6000_BIF_VANDC_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+      g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_insert_before (gsi, g, GSI_SAME_STMT);
+      g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, temp);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_nand.  */
+    case RS6000_BIF_NAND_V16QI_UNS:
+    case RS6000_BIF_NAND_V16QI:
+    case RS6000_BIF_NAND_V8HI_UNS:
+    case RS6000_BIF_NAND_V8HI:
+    case RS6000_BIF_NAND_V4SI_UNS:
+    case RS6000_BIF_NAND_V4SI:
+    case RS6000_BIF_NAND_V2DI_UNS:
+    case RS6000_BIF_NAND_V2DI:
+    case RS6000_BIF_NAND_V4SF:
+    case RS6000_BIF_NAND_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+      g = gimple_build_assign (temp, BIT_AND_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_insert_before (gsi, g, GSI_SAME_STMT);
+      g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_or.  */
+    case RS6000_BIF_VOR_V16QI_UNS:
+    case RS6000_BIF_VOR_V16QI:
+    case RS6000_BIF_VOR_V8HI_UNS:
+    case RS6000_BIF_VOR_V8HI:
+    case RS6000_BIF_VOR_V4SI_UNS:
+    case RS6000_BIF_VOR_V4SI:
+    case RS6000_BIF_VOR_V2DI_UNS:
+    case RS6000_BIF_VOR_V2DI:
+    case RS6000_BIF_VOR_V4SF:
+    case RS6000_BIF_VOR_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* flavors of vec_orc.  */
+    case RS6000_BIF_ORC_V16QI_UNS:
+    case RS6000_BIF_ORC_V16QI:
+    case RS6000_BIF_ORC_V8HI_UNS:
+    case RS6000_BIF_ORC_V8HI:
+    case RS6000_BIF_ORC_V4SI_UNS:
+    case RS6000_BIF_ORC_V4SI:
+    case RS6000_BIF_ORC_V2DI_UNS:
+    case RS6000_BIF_ORC_V2DI:
+    case RS6000_BIF_ORC_V4SF:
+    case RS6000_BIF_ORC_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+      g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_insert_before (gsi, g, GSI_SAME_STMT);
+      g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, temp);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_xor.  */
+    case RS6000_BIF_VXOR_V16QI_UNS:
+    case RS6000_BIF_VXOR_V16QI:
+    case RS6000_BIF_VXOR_V8HI_UNS:
+    case RS6000_BIF_VXOR_V8HI:
+    case RS6000_BIF_VXOR_V4SI_UNS:
+    case RS6000_BIF_VXOR_V4SI:
+    case RS6000_BIF_VXOR_V2DI_UNS:
+    case RS6000_BIF_VXOR_V2DI:
+    case RS6000_BIF_VXOR_V4SF:
+    case RS6000_BIF_VXOR_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, BIT_XOR_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_nor.  */
+    case RS6000_BIF_VNOR_V16QI_UNS:
+    case RS6000_BIF_VNOR_V16QI:
+    case RS6000_BIF_VNOR_V8HI_UNS:
+    case RS6000_BIF_VNOR_V8HI:
+    case RS6000_BIF_VNOR_V4SI_UNS:
+    case RS6000_BIF_VNOR_V4SI:
+    case RS6000_BIF_VNOR_V2DI_UNS:
+    case RS6000_BIF_VNOR_V2DI:
+    case RS6000_BIF_VNOR_V4SF:
+    case RS6000_BIF_VNOR_V2DF:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+      g = gimple_build_assign (temp, BIT_IOR_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_insert_before (gsi, g, GSI_SAME_STMT);
+      g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* flavors of vec_abs.  */
+    case RS6000_BIF_ABS_V16QI:
+    case RS6000_BIF_ABS_V8HI:
+    case RS6000_BIF_ABS_V4SI:
+    case RS6000_BIF_ABS_V4SF:
+    case RS6000_BIF_ABS_V2DI:
+    case RS6000_BIF_XVABSDP:
+    case RS6000_BIF_XVABSSP:
+      arg0 = gimple_call_arg (stmt, 0);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))
+	  && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (arg0))))
+	return false;
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, ABS_EXPR, arg0);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* flavors of vec_min.  */
+    case RS6000_BIF_XVMINDP:
+    case RS6000_BIF_XVMINSP:
+    case RS6000_BIF_VMINFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
+    case RS6000_BIF_VMINSD:
+    case RS6000_BIF_VMINUD:
+    case RS6000_BIF_VMINSB:
+    case RS6000_BIF_VMINSH:
+    case RS6000_BIF_VMINSW:
+    case RS6000_BIF_VMINUB:
+    case RS6000_BIF_VMINUH:
+    case RS6000_BIF_VMINUW:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, MIN_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* flavors of vec_max.  */
+    case RS6000_BIF_XVMAXDP:
+    case RS6000_BIF_XVMAXSP:
+    case RS6000_BIF_VMAXFP:
+      {
+	lhs = gimple_call_lhs (stmt);
+	tree type = TREE_TYPE (lhs);
+	if (HONOR_NANS (type))
+	  return false;
+	gcc_fallthrough ();
+      }
+    case RS6000_BIF_VMAXSD:
+    case RS6000_BIF_VMAXUD:
+    case RS6000_BIF_VMAXSB:
+    case RS6000_BIF_VMAXSH:
+    case RS6000_BIF_VMAXSW:
+    case RS6000_BIF_VMAXUB:
+    case RS6000_BIF_VMAXUH:
+    case RS6000_BIF_VMAXUW:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, MAX_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_eqv.  */
+    case RS6000_BIF_EQV_V16QI:
+    case RS6000_BIF_EQV_V8HI:
+    case RS6000_BIF_EQV_V4SI:
+    case RS6000_BIF_EQV_V4SF:
+    case RS6000_BIF_EQV_V2DF:
+    case RS6000_BIF_EQV_V2DI:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+      g = gimple_build_assign (temp, BIT_XOR_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_insert_before (gsi, g, GSI_SAME_STMT);
+      g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+    /* Flavors of vec_rotate_left.  */
+    case RS6000_BIF_VRLB:
+    case RS6000_BIF_VRLH:
+    case RS6000_BIF_VRLW:
+    case RS6000_BIF_VRLD:
+      arg0 = gimple_call_arg (stmt, 0);
+      arg1 = gimple_call_arg (stmt, 1);
+      lhs = gimple_call_lhs (stmt);
+      g = gimple_build_assign (lhs, LROTATE_EXPR, arg0, arg1);
+      gimple_set_location (g, gimple_location (stmt));
+      gsi_replace (gsi, g, true);
+      return true;
+  /* Flavors of vector shift right algebraic.
+     vec_sra{b,h,w} -> vsra{b,h,w}.  */
+    case RS6000_BIF_VSRAB:
+    case RS6000_BIF_VSRAH:
+    case RS6000_BIF_VSRAW:
+    case RS6000_BIF_VSRAD:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	arg1 = gimple_call_arg (stmt, 1);
+	lhs = gimple_call_lhs (stmt);
+	tree arg1_type = TREE_TYPE (arg1);
+	tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+	tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+	location_t loc = gimple_location (stmt);
+	/* Force arg1 into the range valid matching the arg0 type.  */
+	/* Build a vector consisting of the max valid bit-size values.  */
+	int n_elts = VECTOR_CST_NELTS (arg1);
+	tree element_size = build_int_cst (unsigned_element_type,
+					   128 / n_elts);
+	tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
+	for (int i = 0; i < n_elts; i++)
+	  elts.safe_push (element_size);
+	tree modulo_tree = elts.build ();
+	/* Modulo the provided shift value against that vector.  */
+	gimple_seq stmts = NULL;
+	tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+					   unsigned_arg1_type, arg1);
+	tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+				      unsigned_arg1_type, unsigned_arg1,
+				      modulo_tree);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	/* And finally, do the shift.  */
+	g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, new_arg1);
+	gimple_set_location (g, loc);
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+   /* Flavors of vector shift left.
+      builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}.  */
+    case RS6000_BIF_VSLB:
+    case RS6000_BIF_VSLH:
+    case RS6000_BIF_VSLW:
+    case RS6000_BIF_VSLD:
+      {
+	location_t loc;
+	gimple_seq stmts = NULL;
+	arg0 = gimple_call_arg (stmt, 0);
+	tree arg0_type = TREE_TYPE (arg0);
+	if (INTEGRAL_TYPE_P (TREE_TYPE (arg0_type))
+	    && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0_type)))
+	  return false;
+	arg1 = gimple_call_arg (stmt, 1);
+	tree arg1_type = TREE_TYPE (arg1);
+	tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+	tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+	loc = gimple_location (stmt);
+	lhs = gimple_call_lhs (stmt);
+	/* Force arg1 into the range valid matching the arg0 type.  */
+	/* Build a vector consisting of the max valid bit-size values.  */
+	int n_elts = VECTOR_CST_NELTS (arg1);
+	int tree_size_in_bits = TREE_INT_CST_LOW (size_in_bytes (arg1_type))
+				* BITS_PER_UNIT;
+	tree element_size = build_int_cst (unsigned_element_type,
+					   tree_size_in_bits / n_elts);
+	tree_vector_builder elts (unsigned_type_for (arg1_type), n_elts, 1);
+	for (int i = 0; i < n_elts; i++)
+	  elts.safe_push (element_size);
+	tree modulo_tree = elts.build ();
+	/* Modulo the provided shift value against that vector.  */
+	tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+					   unsigned_arg1_type, arg1);
+	tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+				      unsigned_arg1_type, unsigned_arg1,
+				      modulo_tree);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	/* And finally, do the shift.  */
+	g = gimple_build_assign (lhs, LSHIFT_EXPR, arg0, new_arg1);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+    /* Flavors of vector shift right.  */
+    case RS6000_BIF_VSRB:
+    case RS6000_BIF_VSRH:
+    case RS6000_BIF_VSRW:
+    case RS6000_BIF_VSRD:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	arg1 = gimple_call_arg (stmt, 1);
+	lhs = gimple_call_lhs (stmt);
+	tree arg1_type = TREE_TYPE (arg1);
+	tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+	tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+	location_t loc = gimple_location (stmt);
+	gimple_seq stmts = NULL;
+	/* Convert arg0 to unsigned.  */
+	tree arg0_unsigned
+	  = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+			  unsigned_type_for (TREE_TYPE (arg0)), arg0);
+	/* Force arg1 into the range valid matching the arg0 type.  */
+	/* Build a vector consisting of the max valid bit-size values.  */
+	int n_elts = VECTOR_CST_NELTS (arg1);
+	tree element_size = build_int_cst (unsigned_element_type,
+					   128 / n_elts);
+	tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
+	for (int i = 0; i < n_elts; i++)
+	  elts.safe_push (element_size);
+	tree modulo_tree = elts.build ();
+	/* Modulo the provided shift value against that vector.  */
+	tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+					   unsigned_arg1_type, arg1);
+	tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+				      unsigned_arg1_type, unsigned_arg1,
+				      modulo_tree);
+	/* Do the shift.  */
+	tree res
+	  = gimple_build (&stmts, RSHIFT_EXPR,
+			  TREE_TYPE (arg0_unsigned), arg0_unsigned, new_arg1);
+	/* Convert result back to the lhs type.  */
+	res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	replace_call_with_value (gsi, res);
+	return true;
+      }
+    /* Vector loads.  */
+    case RS6000_BIF_LVX_V16QI:
+    case RS6000_BIF_LVX_V8HI:
+    case RS6000_BIF_LVX_V4SI:
+    case RS6000_BIF_LVX_V4SF:
+    case RS6000_BIF_LVX_V2DI:
+    case RS6000_BIF_LVX_V2DF:
+    case RS6000_BIF_LVX_V1TI:
+      {
+	arg0 = gimple_call_arg (stmt, 0);  // offset
+	arg1 = gimple_call_arg (stmt, 1);  // address
+	lhs = gimple_call_lhs (stmt);
+	location_t loc = gimple_location (stmt);
+	/* Since arg1 may be cast to a different type, just use ptr_type_node
+	   here instead of trying to enforce TBAA on pointer types.  */
+	tree arg1_type = ptr_type_node;
+	tree lhs_type = TREE_TYPE (lhs);
+	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
+	   the tree using the value from arg0.  The resulting type will match
+	   the type of arg1.  */
+	gimple_seq stmts = NULL;
+	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
+	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+				       arg1_type, arg1, temp_offset);
+	/* Mask off any lower bits from the address.  */
+	tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
+					  arg1_type, temp_addr,
+					  build_int_cst (arg1_type, -16));
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	if (!is_gimple_mem_ref_addr (aligned_addr))
+	  {
+	    tree t = make_ssa_name (TREE_TYPE (aligned_addr));
+	    gimple *g = gimple_build_assign (t, aligned_addr);
+	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
+	    aligned_addr = t;
+	  }
+	/* Use the build2 helper to set up the mem_ref.  The MEM_REF could also
+	   take an offset, but since we've already incorporated the offset
+	   above, here we just pass in a zero.  */
+	gimple *g
+	  = gimple_build_assign (lhs, build2 (MEM_REF, lhs_type, aligned_addr,
+					      build_int_cst (arg1_type, 0)));
+	gimple_set_location (g, loc);
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+    /* Vector stores.  */
+    case RS6000_BIF_STVX_V16QI:
+    case RS6000_BIF_STVX_V8HI:
+    case RS6000_BIF_STVX_V4SI:
+    case RS6000_BIF_STVX_V4SF:
+    case RS6000_BIF_STVX_V2DI:
+    case RS6000_BIF_STVX_V2DF:
+      {
+	arg0 = gimple_call_arg (stmt, 0); /* Value to be stored.  */
+	arg1 = gimple_call_arg (stmt, 1); /* Offset.  */
+	tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address.  */
+	location_t loc = gimple_location (stmt);
+	tree arg0_type = TREE_TYPE (arg0);
+	/* Use ptr_type_node (no TBAA) for the arg2_type.
+	   FIXME: (Richard)  "A proper fix would be to transition this type as
+	   seen from the frontend to GIMPLE, for example in a similar way we
+	   do for MEM_REFs by piggy-backing that on an extra argument, a
+	   constant zero pointer of the alias pointer type to use (which would
+	   also serve as a type indicator of the store itself).  I'd use a
+	   target specific internal function for this (not sure if we can have
+	   those target specific, but I guess if it's folded away then that's
+	   fine) and get away with the overload set."  */
+	tree arg2_type = ptr_type_node;
+	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
+	   the tree using the value from arg0.  The resulting type will match
+	   the type of arg2.  */
+	gimple_seq stmts = NULL;
+	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
+	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+				       arg2_type, arg2, temp_offset);
+	/* Mask off any lower bits from the address.  */
+	tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
+					  arg2_type, temp_addr,
+					  build_int_cst (arg2_type, -16));
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	if (!is_gimple_mem_ref_addr (aligned_addr))
+	  {
+	    tree t = make_ssa_name (TREE_TYPE (aligned_addr));
+	    gimple *g = gimple_build_assign (t, aligned_addr);
+	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
+	    aligned_addr = t;
+	  }
+	/* The desired gimple result should be similar to:
+	   MEM[(__vector floatD.1407 *)_1] = vf1D.2697;  */
+	gimple *g
+	  = gimple_build_assign (build2 (MEM_REF, arg0_type, aligned_addr,
+					 build_int_cst (arg2_type, 0)), arg0);
+	gimple_set_location (g, loc);
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* unaligned Vector loads.  */
+    case RS6000_BIF_LXVW4X_V16QI:
+    case RS6000_BIF_LXVW4X_V8HI:
+    case RS6000_BIF_LXVW4X_V4SF:
+    case RS6000_BIF_LXVW4X_V4SI:
+    case RS6000_BIF_LXVD2X_V2DF:
+    case RS6000_BIF_LXVD2X_V2DI:
+      {
+	arg0 = gimple_call_arg (stmt, 0);  // offset
+	arg1 = gimple_call_arg (stmt, 1);  // address
+	lhs = gimple_call_lhs (stmt);
+	location_t loc = gimple_location (stmt);
+	/* Since arg1 may be cast to a different type, just use ptr_type_node
+	   here instead of trying to enforce TBAA on pointer types.  */
+	tree arg1_type = ptr_type_node;
+	tree lhs_type = TREE_TYPE (lhs);
+	/* In GIMPLE the type of the MEM_REF specifies the alignment.  The
+	  required alignment (power) is 4 bytes regardless of data type.  */
+	tree align_ltype = build_aligned_type (lhs_type, 4);
+	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
+	   the tree using the value from arg0.  The resulting type will match
+	   the type of arg1.  */
+	gimple_seq stmts = NULL;
+	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
+	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+				       arg1_type, arg1, temp_offset);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	if (!is_gimple_mem_ref_addr (temp_addr))
+	  {
+	    tree t = make_ssa_name (TREE_TYPE (temp_addr));
+	    gimple *g = gimple_build_assign (t, temp_addr);
+	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
+	    temp_addr = t;
+	  }
+	/* Use the build2 helper to set up the mem_ref.  The MEM_REF could also
+	   take an offset, but since we've already incorporated the offset
+	   above, here we just pass in a zero.  */
+	gimple *g;
+	g = gimple_build_assign (lhs, build2 (MEM_REF, align_ltype, temp_addr,
+					      build_int_cst (arg1_type, 0)));
+	gimple_set_location (g, loc);
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* unaligned Vector stores.  */
+    case RS6000_BIF_STXVW4X_V16QI:
+    case RS6000_BIF_STXVW4X_V8HI:
+    case RS6000_BIF_STXVW4X_V4SF:
+    case RS6000_BIF_STXVW4X_V4SI:
+    case RS6000_BIF_STXVD2X_V2DF:
+    case RS6000_BIF_STXVD2X_V2DI:
+      {
+	arg0 = gimple_call_arg (stmt, 0); /* Value to be stored.  */
+	arg1 = gimple_call_arg (stmt, 1); /* Offset.  */
+	tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address.  */
+	location_t loc = gimple_location (stmt);
+	tree arg0_type = TREE_TYPE (arg0);
+	/* Use ptr_type_node (no TBAA) for the arg2_type.  */
+	tree arg2_type = ptr_type_node;
+	/* In GIMPLE the type of the MEM_REF specifies the alignment.  The
+	   required alignment (power) is 4 bytes regardless of data type.  */
+	tree align_stype = build_aligned_type (arg0_type, 4);
+	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
+	   the tree using the value from arg1.  */
+	gimple_seq stmts = NULL;
+	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
+	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+				       arg2_type, arg2, temp_offset);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	if (!is_gimple_mem_ref_addr (temp_addr))
+	  {
+	    tree t = make_ssa_name (TREE_TYPE (temp_addr));
+	    gimple *g = gimple_build_assign (t, temp_addr);
+	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
+	    temp_addr = t;
+	  }
+	gimple *g;
+	g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr,
+					 build_int_cst (arg2_type, 0)), arg0);
+	gimple_set_location (g, loc);
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* Vector Fused multiply-add (fma).  */
+    case RS6000_BIF_VMADDFP:
+    case RS6000_BIF_XVMADDDP:
+    case RS6000_BIF_XVMADDSP:
+    case RS6000_BIF_VMLADDUHM:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	arg1 = gimple_call_arg (stmt, 1);
+	tree arg2 = gimple_call_arg (stmt, 2);
+	lhs = gimple_call_lhs (stmt);
+	gcall *g = gimple_build_call_internal (IFN_FMA, 3, arg0, arg1, arg2);
+	gimple_call_set_lhs (g, lhs);
+	gimple_call_set_nothrow (g, true);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* Vector compares; EQ, NE, GE, GT, LE.  */
+    case RS6000_BIF_VCMPEQUB:
+    case RS6000_BIF_VCMPEQUH:
+    case RS6000_BIF_VCMPEQUW:
+    case RS6000_BIF_VCMPEQUD:
+    /* We deliberately omit RS6000_BIF_VCMPEQUT for now, because gimple
+       folding produces worse code for 128-bit compares.  */
+      fold_compare_helper (gsi, EQ_EXPR, stmt);
+      return true;
+
+    case RS6000_BIF_VCMPNEB:
+    case RS6000_BIF_VCMPNEH:
+    case RS6000_BIF_VCMPNEW:
+    /* We deliberately omit RS6000_BIF_VCMPNET for now, because gimple
+       folding produces worse code for 128-bit compares.  */
+      fold_compare_helper (gsi, NE_EXPR, stmt);
+      return true;
+
+    case RS6000_BIF_CMPGE_16QI:
+    case RS6000_BIF_CMPGE_U16QI:
+    case RS6000_BIF_CMPGE_8HI:
+    case RS6000_BIF_CMPGE_U8HI:
+    case RS6000_BIF_CMPGE_4SI:
+    case RS6000_BIF_CMPGE_U4SI:
+    case RS6000_BIF_CMPGE_2DI:
+    case RS6000_BIF_CMPGE_U2DI:
+    /* We deliberately omit RS6000_BIF_CMPGE_1TI and RS6000_BIF_CMPGE_U1TI
+       for now, because gimple folding produces worse code for 128-bit
+       compares.  */
+      fold_compare_helper (gsi, GE_EXPR, stmt);
+      return true;
+
+    case RS6000_BIF_VCMPGTSB:
+    case RS6000_BIF_VCMPGTUB:
+    case RS6000_BIF_VCMPGTSH:
+    case RS6000_BIF_VCMPGTUH:
+    case RS6000_BIF_VCMPGTSW:
+    case RS6000_BIF_VCMPGTUW:
+    case RS6000_BIF_VCMPGTUD:
+    case RS6000_BIF_VCMPGTSD:
+    /* We deliberately omit RS6000_BIF_VCMPGTUT and RS6000_BIF_VCMPGTST
+       for now, because gimple folding produces worse code for 128-bit
+       compares.  */
+      fold_compare_helper (gsi, GT_EXPR, stmt);
+      return true;
+
+    case RS6000_BIF_CMPLE_16QI:
+    case RS6000_BIF_CMPLE_U16QI:
+    case RS6000_BIF_CMPLE_8HI:
+    case RS6000_BIF_CMPLE_U8HI:
+    case RS6000_BIF_CMPLE_4SI:
+    case RS6000_BIF_CMPLE_U4SI:
+    case RS6000_BIF_CMPLE_2DI:
+    case RS6000_BIF_CMPLE_U2DI:
+    /* We deliberately omit RS6000_BIF_CMPLE_1TI and RS6000_BIF_CMPLE_U1TI
+       for now, because gimple folding produces worse code for 128-bit
+       compares.  */
+      fold_compare_helper (gsi, LE_EXPR, stmt);
+      return true;
+
+    /* flavors of vec_splat_[us]{8,16,32}.  */
+    case RS6000_BIF_VSPLTISB:
+    case RS6000_BIF_VSPLTISH:
+    case RS6000_BIF_VSPLTISW:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	lhs = gimple_call_lhs (stmt);
+
+	/* Only fold the vec_splat_*() if the lower bits of arg 0 is a
+	   5-bit signed constant in range -16 to +15.  */
+	if (TREE_CODE (arg0) != INTEGER_CST
+	    || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
+	  return false;
+	gimple_seq stmts = NULL;
+	location_t loc = gimple_location (stmt);
+	tree splat_value = gimple_convert (&stmts, loc,
+					   TREE_TYPE (TREE_TYPE (lhs)), arg0);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	tree splat_tree = build_vector_from_val (TREE_TYPE (lhs), splat_value);
+	g = gimple_build_assign (lhs, splat_tree);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* Flavors of vec_splat.  */
+    /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...};  */
+    case RS6000_BIF_VSPLTB:
+    case RS6000_BIF_VSPLTH:
+    case RS6000_BIF_VSPLTW:
+    case RS6000_BIF_XXSPLTD_V2DI:
+    case RS6000_BIF_XXSPLTD_V2DF:
+      {
+	arg0 = gimple_call_arg (stmt, 0); /* input vector.  */
+	arg1 = gimple_call_arg (stmt, 1); /* index into arg0.  */
+	/* Only fold the vec_splat_*() if arg1 is both a constant value and
+	   is a valid index into the arg0 vector.  */
+	unsigned int n_elts = VECTOR_CST_NELTS (arg0);
+	if (TREE_CODE (arg1) != INTEGER_CST
+	    || TREE_INT_CST_LOW (arg1) > (n_elts -1))
+	  return false;
+	lhs = gimple_call_lhs (stmt);
+	tree lhs_type = TREE_TYPE (lhs);
+	tree arg0_type = TREE_TYPE (arg0);
+	tree splat;
+	if (TREE_CODE (arg0) == VECTOR_CST)
+	  splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1));
+	else
+	  {
+	    /* Determine (in bits) the length and start location of the
+	       splat value for a call to the tree_vec_extract helper.  */
+	    int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type))
+				  * BITS_PER_UNIT / n_elts;
+	    int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size;
+	    tree len = build_int_cst (bitsizetype, splat_elem_size);
+	    tree start = build_int_cst (bitsizetype, splat_start_bit);
+	    splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0,
+				      len, start);
+	  }
+	/* And finally, build the new vector.  */
+	tree splat_tree = build_vector_from_val (lhs_type, splat);
+	g = gimple_build_assign (lhs, splat_tree);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* vec_mergel (integrals).  */
+    case RS6000_BIF_VMRGLH:
+    case RS6000_BIF_VMRGLW:
+    case RS6000_BIF_XXMRGLW_4SI:
+    case RS6000_BIF_VMRGLB:
+    case RS6000_BIF_VEC_MERGEL_V2DI:
+    case RS6000_BIF_XXMRGLW_4SF:
+    case RS6000_BIF_VEC_MERGEL_V2DF:
+      fold_mergehl_helper (gsi, stmt, 1);
+      return true;
+    /* vec_mergeh (integrals).  */
+    case RS6000_BIF_VMRGHH:
+    case RS6000_BIF_VMRGHW:
+    case RS6000_BIF_XXMRGHW_4SI:
+    case RS6000_BIF_VMRGHB:
+    case RS6000_BIF_VEC_MERGEH_V2DI:
+    case RS6000_BIF_XXMRGHW_4SF:
+    case RS6000_BIF_VEC_MERGEH_V2DF:
+      fold_mergehl_helper (gsi, stmt, 0);
+      return true;
+
+    /* Flavors of vec_mergee.  */
+    case RS6000_BIF_VMRGEW_V4SI:
+    case RS6000_BIF_VMRGEW_V2DI:
+    case RS6000_BIF_VMRGEW_V4SF:
+    case RS6000_BIF_VMRGEW_V2DF:
+      fold_mergeeo_helper (gsi, stmt, 0);
+      return true;
+    /* Flavors of vec_mergeo.  */
+    case RS6000_BIF_VMRGOW_V4SI:
+    case RS6000_BIF_VMRGOW_V2DI:
+    case RS6000_BIF_VMRGOW_V4SF:
+    case RS6000_BIF_VMRGOW_V2DF:
+      fold_mergeeo_helper (gsi, stmt, 1);
+      return true;
+
+    /* d = vec_pack (a, b) */
+    case RS6000_BIF_VPKUDUM:
+    case RS6000_BIF_VPKUHUM:
+    case RS6000_BIF_VPKUWUM:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	arg1 = gimple_call_arg (stmt, 1);
+	lhs = gimple_call_lhs (stmt);
+	gimple *g = gimple_build_assign (lhs, VEC_PACK_TRUNC_EXPR, arg0, arg1);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    /* d = vec_unpackh (a) */
+    /* Note that the UNPACK_{HI,LO}_EXPR used in the gimple_build_assign call
+       in this code is sensitive to endian-ness, and needs to be inverted to
+       handle both LE and BE targets.  */
+    case RS6000_BIF_VUPKHSB:
+    case RS6000_BIF_VUPKHSH:
+    case RS6000_BIF_VUPKHSW:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	lhs = gimple_call_lhs (stmt);
+	if (BYTES_BIG_ENDIAN)
+	  g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
+	else
+	  g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+    /* d = vec_unpackl (a) */
+    case RS6000_BIF_VUPKLSB:
+    case RS6000_BIF_VUPKLSH:
+    case RS6000_BIF_VUPKLSW:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	lhs = gimple_call_lhs (stmt);
+	if (BYTES_BIG_ENDIAN)
+	  g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
+	else
+	  g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
+	gimple_set_location (g, gimple_location (stmt));
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+    /* There is no gimple type corresponding with pixel, so just return.  */
+    case RS6000_BIF_VUPKHPX:
+    case RS6000_BIF_VUPKLPX:
+      return false;
+
+    /* vec_perm.  */
+    case RS6000_BIF_VPERM_16QI:
+    case RS6000_BIF_VPERM_8HI:
+    case RS6000_BIF_VPERM_4SI:
+    case RS6000_BIF_VPERM_2DI:
+    case RS6000_BIF_VPERM_4SF:
+    case RS6000_BIF_VPERM_2DF:
+    case RS6000_BIF_VPERM_16QI_UNS:
+    case RS6000_BIF_VPERM_8HI_UNS:
+    case RS6000_BIF_VPERM_4SI_UNS:
+    case RS6000_BIF_VPERM_2DI_UNS:
+      {
+	arg0 = gimple_call_arg (stmt, 0);
+	arg1 = gimple_call_arg (stmt, 1);
+	tree permute = gimple_call_arg (stmt, 2);
+	lhs = gimple_call_lhs (stmt);
+	location_t loc = gimple_location (stmt);
+	gimple_seq stmts = NULL;
+	// convert arg0 and arg1 to match the type of the permute
+	// for the VEC_PERM_EXPR operation.
+	tree permute_type = (TREE_TYPE (permute));
+	tree arg0_ptype = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
+					permute_type, arg0);
+	tree arg1_ptype = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
+					permute_type, arg1);
+	tree lhs_ptype = gimple_build (&stmts, loc, VEC_PERM_EXPR,
+				      permute_type, arg0_ptype, arg1_ptype,
+				      permute);
+	// Convert the result back to the desired lhs type upon completion.
+	tree temp = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
+				  TREE_TYPE (lhs), lhs_ptype);
+	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+	g = gimple_build_assign (lhs, temp);
+	gimple_set_location (g, loc);
+	gsi_replace (gsi, g, true);
+	return true;
+      }
+
+    default:
+      if (TARGET_DEBUG_BUILTIN)
+	fprintf (stderr, "gimple builtin intrinsic not matched:%d %s %s\n",
+		 fn_code, fn_name1, fn_name2);
+      break;
+    }
+
+  return false;
+}
+
+/* **** Expansion support. ****  */
+
+static rtx
+altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
+{
+  rtx pat, scratch;
+  tree cr6_form = CALL_EXPR_ARG (exp, 0);
+  tree arg0 = CALL_EXPR_ARG (exp, 1);
+  tree arg1 = CALL_EXPR_ARG (exp, 2);
+  rtx op0 = expand_normal (arg0);
+  rtx op1 = expand_normal (arg1);
+  machine_mode tmode = SImode;
+  machine_mode mode0 = insn_data[icode].operand[1].mode;
+  machine_mode mode1 = insn_data[icode].operand[2].mode;
+  int cr6_form_int;
+
+  if (TREE_CODE (cr6_form) != INTEGER_CST)
+    {
+      error ("argument 1 of %qs must be a constant",
+	     "__builtin_altivec_predicate");
+      return const0_rtx;
+    }
+  else
+    cr6_form_int = TREE_INT_CST_LOW (cr6_form);
+
+  gcc_assert (mode0 == mode1);
+
+  /* If we have invalid arguments, bail out before generating bad rtl.  */
+  if (arg0 == error_mark_node || arg1 == error_mark_node)
+    return const0_rtx;
+
+  if (target == 0
+      || GET_MODE (target) != tmode
+      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+    target = gen_reg_rtx (tmode);
+
+  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+    op0 = copy_to_mode_reg (mode0, op0);
+  if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+    op1 = copy_to_mode_reg (mode1, op1);
+
+  /* Note that for many of the relevant operations (e.g. cmpne or
+     cmpeq) with float or double operands, it makes more sense for the
+     mode of the allocated scratch register to select a vector of
+     integer.  But the choice to copy the mode of operand 0 was made
+     long ago and there are no plans to change it.  */
+  scratch = gen_reg_rtx (mode0);
+
+  pat = GEN_FCN (icode) (scratch, op0, op1);
+  if (! pat)
+    return 0;
+  emit_insn (pat);
+
+  /* The vec_any* and vec_all* predicates use the same opcodes for two
+     different operations, but the bits in CR6 will be different
+     depending on what information we want.  So we have to play tricks
+     with CR6 to get the right bits out.
+
+     If you think this is disgusting, look at the specs for the
+     AltiVec predicates.  */
+
+  switch (cr6_form_int)
+    {
+    case 0:
+      emit_insn (gen_cr6_test_for_zero (target));
+      break;
+    case 1:
+      emit_insn (gen_cr6_test_for_zero_reverse (target));
+      break;
+    case 2:
+      emit_insn (gen_cr6_test_for_lt (target));
+      break;
+    case 3:
+      emit_insn (gen_cr6_test_for_lt_reverse (target));
+      break;
+    default:
+      error ("argument 1 of %qs is out of range",
+	     "__builtin_altivec_predicate");
+      break;
+    }
+
+  return target;
+}
+
+/* Expand vec_init builtin.  */
+static rtx
+altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
+{
+  machine_mode tmode = TYPE_MODE (type);
+  machine_mode inner_mode = GET_MODE_INNER (tmode);
+  int i, n_elt = GET_MODE_NUNITS (tmode);
+
+  gcc_assert (VECTOR_MODE_P (tmode));
+  gcc_assert (n_elt == call_expr_nargs (exp));
+
+  if (!target || !register_operand (target, tmode))
+    target = gen_reg_rtx (tmode);
+
+  /* If we have a vector compromised of a single element, such as V1TImode, do
+     the initialization directly.  */
+  if (n_elt == 1 && GET_MODE_SIZE (tmode) == GET_MODE_SIZE (inner_mode))
+    {
+      rtx x = expand_normal (CALL_EXPR_ARG (exp, 0));
+      emit_move_insn (target, gen_lowpart (tmode, x));
+    }
+  else
+    {
+      rtvec v = rtvec_alloc (n_elt);
+
+      for (i = 0; i < n_elt; ++i)
+	{
+	  rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
+	  RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
+	}
+
+      rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
+    }
+
+  return target;
+}
+
+/* Return the integer constant in ARG.  Constrain it to be in the range
+   of the subparts of VEC_TYPE; issue an error if not.  */
+
+static int
+get_element_number (tree vec_type, tree arg)
+{
+  unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
+
+  if (!tree_fits_uhwi_p (arg)
+      || (elt = tree_to_uhwi (arg), elt > max))
+    {
+      error ("selector must be an integer constant in the range [0, %wi]", max);
+      return 0;
+    }
+
+  return elt;
+}
+
+/* Expand vec_set builtin.  */
+static rtx
+altivec_expand_vec_set_builtin (tree exp)
+{
+  machine_mode tmode, mode1;
+  tree arg0, arg1, arg2;
+  int elt;
+  rtx op0, op1;
+
+  arg0 = CALL_EXPR_ARG (exp, 0);
+  arg1 = CALL_EXPR_ARG (exp, 1);
+  arg2 = CALL_EXPR_ARG (exp, 2);
+
+  tmode = TYPE_MODE (TREE_TYPE (arg0));
+  mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
+  gcc_assert (VECTOR_MODE_P (tmode));
+
+  op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
+  op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
+  elt = get_element_number (TREE_TYPE (arg0), arg2);
+
+  if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
+    op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
+
+  op0 = force_reg (tmode, op0);
+  op1 = force_reg (mode1, op1);
+
+  rs6000_expand_vector_set (op0, op1, GEN_INT (elt));
+
+  return op0;
+}
+
+/* Expand vec_ext builtin.  */
+static rtx
+altivec_expand_vec_ext_builtin (tree exp, rtx target)
+{
+  machine_mode tmode, mode0;
+  tree arg0, arg1;
+  rtx op0;
+  rtx op1;
+
+  arg0 = CALL_EXPR_ARG (exp, 0);
+  arg1 = CALL_EXPR_ARG (exp, 1);
+
+  op0 = expand_normal (arg0);
+  op1 = expand_normal (arg1);
+
+  if (TREE_CODE (arg1) == INTEGER_CST)
+    {
+      unsigned HOST_WIDE_INT elt;
+      unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+      unsigned int truncated_selector;
+      /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
+	 returns low-order bits of INTEGER_CST for modulo indexing.  */
+      elt = TREE_INT_CST_LOW (arg1);
+      truncated_selector = elt % size;
+      op1 = GEN_INT (truncated_selector);
+    }
+
+  tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
+  mode0 = TYPE_MODE (TREE_TYPE (arg0));
+  gcc_assert (VECTOR_MODE_P (mode0));
+
+  op0 = force_reg (mode0, op0);
+
+  if (optimize || !target || !register_operand (target, tmode))
+    target = gen_reg_rtx (tmode);
+
+  rs6000_expand_vector_extract (target, op0, op1);
+
+  return target;
+}
+
+/* Expand ALTIVEC_BUILTIN_MASK_FOR_LOAD.  */
+rtx
+rs6000_expand_ldst_mask (rtx target, tree arg0)
+{
+  int icode2 = BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
+				: (int) CODE_FOR_altivec_lvsl_direct;
+  machine_mode tmode = insn_data[icode2].operand[0].mode;
+  machine_mode mode = insn_data[icode2].operand[1].mode;
+
+  gcc_assert (TARGET_ALTIVEC);
+
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg0)));
+  rtx op = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
+  rtx addr = memory_address (mode, op);
+  /* We need to negate the address.  */
+  op = gen_reg_rtx (GET_MODE (addr));
+  emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr)));
+  op = gen_rtx_MEM (mode, op);
+
+  if (target == 0
+      || GET_MODE (target) != tmode
+      || !insn_data[icode2].operand[0].predicate (target, tmode))
+    target = gen_reg_rtx (tmode);
+
+  rtx pat = GEN_FCN (icode2) (target, op);
+  if (!pat)
+    return 0;
+  emit_insn (pat);
+
+  return target;
+}
+
+/* Used by __builtin_cpu_is(), mapping from PLATFORM names to values.  */
+static const struct
+{
+  const char *cpu;
+  unsigned int cpuid;
+} cpu_is_info[] = {
+  { "power10",	   PPC_PLATFORM_POWER10 },
+  { "power9",	   PPC_PLATFORM_POWER9 },
+  { "power8",	   PPC_PLATFORM_POWER8 },
+  { "power7",	   PPC_PLATFORM_POWER7 },
+  { "power6x",	   PPC_PLATFORM_POWER6X },
+  { "power6",	   PPC_PLATFORM_POWER6 },
+  { "power5+",	   PPC_PLATFORM_POWER5_PLUS },
+  { "power5",	   PPC_PLATFORM_POWER5 },
+  { "ppc970",	   PPC_PLATFORM_PPC970 },
+  { "power4",	   PPC_PLATFORM_POWER4 },
+  { "ppca2",	   PPC_PLATFORM_PPCA2 },
+  { "ppc476",	   PPC_PLATFORM_PPC476 },
+  { "ppc464",	   PPC_PLATFORM_PPC464 },
+  { "ppc440",	   PPC_PLATFORM_PPC440 },
+  { "ppc405",	   PPC_PLATFORM_PPC405 },
+  { "ppc-cell-be", PPC_PLATFORM_CELL_BE }
+};
+
+/* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks.  */
+static const struct
+{
+  const char *hwcap;
+  int mask;
+  unsigned int id;
+} cpu_supports_info[] = {
+  /* AT_HWCAP masks.  */
+  { "4xxmac",		PPC_FEATURE_HAS_4xxMAC,		0 },
+  { "altivec",		PPC_FEATURE_HAS_ALTIVEC,	0 },
+  { "arch_2_05",	PPC_FEATURE_ARCH_2_05,		0 },
+  { "arch_2_06",	PPC_FEATURE_ARCH_2_06,		0 },
+  { "archpmu",		PPC_FEATURE_PERFMON_COMPAT,	0 },
+  { "booke",		PPC_FEATURE_BOOKE,		0 },
+  { "cellbe",		PPC_FEATURE_CELL_BE,		0 },
+  { "dfp",		PPC_FEATURE_HAS_DFP,		0 },
+  { "efpdouble",	PPC_FEATURE_HAS_EFP_DOUBLE,	0 },
+  { "efpsingle",	PPC_FEATURE_HAS_EFP_SINGLE,	0 },
+  { "fpu",		PPC_FEATURE_HAS_FPU,		0 },
+  { "ic_snoop",		PPC_FEATURE_ICACHE_SNOOP,	0 },
+  { "mmu",		PPC_FEATURE_HAS_MMU,		0 },
+  { "notb",		PPC_FEATURE_NO_TB,		0 },
+  { "pa6t",		PPC_FEATURE_PA6T,		0 },
+  { "power4",		PPC_FEATURE_POWER4,		0 },
+  { "power5",		PPC_FEATURE_POWER5,		0 },
+  { "power5+",		PPC_FEATURE_POWER5_PLUS,	0 },
+  { "power6x",		PPC_FEATURE_POWER6_EXT,		0 },
+  { "ppc32",		PPC_FEATURE_32,			0 },
+  { "ppc601",		PPC_FEATURE_601_INSTR,		0 },
+  { "ppc64",		PPC_FEATURE_64,			0 },
+  { "ppcle",		PPC_FEATURE_PPC_LE,		0 },
+  { "smt",		PPC_FEATURE_SMT,		0 },
+  { "spe",		PPC_FEATURE_HAS_SPE,		0 },
+  { "true_le",		PPC_FEATURE_TRUE_LE,		0 },
+  { "ucache",		PPC_FEATURE_UNIFIED_CACHE,	0 },
+  { "vsx",		PPC_FEATURE_HAS_VSX,		0 },
+
+  /* AT_HWCAP2 masks.  */
+  { "arch_2_07",	PPC_FEATURE2_ARCH_2_07,		1 },
+  { "dscr",		PPC_FEATURE2_HAS_DSCR,		1 },
+  { "ebb",		PPC_FEATURE2_HAS_EBB,		1 },
+  { "htm",		PPC_FEATURE2_HAS_HTM,		1 },
+  { "htm-nosc",		PPC_FEATURE2_HTM_NOSC,		1 },
+  { "htm-no-suspend",	PPC_FEATURE2_HTM_NO_SUSPEND,	1 },
+  { "isel",		PPC_FEATURE2_HAS_ISEL,		1 },
+  { "tar",		PPC_FEATURE2_HAS_TAR,		1 },
+  { "vcrypto",		PPC_FEATURE2_HAS_VEC_CRYPTO,	1 },
+  { "arch_3_00",	PPC_FEATURE2_ARCH_3_00,		1 },
+  { "ieee128",		PPC_FEATURE2_HAS_IEEE128,	1 },
+  { "darn",		PPC_FEATURE2_DARN,		1 },
+  { "scv",		PPC_FEATURE2_SCV,		1 },
+  { "arch_3_1",		PPC_FEATURE2_ARCH_3_1,		1 },
+  { "mma",		PPC_FEATURE2_MMA,		1 },
+};
+
+/* Expand the CPU builtin in FCODE and store the result in TARGET.  */
+static rtx
+cpu_expand_builtin (enum rs6000_gen_builtins fcode,
+		    tree exp ATTRIBUTE_UNUSED, rtx target)
+{
+  /* __builtin_cpu_init () is a nop, so expand to nothing.  */
+  if (fcode == RS6000_BIF_CPU_INIT)
+    return const0_rtx;
+
+  if (target == 0 || GET_MODE (target) != SImode)
+    target = gen_reg_rtx (SImode);
+
+  /* TODO: Factor the #ifdef'd code into a separate function.  */
+#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
+  tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
+  /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back
+     to a STRING_CST.  */
+  if (TREE_CODE (arg) == ARRAY_REF
+      && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST
+      && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST
+      && compare_tree_int (TREE_OPERAND (arg, 1), 0) == 0)
+    arg = TREE_OPERAND (arg, 0);
+
+  if (TREE_CODE (arg) != STRING_CST)
+    {
+      error ("builtin %qs only accepts a string argument",
+	     rs6000_builtin_info[(size_t) fcode].bifname);
+      return const0_rtx;
+    }
+
+  if (fcode == RS6000_BIF_CPU_IS)
+    {
+      const char *cpu = TREE_STRING_POINTER (arg);
+      rtx cpuid = NULL_RTX;
+      for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++)
+	if (strcmp (cpu, cpu_is_info[i].cpu) == 0)
+	  {
+	    /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM.  */
+	    cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM);
+	    break;
+	  }
+      if (cpuid == NULL_RTX)
+	{
+	  /* Invalid CPU argument.  */
+	  error ("cpu %qs is an invalid argument to builtin %qs",
+		 cpu, rs6000_builtin_info[(size_t) fcode].bifname);
+	  return const0_rtx;
+	}
+
+      rtx platform = gen_reg_rtx (SImode);
+      rtx address = gen_rtx_PLUS (Pmode,
+				  gen_rtx_REG (Pmode, TLS_REGNUM),
+				  GEN_INT (TCB_PLATFORM_OFFSET));
+      rtx tcbmem = gen_const_mem (SImode, address);
+      emit_move_insn (platform, tcbmem);
+      emit_insn (gen_eqsi3 (target, platform, cpuid));
+    }
+  else if (fcode == RS6000_BIF_CPU_SUPPORTS)
+    {
+      const char *hwcap = TREE_STRING_POINTER (arg);
+      rtx mask = NULL_RTX;
+      int hwcap_offset;
+      for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++)
+	if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0)
+	  {
+	    mask = GEN_INT (cpu_supports_info[i].mask);
+	    hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id);
+	    break;
+	  }
+      if (mask == NULL_RTX)
+	{
+	  /* Invalid HWCAP argument.  */
+	  error ("%s %qs is an invalid argument to builtin %qs",
+		 "hwcap", hwcap,
+		 rs6000_builtin_info[(size_t) fcode].bifname);
+	  return const0_rtx;
+	}
+
+      rtx tcb_hwcap = gen_reg_rtx (SImode);
+      rtx address = gen_rtx_PLUS (Pmode,
+				  gen_rtx_REG (Pmode, TLS_REGNUM),
+				  GEN_INT (hwcap_offset));
+      rtx tcbmem = gen_const_mem (SImode, address);
+      emit_move_insn (tcb_hwcap, tcbmem);
+      rtx scratch1 = gen_reg_rtx (SImode);
+      emit_insn (gen_rtx_SET (scratch1,
+			      gen_rtx_AND (SImode, tcb_hwcap, mask)));
+      rtx scratch2 = gen_reg_rtx (SImode);
+      emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
+      emit_insn (gen_rtx_SET (target,
+			      gen_rtx_XOR (SImode, scratch2, const1_rtx)));
+    }
+  else
+    gcc_unreachable ();
+
+  /* Record that we have expanded a CPU builtin, so that we can later
+     emit a reference to the special symbol exported by LIBC to ensure we
+     do not link against an old LIBC that doesn't support this feature.  */
+  cpu_builtin_p = true;
+
+#else
+  warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware "
+	   "capability bits", rs6000_builtin_info[(size_t) fcode].bifname);
+
+  /* For old LIBCs, always return FALSE.  */
+  emit_move_insn (target, GEN_INT (0));
+#endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
+
+  return target;
+}
+
+/* For the element-reversing load/store built-ins, produce the correct
+   insn_code depending on the target endianness.  */
+static insn_code
+elemrev_icode (rs6000_gen_builtins fcode)
+{
+  switch (fcode)
+    {
+    case RS6000_BIF_ST_ELEMREV_V1TI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+			      : CODE_FOR_vsx_st_elemrev_v1ti;
+
+    case RS6000_BIF_ST_ELEMREV_V2DF:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+			      : CODE_FOR_vsx_st_elemrev_v2df;
+
+    case RS6000_BIF_ST_ELEMREV_V2DI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+			      : CODE_FOR_vsx_st_elemrev_v2di;
+
+    case RS6000_BIF_ST_ELEMREV_V4SF:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+			      : CODE_FOR_vsx_st_elemrev_v4sf;
+
+    case RS6000_BIF_ST_ELEMREV_V4SI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+			      : CODE_FOR_vsx_st_elemrev_v4si;
+
+    case RS6000_BIF_ST_ELEMREV_V8HI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+			      : CODE_FOR_vsx_st_elemrev_v8hi;
+
+    case RS6000_BIF_ST_ELEMREV_V16QI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+			      : CODE_FOR_vsx_st_elemrev_v16qi;
+
+    case RS6000_BIF_LD_ELEMREV_V2DF:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+			      : CODE_FOR_vsx_ld_elemrev_v2df;
+
+    case RS6000_BIF_LD_ELEMREV_V1TI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+			      : CODE_FOR_vsx_ld_elemrev_v1ti;
+
+    case RS6000_BIF_LD_ELEMREV_V2DI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+			      : CODE_FOR_vsx_ld_elemrev_v2di;
+
+    case RS6000_BIF_LD_ELEMREV_V4SF:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+			      : CODE_FOR_vsx_ld_elemrev_v4sf;
+
+    case RS6000_BIF_LD_ELEMREV_V4SI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+			      : CODE_FOR_vsx_ld_elemrev_v4si;
+
+    case RS6000_BIF_LD_ELEMREV_V8HI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+			      : CODE_FOR_vsx_ld_elemrev_v8hi;
+
+    case RS6000_BIF_LD_ELEMREV_V16QI:
+      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+			      : CODE_FOR_vsx_ld_elemrev_v16qi;
+    default:
+      ;
+    }
+
+  gcc_unreachable ();
+}
+
+/* Expand an AltiVec vector load builtin, and return the expanded rtx.  */
+static rtx
+ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
+{
+  if (target == 0
+      || GET_MODE (target) != tmode
+      || !insn_data[icode].operand[0].predicate (target, tmode))
+    target = gen_reg_rtx (tmode);
+
+  op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+  /* These CELL built-ins use BLKmode instead of tmode for historical
+     (i.e., unknown) reasons.  TODO: Is this necessary?  */
+  bool blk = (icode == CODE_FOR_altivec_lvlx
+	      || icode == CODE_FOR_altivec_lvlxl
+	      || icode == CODE_FOR_altivec_lvrx
+	      || icode == CODE_FOR_altivec_lvrxl);
+
+  /* For LVX, express the RTL accurately by ANDing the address with -16.
+     LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+     so the raw address is fine.  */
+  /* TODO: That statement seems wrong, as the UNSPECs don't surround the
+     memory expression, so a latent bug may lie here.  The &-16 is likely
+     needed for all VMX-style loads.  */
+  if (icode == CODE_FOR_altivec_lvx_v1ti
+      || icode == CODE_FOR_altivec_lvx_v2df
+      || icode == CODE_FOR_altivec_lvx_v2di
+      || icode == CODE_FOR_altivec_lvx_v4sf
+      || icode == CODE_FOR_altivec_lvx_v4si
+      || icode == CODE_FOR_altivec_lvx_v8hi
+      || icode == CODE_FOR_altivec_lvx_v16qi)
+    {
+      rtx rawaddr;
+      if (op[0] == const0_rtx)
+	rawaddr = op[1];
+      else
+	{
+	  op[0] = copy_to_mode_reg (Pmode, op[0]);
+	  rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
+	}
+      rtx addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+      addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+      emit_insn (gen_rtx_SET (target, addr));
+    }
+  else
+    {
+      rtx addr;
+      if (op[0] == const0_rtx)
+	addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
+      else
+	{
+	  op[0] = copy_to_mode_reg (Pmode, op[0]);
+	  addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+			      gen_rtx_PLUS (Pmode, op[1], op[0]));
+	}
+
+      rtx pat = GEN_FCN (icode) (target, addr);
+      if (!pat)
+	return 0;
+      emit_insn (pat);
+    }
+
+  return target;
+}
+
+/* Expand a builtin function that loads a scalar into a vector register
+   with sign extension, and return the expanded rtx.  */
+static rtx
+lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
+		       machine_mode tmode, machine_mode smode)
+{
+  rtx pat, addr;
+  op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+  if (op[0] == const0_rtx)
+    addr = gen_rtx_MEM (tmode, op[1]);
+  else
+    {
+      op[0] = copy_to_mode_reg (Pmode, op[0]);
+      addr = gen_rtx_MEM (smode,
+			  gen_rtx_PLUS (Pmode, op[1], op[0]));
+    }
+
+  rtx discratch = gen_reg_rtx (V2DImode);
+  rtx tiscratch = gen_reg_rtx (TImode);
+
+  /* Emit the lxvr*x insn.  */
+  pat = GEN_FCN (icode) (tiscratch, addr);
+  if (!pat)
+    return 0;
+  emit_insn (pat);
+
+  /* Emit a sign extension from V16QI,V8HI,V4SI to V2DI.  */
+  rtx temp1;
+  if (icode == CODE_FOR_vsx_lxvrbx)
+    {
+      temp1  = simplify_gen_subreg (V16QImode, tiscratch, TImode, 0);
+      emit_insn (gen_vsx_sign_extend_qi_v2di (discratch, temp1));
+    }
+  else if (icode == CODE_FOR_vsx_lxvrhx)
+    {
+      temp1  = simplify_gen_subreg (V8HImode, tiscratch, TImode, 0);
+      emit_insn (gen_vsx_sign_extend_hi_v2di (discratch, temp1));
+    }
+  else if (icode == CODE_FOR_vsx_lxvrwx)
+    {
+      temp1  = simplify_gen_subreg (V4SImode, tiscratch, TImode, 0);
+      emit_insn (gen_vsx_sign_extend_si_v2di (discratch, temp1));
+    }
+  else if (icode == CODE_FOR_vsx_lxvrdx)
+    discratch = simplify_gen_subreg (V2DImode, tiscratch, TImode, 0);
+  else
+    gcc_unreachable ();
+
+  /* Emit the sign extension from V2DI (double) to TI (quad).  */
+  rtx temp2 = simplify_gen_subreg (TImode, discratch, V2DImode, 0);
+  emit_insn (gen_extendditi2_vector (target, temp2));
+
+  return target;
+}
+
+/* Expand a builtin function that loads a scalar into a vector register
+   with zero extension, and return the expanded rtx.  */
+static rtx
+lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
+		       machine_mode tmode, machine_mode smode)
+{
+  rtx pat, addr;
+  op[1] = copy_to_mode_reg (Pmode, op[1]);
+
+  if (op[0] == const0_rtx)
+    addr = gen_rtx_MEM (tmode, op[1]);
+  else
+    {
+      op[0] = copy_to_mode_reg (Pmode, op[0]);
+      addr = gen_rtx_MEM (smode,
+			  gen_rtx_PLUS (Pmode, op[1], op[0]));
+    }
+
+  pat = GEN_FCN (icode) (target, addr);
+  if (!pat)
+    return 0;
+  emit_insn (pat);
+  return target;
+}
+
+/* Expand an AltiVec vector store builtin, and return the expanded rtx.  */
+static rtx
+stv_expand_builtin (insn_code icode, rtx *op,
+		    machine_mode tmode, machine_mode smode)
+{
+  op[2] = copy_to_mode_reg (Pmode, op[2]);
+
+  /* For STVX, express the RTL accurately by ANDing the address with -16.
+     STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+     so the raw address is fine.  */
+  /* TODO: That statement seems wrong, as the UNSPECs don't surround the
+     memory expression, so a latent bug may lie here.  The &-16 is likely
+     needed for all VMX-style stores.  */
+  if (icode == CODE_FOR_altivec_stvx_v2df
+      || icode == CODE_FOR_altivec_stvx_v2di
+      || icode == CODE_FOR_altivec_stvx_v4sf
+      || icode == CODE_FOR_altivec_stvx_v4si
+      || icode == CODE_FOR_altivec_stvx_v8hi
+      || icode == CODE_FOR_altivec_stvx_v16qi)
+    {
+      rtx rawaddr;
+      if (op[1] == const0_rtx)
+	rawaddr = op[2];
+      else
+	{
+	  op[1] = copy_to_mode_reg (Pmode, op[1]);
+	  rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
+	}
+
+      rtx addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+      addr = gen_rtx_MEM (tmode, addr);
+      op[0] = copy_to_mode_reg (tmode, op[0]);
+      emit_insn (gen_rtx_SET (addr, op[0]));
+    }
+  else if (icode == CODE_FOR_vsx_stxvrbx
+	   || icode == CODE_FOR_vsx_stxvrhx
+	   || icode == CODE_FOR_vsx_stxvrwx
+	   || icode == CODE_FOR_vsx_stxvrdx)
+    {
+      rtx truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
+      op[0] = copy_to_mode_reg (E_TImode, truncrtx);
+
+      rtx addr;
+      if (op[1] == const0_rtx)
+	addr = gen_rtx_MEM (Pmode, op[2]);
+      else
+	{
+	  op[1] = copy_to_mode_reg (Pmode, op[1]);
+	  addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+	}
+      rtx pat = GEN_FCN (icode) (addr, op[0]);
+      if (pat)
+	emit_insn (pat);
+    }
+  else
+    {
+      if (!insn_data[icode].operand[1].predicate (op[0], smode))
+	op[0] = copy_to_mode_reg (smode, op[0]);
+
+      rtx addr;
+      if (op[1] == const0_rtx)
+	addr = gen_rtx_MEM (tmode, op[2]);
+      else
+	{
+	  op[1] = copy_to_mode_reg (Pmode, op[1]);
+	  addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
+	}
+
+      rtx pat = GEN_FCN (icode) (addr, op[0]);
+      if (pat)
+	emit_insn (pat);
+    }
+
+  return NULL_RTX;
+}
+
+/* Expand the MMA built-in in EXP, and return it.  */
+static rtx
+mma_expand_builtin (tree exp, rtx target, insn_code icode,
+		    rs6000_gen_builtins fcode)
+{
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
+  machine_mode tmode = VOIDmode;
+  rtx op[MAX_MMA_OPERANDS];
+  unsigned nopnds = 0;
+
+  if (!void_func)
+    {
+      tmode = insn_data[icode].operand[0].mode;
+      if (!(target
+	    && GET_MODE (target) == tmode
+	    && insn_data[icode].operand[0].predicate (target, tmode)))
+	target = gen_reg_rtx (tmode);
+      op[nopnds++] = target;
+    }
+  else
+    target = const0_rtx;
+
+  call_expr_arg_iterator iter;
+  tree arg;
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+    {
+      if (arg == error_mark_node)
+	return const0_rtx;
+
+      rtx opnd;
+      const struct insn_operand_data *insn_op;
+      insn_op = &insn_data[icode].operand[nopnds];
+      if (TREE_CODE (arg) == ADDR_EXPR
+	  && MEM_P (DECL_RTL (TREE_OPERAND (arg, 0))))
+	opnd = DECL_RTL (TREE_OPERAND (arg, 0));
+      else
+	opnd = expand_normal (arg);
+
+      if (!insn_op->predicate (opnd, insn_op->mode))
+	{
+	  /* TODO: This use of constraints needs explanation.  */
+	  if (!strcmp (insn_op->constraint, "n"))
+	    {
+	      if (!CONST_INT_P (opnd))
+		error ("argument %d must be an unsigned literal", nopnds);
+	      else
+		error ("argument %d is an unsigned literal that is "
+		       "out of range", nopnds);
+	      return const0_rtx;
+	    }
+	  opnd = copy_to_mode_reg (insn_op->mode, opnd);
+	}
+
+      /* Some MMA instructions have INOUT accumulator operands, so force
+	 their target register to be the same as their input register.  */
+      if (!void_func
+	  && nopnds == 1
+	  && !strcmp (insn_op->constraint, "0")
+	  && insn_op->mode == tmode
+	  && REG_P (opnd)
+	  && insn_data[icode].operand[0].predicate (opnd, tmode))
+	target = op[0] = opnd;
+
+      op[nopnds++] = opnd;
+    }
+
+  rtx pat;
+  switch (nopnds)
+    {
+    case 1:
+      pat = GEN_FCN (icode) (op[0]);
+      break;
+    case 2:
+      pat = GEN_FCN (icode) (op[0], op[1]);
+      break;
+    case 3:
+      /* The ASSEMBLE builtin source operands are reversed in little-endian
+	 mode, so reorder them.  */
+      if (fcode == RS6000_BIF_ASSEMBLE_PAIR_V_INTERNAL && !WORDS_BIG_ENDIAN)
+	std::swap (op[1], op[2]);
+      pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+      break;
+    case 4:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+      break;
+    case 5:
+      /* The ASSEMBLE builtin source operands are reversed in little-endian
+	 mode, so reorder them.  */
+      if (fcode == RS6000_BIF_ASSEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN)
+	{
+	  std::swap (op[1], op[4]);
+	  std::swap (op[2], op[3]);
+	}
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
+      break;
+    case 6:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
+      break;
+    case 7:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6]);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  if (!pat)
+    return NULL_RTX;
+
+  emit_insn (pat);
+  return target;
+}
+
+/* Return the correct ICODE value depending on whether we are
+   setting or reading the HTM SPRs.  */
+static inline enum insn_code
+rs6000_htm_spr_icode (bool nonvoid)
+{
+  if (nonvoid)
+    return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si;
+  else
+    return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si;
+}
+
+/* Return the appropriate SPR number associated with the given builtin.  */
+static inline HOST_WIDE_INT
+htm_spr_num (enum rs6000_gen_builtins code)
+{
+  if (code == RS6000_BIF_GET_TFHAR
+      || code == RS6000_BIF_SET_TFHAR)
+    return TFHAR_SPR;
+  else if (code == RS6000_BIF_GET_TFIAR
+	   || code == RS6000_BIF_SET_TFIAR)
+    return TFIAR_SPR;
+  else if (code == RS6000_BIF_GET_TEXASR
+	   || code == RS6000_BIF_SET_TEXASR)
+    return TEXASR_SPR;
+  gcc_assert (code == RS6000_BIF_GET_TEXASRU
+	      || code == RS6000_BIF_SET_TEXASRU);
+  return TEXASRU_SPR;
+}
+
+/* Expand the HTM builtin in EXP and store the result in TARGET.
+   Return the expanded rtx.  */
+static rtx
+htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode,
+		    tree exp, rtx target)
+{
+  if (!TARGET_POWERPC64
+      && (fcode == RS6000_BIF_TABORTDC
+	  || fcode == RS6000_BIF_TABORTDCI))
+    {
+      error ("builtin %qs is only valid in 64-bit mode", bifaddr->bifname);
+      return const0_rtx;
+    }
+
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+  bool uses_spr = bif_is_htmspr (*bifaddr);
+  insn_code icode = bifaddr->icode;
+
+  if (uses_spr)
+    icode = rs6000_htm_spr_icode (nonvoid);
+
+  rtx op[MAX_HTM_OPERANDS];
+  int nopnds = 0;
+  const insn_operand_data *insn_op = &insn_data[icode].operand[0];
+
+  if (nonvoid)
+    {
+      machine_mode tmode = (uses_spr) ? insn_op->mode : E_SImode;
+      if (!target
+	  || GET_MODE (target) != tmode
+	  || (uses_spr && !insn_op->predicate (target, tmode)))
+	target = gen_reg_rtx (tmode);
+      if (uses_spr)
+	op[nopnds++] = target;
+    }
+
+  tree arg;
+  call_expr_arg_iterator iter;
+
+  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+    {
+      if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS)
+	return const0_rtx;
+
+      insn_op = &insn_data[icode].operand[nopnds];
+      op[nopnds] = expand_normal (arg);
+
+      if (!insn_op->predicate (op[nopnds], insn_op->mode))
+	{
+	  /* TODO: This use of constraints could use explanation.
+	     This happens a couple of places, perhaps make that a
+	     function to document what's happening.  */
+	  if (!strcmp (insn_op->constraint, "n"))
+	    {
+	      int arg_num = nonvoid ? nopnds : nopnds + 1;
+	      if (!CONST_INT_P (op[nopnds]))
+		error ("argument %d must be an unsigned literal", arg_num);
+	      else
+		error ("argument %d is an unsigned literal that is "
+		       "out of range", arg_num);
+	      return const0_rtx;
+	    }
+	  op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
+	}
+
+      nopnds++;
+    }
+
+  /* Handle the builtins for extended mnemonics.  These accept
+     no arguments, but map to builtins that take arguments.  */
+  switch (fcode)
+    {
+    case RS6000_BIF_TENDALL:  /* Alias for: tend. 1  */
+    case RS6000_BIF_TRESUME:  /* Alias for: tsr. 1  */
+      op[nopnds++] = GEN_INT (1);
+      break;
+    case RS6000_BIF_TSUSPEND: /* Alias for: tsr. 0  */
+      op[nopnds++] = GEN_INT (0);
+      break;
+    default:
+      break;
+    }
+
+  /* If this builtin accesses SPRs, then pass in the appropriate
+     SPR number and SPR regno as the last two operands.  */
+  rtx cr = NULL_RTX;
+  if (uses_spr)
+    {
+      machine_mode mode = TARGET_POWERPC64 ? DImode : SImode;
+      op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode));
+    }
+  /* If this builtin accesses a CR field, then pass in a scratch
+     CR field as the last operand.  */
+  else if (bif_is_htmcr (*bifaddr))
+    {
+      cr = gen_reg_rtx (CCmode);
+      op[nopnds++] = cr;
+    }
+
+  rtx pat;
+  switch (nopnds)
+    {
+    case 1:
+      pat = GEN_FCN (icode) (op[0]);
+      break;
+    case 2:
+      pat = GEN_FCN (icode) (op[0], op[1]);
+      break;
+    case 3:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+      break;
+    case 4:
+      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  if (!pat)
+    return NULL_RTX;
+  emit_insn (pat);
+
+  if (bif_is_htmcr (*bifaddr))
+    {
+      if (fcode == RS6000_BIF_TBEGIN)
+	{
+	  /* Emit code to set TARGET to true or false depending on
+	     whether the tbegin. instruction succeeded or failed
+	     to start a transaction.  We do this by placing the 1's
+	     complement of CR's EQ bit into TARGET.  */
+	  rtx scratch = gen_reg_rtx (SImode);
+	  emit_insn (gen_rtx_SET (scratch,
+				  gen_rtx_EQ (SImode, cr,
+					      const0_rtx)));
+	  emit_insn (gen_rtx_SET (target,
+				  gen_rtx_XOR (SImode, scratch,
+					       GEN_INT (1))));
+	}
+      else
+	{
+	  /* Emit code to copy the 4-bit condition register field
+	     CR into the least significant end of register TARGET.  */
+	  rtx scratch1 = gen_reg_rtx (SImode);
+	  rtx scratch2 = gen_reg_rtx (SImode);
+	  rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0);
+	  emit_insn (gen_movcc (subreg, cr));
+	  emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28)));
+	  emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf)));
+	}
+    }
+
+  if (nonvoid)
+    return target;
+  return const0_rtx;
+}
+
+/* Expand an expression EXP that calls a built-in function,
+   with result going to TARGET if that's convenient
+   (and in mode MODE if that's convenient).
+   SUBTARGET may be used as the target for computing one of EXP's operands.
+   IGNORE is nonzero if the value is to be ignored.
+   Use the new builtin infrastructure.  */
+rtx
+rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
+		       machine_mode /* mode */, int ignore)
+{
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  enum rs6000_gen_builtins fcode
+    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
+  size_t uns_fcode = (size_t)fcode;
+  enum insn_code icode = rs6000_builtin_info[uns_fcode].icode;
+
+  /* TODO: The following commentary and code is inherited from the original
+     builtin processing code.  The commentary is a bit confusing, with the
+     intent being that KFmode is always IEEE-128, IFmode is always IBM
+     double-double, and TFmode is the current long double.  The code is
+     confusing in that it converts from KFmode to TFmode pattern names,
+     when the other direction is more intuitive.  Try to address this.  */
+
+  /* We have two different modes (KFmode, TFmode) that are the IEEE
+     128-bit floating point type, depending on whether long double is the
+     IBM extended double (KFmode) or long double is IEEE 128-bit (TFmode).
+     It is simpler if we only define one variant of the built-in function,
+     and switch the code when defining it, rather than defining two built-
+     ins and using the overload table in rs6000-c.cc to switch between the
+     two.  If we don't have the proper assembler, don't do this switch
+     because CODE_FOR_*kf* and CODE_FOR_*tf* will be CODE_FOR_nothing.  */
+  if (FLOAT128_IEEE_P (TFmode))
+    switch (icode)
+      {
+      case CODE_FOR_sqrtkf2_odd:
+	icode = CODE_FOR_sqrttf2_odd;
+	break;
+      case CODE_FOR_trunckfdf2_odd:
+	icode = CODE_FOR_trunctfdf2_odd;
+	break;
+      case CODE_FOR_addkf3_odd:
+	icode = CODE_FOR_addtf3_odd;
+	break;
+      case CODE_FOR_subkf3_odd:
+	icode = CODE_FOR_subtf3_odd;
+	break;
+      case CODE_FOR_mulkf3_odd:
+	icode = CODE_FOR_multf3_odd;
+	break;
+      case CODE_FOR_divkf3_odd:
+	icode = CODE_FOR_divtf3_odd;
+	break;
+      case CODE_FOR_fmakf4_odd:
+	icode = CODE_FOR_fmatf4_odd;
+	break;
+      case CODE_FOR_xsxexpqp_kf:
+	icode = CODE_FOR_xsxexpqp_tf;
+	break;
+      case CODE_FOR_xsxsigqp_kf:
+	icode = CODE_FOR_xsxsigqp_tf;
+	break;
+      case CODE_FOR_xststdcnegqp_kf:
+	icode = CODE_FOR_xststdcnegqp_tf;
+	break;
+      case CODE_FOR_xsiexpqp_kf:
+	icode = CODE_FOR_xsiexpqp_tf;
+	break;
+      case CODE_FOR_xsiexpqpf_kf:
+	icode = CODE_FOR_xsiexpqpf_tf;
+	break;
+      case CODE_FOR_xststdcqp_kf:
+	icode = CODE_FOR_xststdcqp_tf;
+	break;
+      case CODE_FOR_xscmpexpqp_eq_kf:
+	icode = CODE_FOR_xscmpexpqp_eq_tf;
+	break;
+      case CODE_FOR_xscmpexpqp_lt_kf:
+	icode = CODE_FOR_xscmpexpqp_lt_tf;
+	break;
+      case CODE_FOR_xscmpexpqp_gt_kf:
+	icode = CODE_FOR_xscmpexpqp_gt_tf;
+	break;
+      case CODE_FOR_xscmpexpqp_unordered_kf:
+	icode = CODE_FOR_xscmpexpqp_unordered_tf;
+	break;
+      default:
+	break;
+      }
+
+  /* In case of "#pragma target" changes, we initialize all builtins
+     but check for actual availability now, during expand time.  For
+     invalid builtins, generate a normal call.  */
+  bifdata *bifaddr = &rs6000_builtin_info[uns_fcode];
+  bif_enable e = bifaddr->enable;
+
+  if (!(e == ENB_ALWAYS
+	|| (e == ENB_P5 && TARGET_POPCNTB)
+	|| (e == ENB_P6 && TARGET_CMPB)
+	|| (e == ENB_P6_64 && TARGET_CMPB && TARGET_POWERPC64)
+	|| (e == ENB_ALTIVEC && TARGET_ALTIVEC)
+	|| (e == ENB_CELL && TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL)
+	|| (e == ENB_VSX && TARGET_VSX)
+	|| (e == ENB_P7 && TARGET_POPCNTD)
+	|| (e == ENB_P7_64 && TARGET_POPCNTD && TARGET_POWERPC64)
+	|| (e == ENB_P8 && TARGET_DIRECT_MOVE)
+	|| (e == ENB_P8V && TARGET_P8_VECTOR)
+	|| (e == ENB_P9 && TARGET_MODULO)
+	|| (e == ENB_P9_64 && TARGET_MODULO && TARGET_POWERPC64)
+	|| (e == ENB_P9V && TARGET_P9_VECTOR)
+	|| (e == ENB_IEEE128_HW && TARGET_FLOAT128_HW)
+	|| (e == ENB_DFP && TARGET_DFP)
+	|| (e == ENB_CRYPTO && TARGET_CRYPTO)
+	|| (e == ENB_HTM && TARGET_HTM)
+	|| (e == ENB_P10 && TARGET_POWER10)
+	|| (e == ENB_P10_64 && TARGET_POWER10 && TARGET_POWERPC64)
+	|| (e == ENB_MMA && TARGET_MMA)))
+    {
+      rs6000_invalid_builtin (fcode);
+      return expand_call (exp, target, ignore);
+    }
+
+  if (bif_is_nosoft (*bifaddr)
+      && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
+    {
+      error ("%qs not supported with %<-msoft-float%>",
+	     bifaddr->bifname);
+      return const0_rtx;
+    }
+
+  if (bif_is_no32bit (*bifaddr) && TARGET_32BIT)
+    {
+      error ("%qs is not supported in 32-bit mode", bifaddr->bifname);
+      return const0_rtx;
+    }
+
+  if (bif_is_ibmld (*bifaddr) && !FLOAT128_2REG_P (TFmode))
+    {
+      error ("%qs requires %<long double%> to be IBM 128-bit format",
+	     bifaddr->bifname);
+      return const0_rtx;
+    }
+
+  if (bif_is_cpu (*bifaddr))
+    return cpu_expand_builtin (fcode, exp, target);
+
+  if (bif_is_init (*bifaddr))
+    return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
+
+  if (bif_is_set (*bifaddr))
+    return altivec_expand_vec_set_builtin (exp);
+
+  if (bif_is_extract (*bifaddr))
+    return altivec_expand_vec_ext_builtin (exp, target);
+
+  if (bif_is_predicate (*bifaddr))
+    return altivec_expand_predicate_builtin (icode, exp, target);
+
+  if (bif_is_htm (*bifaddr))
+    return htm_expand_builtin (bifaddr, fcode, exp, target);
+
+  if (bif_is_32bit (*bifaddr) && TARGET_32BIT)
+    {
+      if (fcode == RS6000_BIF_MFTB)
+	icode = CODE_FOR_rs6000_mftb_si;
+      else if (fcode == RS6000_BIF_BPERMD)
+	icode = CODE_FOR_bpermd_si;
+      else if (fcode == RS6000_BIF_DARN)
+	icode = CODE_FOR_darn_64_si;
+      else if (fcode == RS6000_BIF_DARN_32)
+	icode = CODE_FOR_darn_32_si;
+      else if (fcode == RS6000_BIF_DARN_RAW)
+	icode = CODE_FOR_darn_raw_si;
+      else
+	gcc_unreachable ();
+    }
+
+  if (bif_is_endian (*bifaddr) && BYTES_BIG_ENDIAN)
+    {
+      if (fcode == RS6000_BIF_LD_ELEMREV_V1TI)
+	icode = CODE_FOR_vsx_load_v1ti;
+      else if (fcode == RS6000_BIF_LD_ELEMREV_V2DF)
+	icode = CODE_FOR_vsx_load_v2df;
+      else if (fcode == RS6000_BIF_LD_ELEMREV_V2DI)
+	icode = CODE_FOR_vsx_load_v2di;
+      else if (fcode == RS6000_BIF_LD_ELEMREV_V4SF)
+	icode = CODE_FOR_vsx_load_v4sf;
+      else if (fcode == RS6000_BIF_LD_ELEMREV_V4SI)
+	icode = CODE_FOR_vsx_load_v4si;
+      else if (fcode == RS6000_BIF_LD_ELEMREV_V8HI)
+	icode = CODE_FOR_vsx_load_v8hi;
+      else if (fcode == RS6000_BIF_LD_ELEMREV_V16QI)
+	icode = CODE_FOR_vsx_load_v16qi;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V1TI)
+	icode = CODE_FOR_vsx_store_v1ti;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V2DF)
+	icode = CODE_FOR_vsx_store_v2df;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V2DI)
+	icode = CODE_FOR_vsx_store_v2di;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V4SF)
+	icode = CODE_FOR_vsx_store_v4sf;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V4SI)
+	icode = CODE_FOR_vsx_store_v4si;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V8HI)
+	icode = CODE_FOR_vsx_store_v8hi;
+      else if (fcode == RS6000_BIF_ST_ELEMREV_V16QI)
+	icode = CODE_FOR_vsx_store_v16qi;
+      else
+	gcc_unreachable ();
+    }
+
+
+  /* TRUE iff the built-in function returns void.  */
+  bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
+  /* Position of first argument (0 for void-returning functions, else 1).  */
+  int k;
+  /* Modes for the return value, if any, and arguments.  */
+  const int MAX_BUILTIN_ARGS = 6;
+  machine_mode mode[MAX_BUILTIN_ARGS + 1];
+
+  if (void_func)
+    k = 0;
+  else
+    {
+      k = 1;
+      mode[0] = insn_data[icode].operand[0].mode;
+    }
+
+  /* Tree expressions for each argument.  */
+  tree arg[MAX_BUILTIN_ARGS];
+  /* RTL expressions for each argument.  */
+  rtx op[MAX_BUILTIN_ARGS];
+
+  int nargs = bifaddr->nargs;
+  gcc_assert (nargs <= MAX_BUILTIN_ARGS);
+
+
+  for (int i = 0; i < nargs; i++)
+    {
+      arg[i] = CALL_EXPR_ARG (exp, i);
+      if (arg[i] == error_mark_node)
+	return const0_rtx;
+      STRIP_NOPS (arg[i]);
+      op[i] = expand_normal (arg[i]);
+      /* We have a couple of pesky patterns that don't specify the mode...  */
+      mode[i+k] = insn_data[icode].operand[i+k].mode;
+      if (!mode[i+k])
+	mode[i+k] = Pmode;
+    }
+
+  /* Check for restricted constant arguments.  */
+  for (int i = 0; i < 2; i++)
+    {
+      switch (bifaddr->restr[i])
+	{
+	case RES_BITS:
+	  {
+	    size_t mask = 1;
+	    mask <<= bifaddr->restr_val1[i];
+	    mask--;
+	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
+	    STRIP_NOPS (restr_arg);
+	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
+		  && (TREE_INT_CST_LOW (restr_arg) & ~mask) == 0))
+	      {
+		error ("argument %d must be a %d-bit unsigned literal",
+		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i]);
+		return CONST0_RTX (mode[0]);
+	      }
+	    break;
+	  }
+	case RES_RANGE:
+	  {
+	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
+	    STRIP_NOPS (restr_arg);
+	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
+		  && IN_RANGE (tree_to_shwi (restr_arg),
+			       bifaddr->restr_val1[i],
+			       bifaddr->restr_val2[i])))
+	      {
+		error ("argument %d must be a literal between %d and %d,"
+		       " inclusive",
+		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i],
+		       bifaddr->restr_val2[i]);
+		return CONST0_RTX (mode[0]);
+	      }
+	    break;
+	  }
+	case RES_VAR_RANGE:
+	  {
+	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
+	    STRIP_NOPS (restr_arg);
+	    if (TREE_CODE (restr_arg) == INTEGER_CST
+		&& !IN_RANGE (tree_to_shwi (restr_arg),
+			      bifaddr->restr_val1[i],
+			      bifaddr->restr_val2[i]))
+	      {
+		error ("argument %d must be a variable or a literal "
+		       "between %d and %d, inclusive",
+		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i],
+		       bifaddr->restr_val2[i]);
+		return CONST0_RTX (mode[0]);
+	      }
+	    break;
+	  }
+	case RES_VALUES:
+	  {
+	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
+	    STRIP_NOPS (restr_arg);
+	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
+		  && (tree_to_shwi (restr_arg) == bifaddr->restr_val1[i]
+		      || tree_to_shwi (restr_arg) == bifaddr->restr_val2[i])))
+	      {
+		error ("argument %d must be either a literal %d or a "
+		       "literal %d",
+		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i],
+		       bifaddr->restr_val2[i]);
+		return CONST0_RTX (mode[0]);
+	      }
+	    break;
+	  }
+	default:
+	case RES_NONE:
+	  break;
+	}
+    }
+
+  if (bif_is_ldstmask (*bifaddr))
+    return rs6000_expand_ldst_mask (target, arg[0]);
+
+  if (bif_is_stvec (*bifaddr))
+    {
+      if (bif_is_reve (*bifaddr))
+	icode = elemrev_icode (fcode);
+      return stv_expand_builtin (icode, op, mode[0], mode[1]);
+    }
+
+  if (bif_is_ldvec (*bifaddr))
+    {
+      if (bif_is_reve (*bifaddr))
+	icode = elemrev_icode (fcode);
+      return ldv_expand_builtin (target, icode, op, mode[0]);
+    }
+
+  if (bif_is_lxvrse (*bifaddr))
+    return lxvrse_expand_builtin (target, icode, op, mode[0], mode[1]);
+
+  if (bif_is_lxvrze (*bifaddr))
+    return lxvrze_expand_builtin (target, icode, op, mode[0], mode[1]);
+
+  if (bif_is_mma (*bifaddr))
+    return mma_expand_builtin (exp, target, icode, fcode);
+
+  if (fcode == RS6000_BIF_PACK_IF
+      && TARGET_LONG_DOUBLE_128
+      && !TARGET_IEEEQUAD)
+    {
+      icode = CODE_FOR_packtf;
+      fcode = RS6000_BIF_PACK_TF;
+      uns_fcode = (size_t) fcode;
+    }
+  else if (fcode == RS6000_BIF_UNPACK_IF
+	   && TARGET_LONG_DOUBLE_128
+	   && !TARGET_IEEEQUAD)
+    {
+      icode = CODE_FOR_unpacktf;
+      fcode = RS6000_BIF_UNPACK_TF;
+      uns_fcode = (size_t) fcode;
+    }
+
+  if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
+    target = NULL_RTX;
+  else if (target == 0
+	   || GET_MODE (target) != mode[0]
+	   || !insn_data[icode].operand[0].predicate (target, mode[0]))
+    target = gen_reg_rtx (mode[0]);
+
+  for (int i = 0; i < nargs; i++)
+    if (!insn_data[icode].operand[i+k].predicate (op[i], mode[i+k]))
+      op[i] = copy_to_mode_reg (mode[i+k], op[i]);
+
+  rtx pat;
+
+  switch (nargs)
+    {
+    case 0:
+      pat = (void_func
+	     ? GEN_FCN (icode) ()
+	     : GEN_FCN (icode) (target));
+      break;
+    case 1:
+      pat = (void_func
+	     ? GEN_FCN (icode) (op[0])
+	     : GEN_FCN (icode) (target, op[0]));
+      break;
+    case 2:
+      pat = (void_func
+	     ? GEN_FCN (icode) (op[0], op[1])
+	     : GEN_FCN (icode) (target, op[0], op[1]));
+      break;
+    case 3:
+      pat = (void_func
+	     ? GEN_FCN (icode) (op[0], op[1], op[2])
+	     : GEN_FCN (icode) (target, op[0], op[1], op[2]));
+      break;
+    case 4:
+      pat = (void_func
+	     ? GEN_FCN (icode) (op[0], op[1], op[2], op[3])
+	     : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]));
+      break;
+    case 5:
+      pat = (void_func
+	     ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4])
+	     : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]));
+      break;
+    case 6:
+      pat = (void_func
+	     ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5])
+	     : GEN_FCN (icode) (target, op[0], op[1],
+				op[2], op[3], op[4], op[5]));
+      break;
+    default:
+      gcc_assert (MAX_BUILTIN_ARGS == 6);
+      gcc_unreachable ();
+    }
+
+  if (!pat)
+    return 0;
+
+  emit_insn (pat);
+  return target;
+}
diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index e002e1f2b70..752f25f6527 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -89,85 +89,6 @@
 #define TARGET_NO_PROTOTYPE 0
 #endif
 
-/* Used by __builtin_cpu_is(), mapping from PLATFORM names to values.  */
-static const struct
-{
-  const char *cpu;
-  unsigned int cpuid;
-} cpu_is_info[] = {
-  { "power10",	   PPC_PLATFORM_POWER10 },
-  { "power9",	   PPC_PLATFORM_POWER9 },
-  { "power8",	   PPC_PLATFORM_POWER8 },
-  { "power7",	   PPC_PLATFORM_POWER7 },
-  { "power6x",	   PPC_PLATFORM_POWER6X },
-  { "power6",	   PPC_PLATFORM_POWER6 },
-  { "power5+",	   PPC_PLATFORM_POWER5_PLUS },
-  { "power5",	   PPC_PLATFORM_POWER5 },
-  { "ppc970",	   PPC_PLATFORM_PPC970 },
-  { "power4",	   PPC_PLATFORM_POWER4 },
-  { "ppca2",	   PPC_PLATFORM_PPCA2 },
-  { "ppc476",	   PPC_PLATFORM_PPC476 },
-  { "ppc464",	   PPC_PLATFORM_PPC464 },
-  { "ppc440",	   PPC_PLATFORM_PPC440 },
-  { "ppc405",	   PPC_PLATFORM_PPC405 },
-  { "ppc-cell-be", PPC_PLATFORM_CELL_BE }
-};
-
-/* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks.  */
-static const struct
-{
-  const char *hwcap;
-  int mask;
-  unsigned int id;
-} cpu_supports_info[] = {
-  /* AT_HWCAP masks.  */
-  { "4xxmac",		PPC_FEATURE_HAS_4xxMAC,		0 },
-  { "altivec",		PPC_FEATURE_HAS_ALTIVEC,	0 },
-  { "arch_2_05",	PPC_FEATURE_ARCH_2_05,		0 },
-  { "arch_2_06",	PPC_FEATURE_ARCH_2_06,		0 },
-  { "archpmu",		PPC_FEATURE_PERFMON_COMPAT,	0 },
-  { "booke",		PPC_FEATURE_BOOKE,		0 },
-  { "cellbe",		PPC_FEATURE_CELL_BE,		0 },
-  { "dfp",		PPC_FEATURE_HAS_DFP,		0 },
-  { "efpdouble",	PPC_FEATURE_HAS_EFP_DOUBLE,	0 },
-  { "efpsingle",	PPC_FEATURE_HAS_EFP_SINGLE,	0 },
-  { "fpu",		PPC_FEATURE_HAS_FPU,		0 },
-  { "ic_snoop",		PPC_FEATURE_ICACHE_SNOOP,	0 },
-  { "mmu",		PPC_FEATURE_HAS_MMU,		0 },
-  { "notb",		PPC_FEATURE_NO_TB,		0 },
-  { "pa6t",		PPC_FEATURE_PA6T,		0 },
-  { "power4",		PPC_FEATURE_POWER4,		0 },
-  { "power5",		PPC_FEATURE_POWER5,		0 },
-  { "power5+",		PPC_FEATURE_POWER5_PLUS,	0 },
-  { "power6x",		PPC_FEATURE_POWER6_EXT,		0 },
-  { "ppc32",		PPC_FEATURE_32,			0 },
-  { "ppc601",		PPC_FEATURE_601_INSTR,		0 },
-  { "ppc64",		PPC_FEATURE_64,			0 },
-  { "ppcle",		PPC_FEATURE_PPC_LE,		0 },
-  { "smt",		PPC_FEATURE_SMT,		0 },
-  { "spe",		PPC_FEATURE_HAS_SPE,		0 },
-  { "true_le",		PPC_FEATURE_TRUE_LE,		0 },
-  { "ucache",		PPC_FEATURE_UNIFIED_CACHE,	0 },
-  { "vsx",		PPC_FEATURE_HAS_VSX,		0 },
-
-  /* AT_HWCAP2 masks.  */
-  { "arch_2_07",	PPC_FEATURE2_ARCH_2_07,		1 },
-  { "dscr",		PPC_FEATURE2_HAS_DSCR,		1 },
-  { "ebb",		PPC_FEATURE2_HAS_EBB,		1 },
-  { "htm",		PPC_FEATURE2_HAS_HTM,		1 },
-  { "htm-nosc",		PPC_FEATURE2_HTM_NOSC,		1 },
-  { "htm-no-suspend",	PPC_FEATURE2_HTM_NO_SUSPEND,	1 },
-  { "isel",		PPC_FEATURE2_HAS_ISEL,		1 },
-  { "tar",		PPC_FEATURE2_HAS_TAR,		1 },
-  { "vcrypto",		PPC_FEATURE2_HAS_VEC_CRYPTO,	1 },
-  { "arch_3_00",	PPC_FEATURE2_ARCH_3_00,		1 },
-  { "ieee128",		PPC_FEATURE2_HAS_IEEE128,	1 },
-  { "darn",		PPC_FEATURE2_DARN,		1 },
-  { "scv",		PPC_FEATURE2_SCV,		1 },
-  { "arch_3_1",		PPC_FEATURE2_ARCH_3_1,		1 },
-  { "mma",		PPC_FEATURE2_MMA,		1 },
-};
-\f
 /* Nonzero if we can use a floating-point register to pass this arg.  */
 #define USE_FP_FOR_ARG_P(CUM,MODE)		\
   (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE)		\
@@ -2892,188 +2813,6 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
   return build_va_arg_indirect_ref (addr);
 }
 
-/* Debug utility to translate a type node to a single textual token.  */
-static
-const char *rs6000_type_string (tree type_node)
-{
-  if (type_node == void_type_node)
-    return "void";
-  else if (type_node == long_integer_type_node)
-    return "long";
-  else if (type_node == long_unsigned_type_node)
-    return "ulong";
-  else if (type_node == long_long_integer_type_node)
-    return "longlong";
-  else if (type_node == long_long_unsigned_type_node)
-    return "ulonglong";
-  else if (type_node == bool_V2DI_type_node)
-    return "vbll";
-  else if (type_node == bool_V4SI_type_node)
-    return "vbi";
-  else if (type_node == bool_V8HI_type_node)
-    return "vbs";
-  else if (type_node == bool_V16QI_type_node)
-    return "vbc";
-  else if (type_node == bool_int_type_node)
-    return "bool";
-  else if (type_node == dfloat64_type_node)
-    return "_Decimal64";
-  else if (type_node == double_type_node)
-    return "double";
-  else if (type_node == intDI_type_node)
-    return "sll";
-  else if (type_node == intHI_type_node)
-    return "ss";
-  else if (type_node == ibm128_float_type_node)
-    return "__ibm128";
-  else if (type_node == opaque_V4SI_type_node)
-    return "opaque";
-  else if (POINTER_TYPE_P (type_node))
-    return "void*";
-  else if (type_node == intQI_type_node || type_node == char_type_node)
-    return "sc";
-  else if (type_node == dfloat32_type_node)
-    return "_Decimal32";
-  else if (type_node == float_type_node)
-    return "float";
-  else if (type_node == intSI_type_node || type_node == integer_type_node)
-    return "si";
-  else if (type_node == dfloat128_type_node)
-    return "_Decimal128";
-  else if (type_node == long_double_type_node)
-    return "longdouble";
-  else if (type_node == intTI_type_node)
-    return "sq";
-  else if (type_node == unsigned_intDI_type_node)
-    return "ull";
-  else if (type_node == unsigned_intHI_type_node)
-    return "us";
-  else if (type_node == unsigned_intQI_type_node)
-    return "uc";
-  else if (type_node == unsigned_intSI_type_node)
-    return "ui";
-  else if (type_node == unsigned_intTI_type_node)
-    return "uq";
-  else if (type_node == unsigned_V1TI_type_node)
-    return "vuq";
-  else if (type_node == unsigned_V2DI_type_node)
-    return "vull";
-  else if (type_node == unsigned_V4SI_type_node)
-    return "vui";
-  else if (type_node == unsigned_V8HI_type_node)
-    return "vus";
-  else if (type_node == unsigned_V16QI_type_node)
-    return "vuc";
-  else if (type_node == V16QI_type_node)
-    return "vsc";
-  else if (type_node == V1TI_type_node)
-    return "vsq";
-  else if (type_node == V2DF_type_node)
-    return "vd";
-  else if (type_node == V2DI_type_node)
-    return "vsll";
-  else if (type_node == V4SF_type_node)
-    return "vf";
-  else if (type_node == V4SI_type_node)
-    return "vsi";
-  else if (type_node == V8HI_type_node)
-    return "vss";
-  else if (type_node == pixel_V8HI_type_node)
-    return "vp";
-  else if (type_node == pcvoid_type_node)
-    return "voidc*";
-  else if (type_node == float128_type_node)
-    return "_Float128";
-  else if (type_node == vector_pair_type_node)
-    return "__vector_pair";
-  else if (type_node == vector_quad_type_node)
-    return "__vector_quad";
-
-  return "unknown";
-}
-
-static rtx
-altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
-{
-  rtx pat, scratch;
-  tree cr6_form = CALL_EXPR_ARG (exp, 0);
-  tree arg0 = CALL_EXPR_ARG (exp, 1);
-  tree arg1 = CALL_EXPR_ARG (exp, 2);
-  rtx op0 = expand_normal (arg0);
-  rtx op1 = expand_normal (arg1);
-  machine_mode tmode = SImode;
-  machine_mode mode0 = insn_data[icode].operand[1].mode;
-  machine_mode mode1 = insn_data[icode].operand[2].mode;
-  int cr6_form_int;
-
-  if (TREE_CODE (cr6_form) != INTEGER_CST)
-    {
-      error ("argument 1 of %qs must be a constant",
-	     "__builtin_altivec_predicate");
-      return const0_rtx;
-    }
-  else
-    cr6_form_int = TREE_INT_CST_LOW (cr6_form);
-
-  gcc_assert (mode0 == mode1);
-
-  /* If we have invalid arguments, bail out before generating bad rtl.  */
-  if (arg0 == error_mark_node || arg1 == error_mark_node)
-    return const0_rtx;
-
-  if (target == 0
-      || GET_MODE (target) != tmode
-      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
-    target = gen_reg_rtx (tmode);
-
-  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
-    op0 = copy_to_mode_reg (mode0, op0);
-  if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
-    op1 = copy_to_mode_reg (mode1, op1);
-
-  /* Note that for many of the relevant operations (e.g. cmpne or
-     cmpeq) with float or double operands, it makes more sense for the
-     mode of the allocated scratch register to select a vector of
-     integer.  But the choice to copy the mode of operand 0 was made
-     long ago and there are no plans to change it.  */
-  scratch = gen_reg_rtx (mode0);
-
-  pat = GEN_FCN (icode) (scratch, op0, op1);
-  if (! pat)
-    return 0;
-  emit_insn (pat);
-
-  /* The vec_any* and vec_all* predicates use the same opcodes for two
-     different operations, but the bits in CR6 will be different
-     depending on what information we want.  So we have to play tricks
-     with CR6 to get the right bits out.
-
-     If you think this is disgusting, look at the specs for the
-     AltiVec predicates.  */
-
-  switch (cr6_form_int)
-    {
-    case 0:
-      emit_insn (gen_cr6_test_for_zero (target));
-      break;
-    case 1:
-      emit_insn (gen_cr6_test_for_zero_reverse (target));
-      break;
-    case 2:
-      emit_insn (gen_cr6_test_for_lt (target));
-      break;
-    case 3:
-      emit_insn (gen_cr6_test_for_lt_reverse (target));
-      break;
-    default:
-      error ("argument 1 of %qs is out of range",
-	     "__builtin_altivec_predicate");
-      break;
-    }
-
-  return target;
-}
-
 rtx
 swap_endian_selector_for_mode (machine_mode mode)
 {
@@ -3112,3269 +2851,6 @@ swap_endian_selector_for_mode (machine_mode mode)
 						     gen_rtvec_v (16, perm)));
 }
 
-/* Return the correct ICODE value depending on whether we are
-   setting or reading the HTM SPRs.  */
-static inline enum insn_code
-rs6000_htm_spr_icode (bool nonvoid)
-{
-  if (nonvoid)
-    return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si;
-  else
-    return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si;
-}
-
-/* Expand vec_init builtin.  */
-static rtx
-altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
-{
-  machine_mode tmode = TYPE_MODE (type);
-  machine_mode inner_mode = GET_MODE_INNER (tmode);
-  int i, n_elt = GET_MODE_NUNITS (tmode);
-
-  gcc_assert (VECTOR_MODE_P (tmode));
-  gcc_assert (n_elt == call_expr_nargs (exp));
-
-  if (!target || !register_operand (target, tmode))
-    target = gen_reg_rtx (tmode);
-
-  /* If we have a vector compromised of a single element, such as V1TImode, do
-     the initialization directly.  */
-  if (n_elt == 1 && GET_MODE_SIZE (tmode) == GET_MODE_SIZE (inner_mode))
-    {
-      rtx x = expand_normal (CALL_EXPR_ARG (exp, 0));
-      emit_move_insn (target, gen_lowpart (tmode, x));
-    }
-  else
-    {
-      rtvec v = rtvec_alloc (n_elt);
-
-      for (i = 0; i < n_elt; ++i)
-	{
-	  rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
-	  RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
-	}
-
-      rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
-    }
-
-  return target;
-}
-
-/* Return the integer constant in ARG.  Constrain it to be in the range
-   of the subparts of VEC_TYPE; issue an error if not.  */
-
-static int
-get_element_number (tree vec_type, tree arg)
-{
-  unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
-
-  if (!tree_fits_uhwi_p (arg)
-      || (elt = tree_to_uhwi (arg), elt > max))
-    {
-      error ("selector must be an integer constant in the range [0, %wi]", max);
-      return 0;
-    }
-
-  return elt;
-}
-
-/* Expand vec_set builtin.  */
-static rtx
-altivec_expand_vec_set_builtin (tree exp)
-{
-  machine_mode tmode, mode1;
-  tree arg0, arg1, arg2;
-  int elt;
-  rtx op0, op1;
-
-  arg0 = CALL_EXPR_ARG (exp, 0);
-  arg1 = CALL_EXPR_ARG (exp, 1);
-  arg2 = CALL_EXPR_ARG (exp, 2);
-
-  tmode = TYPE_MODE (TREE_TYPE (arg0));
-  mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
-  gcc_assert (VECTOR_MODE_P (tmode));
-
-  op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
-  op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
-  elt = get_element_number (TREE_TYPE (arg0), arg2);
-
-  if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
-    op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
-
-  op0 = force_reg (tmode, op0);
-  op1 = force_reg (mode1, op1);
-
-  rs6000_expand_vector_set (op0, op1, GEN_INT (elt));
-
-  return op0;
-}
-
-/* Expand vec_ext builtin.  */
-static rtx
-altivec_expand_vec_ext_builtin (tree exp, rtx target)
-{
-  machine_mode tmode, mode0;
-  tree arg0, arg1;
-  rtx op0;
-  rtx op1;
-
-  arg0 = CALL_EXPR_ARG (exp, 0);
-  arg1 = CALL_EXPR_ARG (exp, 1);
-
-  op0 = expand_normal (arg0);
-  op1 = expand_normal (arg1);
-
-  if (TREE_CODE (arg1) == INTEGER_CST)
-    {
-      unsigned HOST_WIDE_INT elt;
-      unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
-      unsigned int truncated_selector;
-      /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
-	 returns low-order bits of INTEGER_CST for modulo indexing.  */
-      elt = TREE_INT_CST_LOW (arg1);
-      truncated_selector = elt % size;
-      op1 = GEN_INT (truncated_selector);
-    }
-
-  tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
-  mode0 = TYPE_MODE (TREE_TYPE (arg0));
-  gcc_assert (VECTOR_MODE_P (mode0));
-
-  op0 = force_reg (mode0, op0);
-
-  if (optimize || !target || !register_operand (target, tmode))
-    target = gen_reg_rtx (tmode);
-
-  rs6000_expand_vector_extract (target, op0, op1);
-
-  return target;
-}
-
-/* Raise an error message for a builtin function that is called without the
-   appropriate target options being set.  */
-
-void
-rs6000_invalid_builtin (enum rs6000_gen_builtins fncode)
-{
-  size_t j = (size_t) fncode;
-  const char *name = rs6000_builtin_info[j].bifname;
-
-  switch (rs6000_builtin_info[j].enable)
-    {
-    case ENB_P5:
-      error ("%qs requires the %qs option", name, "-mcpu=power5");
-      break;
-    case ENB_P6:
-      error ("%qs requires the %qs option", name, "-mcpu=power6");
-      break;
-    case ENB_P6_64:
-      error ("%qs requires the %qs option and either the %qs or %qs option",
-	     name, "-mcpu=power6", "-m64", "-mpowerpc64");
-      break;
-    case ENB_ALTIVEC:
-      error ("%qs requires the %qs option", name, "-maltivec");
-      break;
-    case ENB_CELL:
-      error ("%qs requires the %qs option", name, "-mcpu=cell");
-      break;
-    case ENB_VSX:
-      error ("%qs requires the %qs option", name, "-mvsx");
-      break;
-    case ENB_P7:
-      error ("%qs requires the %qs option", name, "-mcpu=power7");
-      break;
-    case ENB_P7_64:
-      error ("%qs requires the %qs option and either the %qs or %qs option",
-	     name, "-mcpu=power7", "-m64", "-mpowerpc64");
-      break;
-    case ENB_P8:
-      error ("%qs requires the %qs option", name, "-mcpu=power8");
-      break;
-    case ENB_P8V:
-      error ("%qs requires the %qs and %qs options", name, "-mcpu=power8",
-	     "-mvsx");
-      break;
-    case ENB_P9:
-      error ("%qs requires the %qs option", name, "-mcpu=power9");
-      break;
-    case ENB_P9_64:
-      error ("%qs requires the %qs option and either the %qs or %qs option",
-	     name, "-mcpu=power9", "-m64", "-mpowerpc64");
-      break;
-    case ENB_P9V:
-      error ("%qs requires the %qs and %qs options", name, "-mcpu=power9",
-	     "-mvsx");
-      break;
-    case ENB_IEEE128_HW:
-      error ("%qs requires quad-precision floating-point arithmetic", name);
-      break;
-    case ENB_DFP:
-      error ("%qs requires the %qs option", name, "-mhard-dfp");
-      break;
-    case ENB_CRYPTO:
-      error ("%qs requires the %qs option", name, "-mcrypto");
-      break;
-    case ENB_HTM:
-      error ("%qs requires the %qs option", name, "-mhtm");
-      break;
-    case ENB_P10:
-      error ("%qs requires the %qs option", name, "-mcpu=power10");
-      break;
-    case ENB_P10_64:
-      error ("%qs requires the %qs option and either the %qs or %qs option",
-	     name, "-mcpu=power10", "-m64", "-mpowerpc64");
-      break;
-    case ENB_MMA:
-      error ("%qs requires the %qs option", name, "-mmma");
-      break;
-    default:
-    case ENB_ALWAYS:
-      gcc_unreachable ();
-    }
-}
-
-/* Target hook for early folding of built-ins, shamelessly stolen
-   from ia64.cc.  */
-
-tree
-rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
-		     int n_args ATTRIBUTE_UNUSED,
-		     tree *args ATTRIBUTE_UNUSED,
-		     bool ignore ATTRIBUTE_UNUSED)
-{
-#ifdef SUBTARGET_FOLD_BUILTIN
-  return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
-#else
-  return NULL_TREE;
-#endif
-}
-
-/* Helper function to handle the gimple folding of a vector compare
-   operation.  This sets up true/false vectors, and uses the
-   VEC_COND_EXPR operation.
-   CODE indicates which comparison is to be made. (EQ, GT, ...).
-   TYPE indicates the type of the result.
-   Code is inserted before GSI.  */
-static tree
-fold_build_vec_cmp (tree_code code, tree type, tree arg0, tree arg1,
-		    gimple_stmt_iterator *gsi)
-{
-  tree cmp_type = truth_type_for (type);
-  tree zero_vec = build_zero_cst (type);
-  tree minus_one_vec = build_minus_one_cst (type);
-  tree temp = create_tmp_reg_or_ssa_name (cmp_type);
-  gimple *g = gimple_build_assign (temp, code, arg0, arg1);
-  gsi_insert_before (gsi, g, GSI_SAME_STMT);
-  return fold_build3 (VEC_COND_EXPR, type, temp, minus_one_vec, zero_vec);
-}
-
-/* Helper function to handle the in-between steps for the
-   vector compare built-ins.  */
-static void
-fold_compare_helper (gimple_stmt_iterator *gsi, tree_code code, gimple *stmt)
-{
-  tree arg0 = gimple_call_arg (stmt, 0);
-  tree arg1 = gimple_call_arg (stmt, 1);
-  tree lhs = gimple_call_lhs (stmt);
-  tree cmp = fold_build_vec_cmp (code, TREE_TYPE (lhs), arg0, arg1, gsi);
-  gimple *g = gimple_build_assign (lhs, cmp);
-  gimple_set_location (g, gimple_location (stmt));
-  gsi_replace (gsi, g, true);
-}
-
-/* Helper function to map V2DF and V4SF types to their
- integral equivalents (V2DI and V4SI).  */
-tree map_to_integral_tree_type (tree input_tree_type)
-{
-  if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type)))
-    return input_tree_type;
-  else
-    {
-      if (types_compatible_p (TREE_TYPE (input_tree_type),
-			      TREE_TYPE (V2DF_type_node)))
-	return V2DI_type_node;
-      else if (types_compatible_p (TREE_TYPE (input_tree_type),
-				   TREE_TYPE (V4SF_type_node)))
-	return V4SI_type_node;
-      else
-	gcc_unreachable ();
-    }
-}
-
-/* Helper function to handle the vector merge[hl] built-ins.  The
-   implementation difference between h and l versions for this code are in
-   the values used when building of the permute vector for high word versus
-   low word merge.  The variance is keyed off the use_high parameter.  */
-static void
-fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high)
-{
-  tree arg0 = gimple_call_arg (stmt, 0);
-  tree arg1 = gimple_call_arg (stmt, 1);
-  tree lhs = gimple_call_lhs (stmt);
-  tree lhs_type = TREE_TYPE (lhs);
-  int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
-  int midpoint = n_elts / 2;
-  int offset = 0;
-
-  if (use_high == 1)
-    offset = midpoint;
-
-  /* The permute_type will match the lhs for integral types.  For double and
-     float types, the permute type needs to map to the V2 or V4 type that
-     matches size.  */
-  tree permute_type;
-  permute_type = map_to_integral_tree_type (lhs_type);
-  tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
-
-  for (int i = 0; i < midpoint; i++)
-    {
-      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
-				     offset + i));
-      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
-				     offset + n_elts + i));
-    }
-
-  tree permute = elts.build ();
-
-  gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
-  gimple_set_location (g, gimple_location (stmt));
-  gsi_replace (gsi, g, true);
-}
-
-/* Helper function to handle the vector merge[eo] built-ins.  */
-static void
-fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_odd)
-{
-  tree arg0 = gimple_call_arg (stmt, 0);
-  tree arg1 = gimple_call_arg (stmt, 1);
-  tree lhs = gimple_call_lhs (stmt);
-  tree lhs_type = TREE_TYPE (lhs);
-  int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
-
-  /* The permute_type will match the lhs for integral types.  For double and
-     float types, the permute type needs to map to the V2 or V4 type that
-     matches size.  */
-  tree permute_type;
-  permute_type = map_to_integral_tree_type (lhs_type);
-
-  tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
-
- /* Build the permute vector.  */
-  for (int i = 0; i < n_elts / 2; i++)
-    {
-      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
-				     2*i + use_odd));
-      elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
-				     2*i + use_odd + n_elts));
-    }
-
-  tree permute = elts.build ();
-
-  gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
-  gimple_set_location (g, gimple_location (stmt));
-  gsi_replace (gsi, g, true);
-}
-
-/*  Helper function to sort out which built-ins may be valid without having
-    a LHS.  */
-static bool
-rs6000_builtin_valid_without_lhs (enum rs6000_gen_builtins fn_code,
-				  tree fndecl)
-{
-  if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
-    return true;
-
-  switch (fn_code)
-    {
-    case RS6000_BIF_STVX_V16QI:
-    case RS6000_BIF_STVX_V8HI:
-    case RS6000_BIF_STVX_V4SI:
-    case RS6000_BIF_STVX_V4SF:
-    case RS6000_BIF_STVX_V2DI:
-    case RS6000_BIF_STVX_V2DF:
-    case RS6000_BIF_STXVW4X_V16QI:
-    case RS6000_BIF_STXVW4X_V8HI:
-    case RS6000_BIF_STXVW4X_V4SF:
-    case RS6000_BIF_STXVW4X_V4SI:
-    case RS6000_BIF_STXVD2X_V2DF:
-    case RS6000_BIF_STXVD2X_V2DI:
-      return true;
-    default:
-      return false;
-    }
-}
-
-/* Check whether a builtin function is supported in this target
-   configuration.  */
-bool
-rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
-{
-  switch (rs6000_builtin_info[(size_t) fncode].enable)
-    {
-    case ENB_ALWAYS:
-      return true;
-    case ENB_P5:
-      return TARGET_POPCNTB;
-    case ENB_P6:
-      return TARGET_CMPB;
-    case ENB_P6_64:
-      return TARGET_CMPB && TARGET_POWERPC64;
-    case ENB_P7:
-      return TARGET_POPCNTD;
-    case ENB_P7_64:
-      return TARGET_POPCNTD && TARGET_POWERPC64;
-    case ENB_P8:
-      return TARGET_DIRECT_MOVE;
-    case ENB_P8V:
-      return TARGET_P8_VECTOR;
-    case ENB_P9:
-      return TARGET_MODULO;
-    case ENB_P9_64:
-      return TARGET_MODULO && TARGET_POWERPC64;
-    case ENB_P9V:
-      return TARGET_P9_VECTOR;
-    case ENB_P10:
-      return TARGET_POWER10;
-    case ENB_P10_64:
-      return TARGET_POWER10 && TARGET_POWERPC64;
-    case ENB_ALTIVEC:
-      return TARGET_ALTIVEC;
-    case ENB_VSX:
-      return TARGET_VSX;
-    case ENB_CELL:
-      return TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL;
-    case ENB_IEEE128_HW:
-      return TARGET_FLOAT128_HW;
-    case ENB_DFP:
-      return TARGET_DFP;
-    case ENB_CRYPTO:
-      return TARGET_CRYPTO;
-    case ENB_HTM:
-      return TARGET_HTM;
-    case ENB_MMA:
-      return TARGET_MMA;
-    default:
-      gcc_unreachable ();
-    }
-  gcc_unreachable ();
-}
-
-/* Expand the MMA built-ins early, so that we can convert the pass-by-reference
-   __vector_quad arguments into pass-by-value arguments, leading to more
-   efficient code generation.  */
-static bool
-rs6000_gimple_fold_mma_builtin (gimple_stmt_iterator *gsi,
-				rs6000_gen_builtins fn_code)
-{
-  gimple *stmt = gsi_stmt (*gsi);
-  size_t fncode = (size_t) fn_code;
-
-  if (!bif_is_mma (rs6000_builtin_info[fncode]))
-    return false;
-
-  /* Each call that can be gimple-expanded has an associated built-in
-     function that it will expand into.  If this one doesn't, we have
-     already expanded it!  Exceptions: lxvp and stxvp.  */
-  if (rs6000_builtin_info[fncode].assoc_bif == RS6000_BIF_NONE
-      && fncode != RS6000_BIF_LXVP
-      && fncode != RS6000_BIF_STXVP)
-    return false;
-
-  bifdata *bd = &rs6000_builtin_info[fncode];
-  unsigned nopnds = bd->nargs;
-  gimple_seq new_seq = NULL;
-  gimple *new_call;
-  tree new_decl;
-
-  /* Compatibility built-ins; we used to call these
-     __builtin_mma_{dis,}assemble_pair, but now we call them
-     __builtin_vsx_{dis,}assemble_pair.  Handle the old versions.  */
-  if (fncode == RS6000_BIF_ASSEMBLE_PAIR)
-    fncode = RS6000_BIF_ASSEMBLE_PAIR_V;
-  else if (fncode == RS6000_BIF_DISASSEMBLE_PAIR)
-    fncode = RS6000_BIF_DISASSEMBLE_PAIR_V;
-
-  if (fncode == RS6000_BIF_DISASSEMBLE_ACC
-      || fncode == RS6000_BIF_DISASSEMBLE_PAIR_V)
-    {
-      /* This is an MMA disassemble built-in function.  */
-      push_gimplify_context (true);
-      unsigned nvec = (fncode == RS6000_BIF_DISASSEMBLE_ACC) ? 4 : 2;
-      tree dst_ptr = gimple_call_arg (stmt, 0);
-      tree src_ptr = gimple_call_arg (stmt, 1);
-      tree src_type = TREE_TYPE (src_ptr);
-      tree src = create_tmp_reg_or_ssa_name (TREE_TYPE (src_type));
-      gimplify_assign (src, build_simple_mem_ref (src_ptr), &new_seq);
-
-      /* If we are not disassembling an accumulator/pair or our destination is
-	 another accumulator/pair, then just copy the entire thing as is.  */
-      if ((fncode == RS6000_BIF_DISASSEMBLE_ACC
-	   && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_quad_type_node)
-	  || (fncode == RS6000_BIF_DISASSEMBLE_PAIR_V
-	      && TREE_TYPE (TREE_TYPE (dst_ptr)) == vector_pair_type_node))
-	{
-	  tree dst = build_simple_mem_ref (build1 (VIEW_CONVERT_EXPR,
-						   src_type, dst_ptr));
-	  gimplify_assign (dst, src, &new_seq);
-	  pop_gimplify_context (NULL);
-	  gsi_replace_with_seq (gsi, new_seq, true);
-	  return true;
-	}
-
-      /* If we're disassembling an accumulator into a different type, we need
-	 to emit a xxmfacc instruction now, since we cannot do it later.  */
-      if (fncode == RS6000_BIF_DISASSEMBLE_ACC)
-	{
-	  new_decl = rs6000_builtin_decls[RS6000_BIF_XXMFACC_INTERNAL];
-	  new_call = gimple_build_call (new_decl, 1, src);
-	  src = create_tmp_reg_or_ssa_name (vector_quad_type_node);
-	  gimple_call_set_lhs (new_call, src);
-	  gimple_seq_add_stmt (&new_seq, new_call);
-	}
-
-      /* Copy the accumulator/pair vector by vector.  */
-      new_decl
-	= rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif];
-      tree dst_type = build_pointer_type_for_mode (unsigned_V16QI_type_node,
-						   ptr_mode, true);
-      tree dst_base = build1 (VIEW_CONVERT_EXPR, dst_type, dst_ptr);
-      for (unsigned i = 0; i < nvec; i++)
-	{
-	  unsigned index = WORDS_BIG_ENDIAN ? i : nvec - 1 - i;
-	  tree dst = build2 (MEM_REF, unsigned_V16QI_type_node, dst_base,
-			     build_int_cst (dst_type, index * 16));
-	  tree dstssa = create_tmp_reg_or_ssa_name (unsigned_V16QI_type_node);
-	  new_call = gimple_build_call (new_decl, 2, src,
-					build_int_cstu (uint16_type_node, i));
-	  gimple_call_set_lhs (new_call, dstssa);
-	  gimple_seq_add_stmt (&new_seq, new_call);
-	  gimplify_assign (dst, dstssa, &new_seq);
-	}
-      pop_gimplify_context (NULL);
-      gsi_replace_with_seq (gsi, new_seq, true);
-      return true;
-    }
-
-  /* TODO: Do some factoring on these two chunks.  */
-  if (fncode == RS6000_BIF_LXVP)
-    {
-      push_gimplify_context (true);
-      tree offset = gimple_call_arg (stmt, 0);
-      tree ptr = gimple_call_arg (stmt, 1);
-      tree lhs = gimple_call_lhs (stmt);
-      if (TREE_TYPE (TREE_TYPE (ptr)) != vector_pair_type_node)
-	ptr = build1 (VIEW_CONVERT_EXPR,
-		      build_pointer_type (vector_pair_type_node), ptr);
-      tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR,
-					       TREE_TYPE (ptr), ptr, offset));
-      gimplify_assign (lhs, mem, &new_seq);
-      pop_gimplify_context (NULL);
-      gsi_replace_with_seq (gsi, new_seq, true);
-      return true;
-    }
-
-  if (fncode == RS6000_BIF_STXVP)
-    {
-      push_gimplify_context (true);
-      tree src = gimple_call_arg (stmt, 0);
-      tree offset = gimple_call_arg (stmt, 1);
-      tree ptr = gimple_call_arg (stmt, 2);
-      if (TREE_TYPE (TREE_TYPE (ptr)) != vector_pair_type_node)
-	ptr = build1 (VIEW_CONVERT_EXPR,
-		      build_pointer_type (vector_pair_type_node), ptr);
-      tree mem = build_simple_mem_ref (build2 (POINTER_PLUS_EXPR,
-					       TREE_TYPE (ptr), ptr, offset));
-      gimplify_assign (mem, src, &new_seq);
-      pop_gimplify_context (NULL);
-      gsi_replace_with_seq (gsi, new_seq, true);
-      return true;
-    }
-
-  /* Convert this built-in into an internal version that uses pass-by-value
-     arguments.  The internal built-in is found in the assoc_bif field.  */
-  new_decl = rs6000_builtin_decls[rs6000_builtin_info[fncode].assoc_bif];
-  tree lhs, op[MAX_MMA_OPERANDS];
-  tree acc = gimple_call_arg (stmt, 0);
-  push_gimplify_context (true);
-
-  if (bif_is_quad (*bd))
-    {
-      /* This built-in has a pass-by-reference accumulator input, so load it
-	 into a temporary accumulator for use as a pass-by-value input.  */
-      op[0] = create_tmp_reg_or_ssa_name (vector_quad_type_node);
-      for (unsigned i = 1; i < nopnds; i++)
-	op[i] = gimple_call_arg (stmt, i);
-      gimplify_assign (op[0], build_simple_mem_ref (acc), &new_seq);
-    }
-  else
-    {
-      /* This built-in does not use its pass-by-reference accumulator argument
-	 as an input argument, so remove it from the input list.  */
-      nopnds--;
-      for (unsigned i = 0; i < nopnds; i++)
-	op[i] = gimple_call_arg (stmt, i + 1);
-    }
-
-  switch (nopnds)
-    {
-    case 0:
-      new_call = gimple_build_call (new_decl, 0);
-      break;
-    case 1:
-      new_call = gimple_build_call (new_decl, 1, op[0]);
-      break;
-    case 2:
-      new_call = gimple_build_call (new_decl, 2, op[0], op[1]);
-      break;
-    case 3:
-      new_call = gimple_build_call (new_decl, 3, op[0], op[1], op[2]);
-      break;
-    case 4:
-      new_call = gimple_build_call (new_decl, 4, op[0], op[1], op[2], op[3]);
-      break;
-    case 5:
-      new_call = gimple_build_call (new_decl, 5, op[0], op[1], op[2], op[3],
-				    op[4]);
-      break;
-    case 6:
-      new_call = gimple_build_call (new_decl, 6, op[0], op[1], op[2], op[3],
-				    op[4], op[5]);
-      break;
-    case 7:
-      new_call = gimple_build_call (new_decl, 7, op[0], op[1], op[2], op[3],
-				    op[4], op[5], op[6]);
-      break;
-    default:
-      gcc_unreachable ();
-    }
-
-  if (fncode == RS6000_BIF_BUILD_PAIR || fncode == RS6000_BIF_ASSEMBLE_PAIR_V)
-    lhs = create_tmp_reg_or_ssa_name (vector_pair_type_node);
-  else
-    lhs = create_tmp_reg_or_ssa_name (vector_quad_type_node);
-  gimple_call_set_lhs (new_call, lhs);
-  gimple_seq_add_stmt (&new_seq, new_call);
-  gimplify_assign (build_simple_mem_ref (acc), lhs, &new_seq);
-  pop_gimplify_context (NULL);
-  gsi_replace_with_seq (gsi, new_seq, true);
-
-  return true;
-}
-
-/* Fold a machine-dependent built-in in GIMPLE.  (For folding into
-   a constant, use rs6000_fold_builtin.)  */
-bool
-rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
-{
-  gimple *stmt = gsi_stmt (*gsi);
-  tree fndecl = gimple_call_fndecl (stmt);
-  gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
-  enum rs6000_gen_builtins fn_code
-    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
-  tree arg0, arg1, lhs, temp;
-  enum tree_code bcode;
-  gimple *g;
-
-  size_t uns_fncode = (size_t) fn_code;
-  enum insn_code icode = rs6000_builtin_info[uns_fncode].icode;
-  const char *fn_name1 = rs6000_builtin_info[uns_fncode].bifname;
-  const char *fn_name2 = (icode != CODE_FOR_nothing)
-			  ? get_insn_name ((int) icode)
-			  : "nothing";
-
-  if (TARGET_DEBUG_BUILTIN)
-      fprintf (stderr, "rs6000_gimple_fold_builtin %d %s %s\n",
-	       fn_code, fn_name1, fn_name2);
-
-  if (!rs6000_fold_gimple)
-    return false;
-
-  /* Prevent gimple folding for code that does not have a LHS, unless it is
-     allowed per the rs6000_builtin_valid_without_lhs helper function.  */
-  if (!gimple_call_lhs (stmt)
-      && !rs6000_builtin_valid_without_lhs (fn_code, fndecl))
-    return false;
-
-  /* Don't fold invalid builtins, let rs6000_expand_builtin diagnose it.  */
-  if (!rs6000_builtin_is_supported (fn_code))
-    return false;
-
-  if (rs6000_gimple_fold_mma_builtin (gsi, fn_code))
-    return true;
-
-  switch (fn_code)
-    {
-    /* Flavors of vec_add.  We deliberately don't expand
-       RS6000_BIF_VADDUQM as it gets lowered from V1TImode to
-       TImode, resulting in much poorer code generation.  */
-    case RS6000_BIF_VADDUBM:
-    case RS6000_BIF_VADDUHM:
-    case RS6000_BIF_VADDUWM:
-    case RS6000_BIF_VADDUDM:
-    case RS6000_BIF_VADDFP:
-    case RS6000_BIF_XVADDDP:
-    case RS6000_BIF_XVADDSP:
-      bcode = PLUS_EXPR;
-    do_binary:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
-	  && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
-	{
-	  /* Ensure the binary operation is performed in a type
-	     that wraps if it is integral type.  */
-	  gimple_seq stmts = NULL;
-	  tree type = unsigned_type_for (TREE_TYPE (lhs));
-	  tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
-				     type, arg0);
-	  tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
-				     type, arg1);
-	  tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
-				   type, uarg0, uarg1);
-	  gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	  g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
-				   build1 (VIEW_CONVERT_EXPR,
-					   TREE_TYPE (lhs), res));
-	  gsi_replace (gsi, g, true);
-	  return true;
-	}
-      g = gimple_build_assign (lhs, bcode, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_sub.  We deliberately don't expand
-       RS6000_BIF_VSUBUQM. */
-    case RS6000_BIF_VSUBUBM:
-    case RS6000_BIF_VSUBUHM:
-    case RS6000_BIF_VSUBUWM:
-    case RS6000_BIF_VSUBUDM:
-    case RS6000_BIF_VSUBFP:
-    case RS6000_BIF_XVSUBDP:
-    case RS6000_BIF_XVSUBSP:
-      bcode = MINUS_EXPR;
-      goto do_binary;
-    case RS6000_BIF_XVMULSP:
-    case RS6000_BIF_XVMULDP:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, MULT_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Even element flavors of vec_mul (signed). */
-    case RS6000_BIF_VMULESB:
-    case RS6000_BIF_VMULESH:
-    case RS6000_BIF_VMULESW:
-    /* Even element flavors of vec_mul (unsigned).  */
-    case RS6000_BIF_VMULEUB:
-    case RS6000_BIF_VMULEUH:
-    case RS6000_BIF_VMULEUW:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, VEC_WIDEN_MULT_EVEN_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Odd element flavors of vec_mul (signed).  */
-    case RS6000_BIF_VMULOSB:
-    case RS6000_BIF_VMULOSH:
-    case RS6000_BIF_VMULOSW:
-    /* Odd element flavors of vec_mul (unsigned). */
-    case RS6000_BIF_VMULOUB:
-    case RS6000_BIF_VMULOUH:
-    case RS6000_BIF_VMULOUW:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, VEC_WIDEN_MULT_ODD_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_div (Integer).  */
-    case RS6000_BIF_DIV_V2DI:
-    case RS6000_BIF_UDIV_V2DI:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, TRUNC_DIV_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_div (Float).  */
-    case RS6000_BIF_XVDIVSP:
-    case RS6000_BIF_XVDIVDP:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, RDIV_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_and.  */
-    case RS6000_BIF_VAND_V16QI_UNS:
-    case RS6000_BIF_VAND_V16QI:
-    case RS6000_BIF_VAND_V8HI_UNS:
-    case RS6000_BIF_VAND_V8HI:
-    case RS6000_BIF_VAND_V4SI_UNS:
-    case RS6000_BIF_VAND_V4SI:
-    case RS6000_BIF_VAND_V2DI_UNS:
-    case RS6000_BIF_VAND_V2DI:
-    case RS6000_BIF_VAND_V4SF:
-    case RS6000_BIF_VAND_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_andc.  */
-    case RS6000_BIF_VANDC_V16QI_UNS:
-    case RS6000_BIF_VANDC_V16QI:
-    case RS6000_BIF_VANDC_V8HI_UNS:
-    case RS6000_BIF_VANDC_V8HI:
-    case RS6000_BIF_VANDC_V4SI_UNS:
-    case RS6000_BIF_VANDC_V4SI:
-    case RS6000_BIF_VANDC_V2DI_UNS:
-    case RS6000_BIF_VANDC_V2DI:
-    case RS6000_BIF_VANDC_V4SF:
-    case RS6000_BIF_VANDC_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
-      g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_insert_before (gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, temp);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_nand.  */
-    case RS6000_BIF_NAND_V16QI_UNS:
-    case RS6000_BIF_NAND_V16QI:
-    case RS6000_BIF_NAND_V8HI_UNS:
-    case RS6000_BIF_NAND_V8HI:
-    case RS6000_BIF_NAND_V4SI_UNS:
-    case RS6000_BIF_NAND_V4SI:
-    case RS6000_BIF_NAND_V2DI_UNS:
-    case RS6000_BIF_NAND_V2DI:
-    case RS6000_BIF_NAND_V4SF:
-    case RS6000_BIF_NAND_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
-      g = gimple_build_assign (temp, BIT_AND_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_insert_before (gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_or.  */
-    case RS6000_BIF_VOR_V16QI_UNS:
-    case RS6000_BIF_VOR_V16QI:
-    case RS6000_BIF_VOR_V8HI_UNS:
-    case RS6000_BIF_VOR_V8HI:
-    case RS6000_BIF_VOR_V4SI_UNS:
-    case RS6000_BIF_VOR_V4SI:
-    case RS6000_BIF_VOR_V2DI_UNS:
-    case RS6000_BIF_VOR_V2DI:
-    case RS6000_BIF_VOR_V4SF:
-    case RS6000_BIF_VOR_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* flavors of vec_orc.  */
-    case RS6000_BIF_ORC_V16QI_UNS:
-    case RS6000_BIF_ORC_V16QI:
-    case RS6000_BIF_ORC_V8HI_UNS:
-    case RS6000_BIF_ORC_V8HI:
-    case RS6000_BIF_ORC_V4SI_UNS:
-    case RS6000_BIF_ORC_V4SI:
-    case RS6000_BIF_ORC_V2DI_UNS:
-    case RS6000_BIF_ORC_V2DI:
-    case RS6000_BIF_ORC_V4SF:
-    case RS6000_BIF_ORC_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
-      g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_insert_before (gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, temp);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_xor.  */
-    case RS6000_BIF_VXOR_V16QI_UNS:
-    case RS6000_BIF_VXOR_V16QI:
-    case RS6000_BIF_VXOR_V8HI_UNS:
-    case RS6000_BIF_VXOR_V8HI:
-    case RS6000_BIF_VXOR_V4SI_UNS:
-    case RS6000_BIF_VXOR_V4SI:
-    case RS6000_BIF_VXOR_V2DI_UNS:
-    case RS6000_BIF_VXOR_V2DI:
-    case RS6000_BIF_VXOR_V4SF:
-    case RS6000_BIF_VXOR_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, BIT_XOR_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_nor.  */
-    case RS6000_BIF_VNOR_V16QI_UNS:
-    case RS6000_BIF_VNOR_V16QI:
-    case RS6000_BIF_VNOR_V8HI_UNS:
-    case RS6000_BIF_VNOR_V8HI:
-    case RS6000_BIF_VNOR_V4SI_UNS:
-    case RS6000_BIF_VNOR_V4SI:
-    case RS6000_BIF_VNOR_V2DI_UNS:
-    case RS6000_BIF_VNOR_V2DI:
-    case RS6000_BIF_VNOR_V4SF:
-    case RS6000_BIF_VNOR_V2DF:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
-      g = gimple_build_assign (temp, BIT_IOR_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_insert_before (gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* flavors of vec_abs.  */
-    case RS6000_BIF_ABS_V16QI:
-    case RS6000_BIF_ABS_V8HI:
-    case RS6000_BIF_ABS_V4SI:
-    case RS6000_BIF_ABS_V4SF:
-    case RS6000_BIF_ABS_V2DI:
-    case RS6000_BIF_XVABSDP:
-    case RS6000_BIF_XVABSSP:
-      arg0 = gimple_call_arg (stmt, 0);
-      if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))
-	  && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (arg0))))
-	return false;
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, ABS_EXPR, arg0);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* flavors of vec_min.  */
-    case RS6000_BIF_XVMINDP:
-    case RS6000_BIF_XVMINSP:
-    case RS6000_BIF_VMINFP:
-      {
-	lhs = gimple_call_lhs (stmt);
-	tree type = TREE_TYPE (lhs);
-	if (HONOR_NANS (type))
-	  return false;
-	gcc_fallthrough ();
-      }
-    case RS6000_BIF_VMINSD:
-    case RS6000_BIF_VMINUD:
-    case RS6000_BIF_VMINSB:
-    case RS6000_BIF_VMINSH:
-    case RS6000_BIF_VMINSW:
-    case RS6000_BIF_VMINUB:
-    case RS6000_BIF_VMINUH:
-    case RS6000_BIF_VMINUW:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, MIN_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* flavors of vec_max.  */
-    case RS6000_BIF_XVMAXDP:
-    case RS6000_BIF_XVMAXSP:
-    case RS6000_BIF_VMAXFP:
-      {
-	lhs = gimple_call_lhs (stmt);
-	tree type = TREE_TYPE (lhs);
-	if (HONOR_NANS (type))
-	  return false;
-	gcc_fallthrough ();
-      }
-    case RS6000_BIF_VMAXSD:
-    case RS6000_BIF_VMAXUD:
-    case RS6000_BIF_VMAXSB:
-    case RS6000_BIF_VMAXSH:
-    case RS6000_BIF_VMAXSW:
-    case RS6000_BIF_VMAXUB:
-    case RS6000_BIF_VMAXUH:
-    case RS6000_BIF_VMAXUW:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, MAX_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_eqv.  */
-    case RS6000_BIF_EQV_V16QI:
-    case RS6000_BIF_EQV_V8HI:
-    case RS6000_BIF_EQV_V4SI:
-    case RS6000_BIF_EQV_V4SF:
-    case RS6000_BIF_EQV_V2DF:
-    case RS6000_BIF_EQV_V2DI:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
-      g = gimple_build_assign (temp, BIT_XOR_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_insert_before (gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-    /* Flavors of vec_rotate_left.  */
-    case RS6000_BIF_VRLB:
-    case RS6000_BIF_VRLH:
-    case RS6000_BIF_VRLW:
-    case RS6000_BIF_VRLD:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, LROTATE_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
-  /* Flavors of vector shift right algebraic.
-     vec_sra{b,h,w} -> vsra{b,h,w}.  */
-    case RS6000_BIF_VSRAB:
-    case RS6000_BIF_VSRAH:
-    case RS6000_BIF_VSRAW:
-    case RS6000_BIF_VSRAD:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	arg1 = gimple_call_arg (stmt, 1);
-	lhs = gimple_call_lhs (stmt);
-	tree arg1_type = TREE_TYPE (arg1);
-	tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
-	tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
-	location_t loc = gimple_location (stmt);
-	/* Force arg1 into the range valid matching the arg0 type.  */
-	/* Build a vector consisting of the max valid bit-size values.  */
-	int n_elts = VECTOR_CST_NELTS (arg1);
-	tree element_size = build_int_cst (unsigned_element_type,
-					   128 / n_elts);
-	tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
-	for (int i = 0; i < n_elts; i++)
-	  elts.safe_push (element_size);
-	tree modulo_tree = elts.build ();
-	/* Modulo the provided shift value against that vector.  */
-	gimple_seq stmts = NULL;
-	tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
-					   unsigned_arg1_type, arg1);
-	tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
-				      unsigned_arg1_type, unsigned_arg1,
-				      modulo_tree);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	/* And finally, do the shift.  */
-	g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, new_arg1);
-	gimple_set_location (g, loc);
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-   /* Flavors of vector shift left.
-      builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}.  */
-    case RS6000_BIF_VSLB:
-    case RS6000_BIF_VSLH:
-    case RS6000_BIF_VSLW:
-    case RS6000_BIF_VSLD:
-      {
-	location_t loc;
-	gimple_seq stmts = NULL;
-	arg0 = gimple_call_arg (stmt, 0);
-	tree arg0_type = TREE_TYPE (arg0);
-	if (INTEGRAL_TYPE_P (TREE_TYPE (arg0_type))
-	    && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0_type)))
-	  return false;
-	arg1 = gimple_call_arg (stmt, 1);
-	tree arg1_type = TREE_TYPE (arg1);
-	tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
-	tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
-	loc = gimple_location (stmt);
-	lhs = gimple_call_lhs (stmt);
-	/* Force arg1 into the range valid matching the arg0 type.  */
-	/* Build a vector consisting of the max valid bit-size values.  */
-	int n_elts = VECTOR_CST_NELTS (arg1);
-	int tree_size_in_bits = TREE_INT_CST_LOW (size_in_bytes (arg1_type))
-				* BITS_PER_UNIT;
-	tree element_size = build_int_cst (unsigned_element_type,
-					   tree_size_in_bits / n_elts);
-	tree_vector_builder elts (unsigned_type_for (arg1_type), n_elts, 1);
-	for (int i = 0; i < n_elts; i++)
-	  elts.safe_push (element_size);
-	tree modulo_tree = elts.build ();
-	/* Modulo the provided shift value against that vector.  */
-	tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
-					   unsigned_arg1_type, arg1);
-	tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
-				      unsigned_arg1_type, unsigned_arg1,
-				      modulo_tree);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	/* And finally, do the shift.  */
-	g = gimple_build_assign (lhs, LSHIFT_EXPR, arg0, new_arg1);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-    /* Flavors of vector shift right.  */
-    case RS6000_BIF_VSRB:
-    case RS6000_BIF_VSRH:
-    case RS6000_BIF_VSRW:
-    case RS6000_BIF_VSRD:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	arg1 = gimple_call_arg (stmt, 1);
-	lhs = gimple_call_lhs (stmt);
-	tree arg1_type = TREE_TYPE (arg1);
-	tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
-	tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
-	location_t loc = gimple_location (stmt);
-	gimple_seq stmts = NULL;
-	/* Convert arg0 to unsigned.  */
-	tree arg0_unsigned
-	  = gimple_build (&stmts, VIEW_CONVERT_EXPR,
-			  unsigned_type_for (TREE_TYPE (arg0)), arg0);
-	/* Force arg1 into the range valid matching the arg0 type.  */
-	/* Build a vector consisting of the max valid bit-size values.  */
-	int n_elts = VECTOR_CST_NELTS (arg1);
-	tree element_size = build_int_cst (unsigned_element_type,
-					   128 / n_elts);
-	tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
-	for (int i = 0; i < n_elts; i++)
-	  elts.safe_push (element_size);
-	tree modulo_tree = elts.build ();
-	/* Modulo the provided shift value against that vector.  */
-	tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
-					   unsigned_arg1_type, arg1);
-	tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
-				      unsigned_arg1_type, unsigned_arg1,
-				      modulo_tree);
-	/* Do the shift.  */
-	tree res
-	  = gimple_build (&stmts, RSHIFT_EXPR,
-			  TREE_TYPE (arg0_unsigned), arg0_unsigned, new_arg1);
-	/* Convert result back to the lhs type.  */
-	res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	replace_call_with_value (gsi, res);
-	return true;
-      }
-    /* Vector loads.  */
-    case RS6000_BIF_LVX_V16QI:
-    case RS6000_BIF_LVX_V8HI:
-    case RS6000_BIF_LVX_V4SI:
-    case RS6000_BIF_LVX_V4SF:
-    case RS6000_BIF_LVX_V2DI:
-    case RS6000_BIF_LVX_V2DF:
-    case RS6000_BIF_LVX_V1TI:
-      {
-	arg0 = gimple_call_arg (stmt, 0);  // offset
-	arg1 = gimple_call_arg (stmt, 1);  // address
-	lhs = gimple_call_lhs (stmt);
-	location_t loc = gimple_location (stmt);
-	/* Since arg1 may be cast to a different type, just use ptr_type_node
-	   here instead of trying to enforce TBAA on pointer types.  */
-	tree arg1_type = ptr_type_node;
-	tree lhs_type = TREE_TYPE (lhs);
-	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
-	   the tree using the value from arg0.  The resulting type will match
-	   the type of arg1.  */
-	gimple_seq stmts = NULL;
-	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
-	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
-				       arg1_type, arg1, temp_offset);
-	/* Mask off any lower bits from the address.  */
-	tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
-					  arg1_type, temp_addr,
-					  build_int_cst (arg1_type, -16));
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	if (!is_gimple_mem_ref_addr (aligned_addr))
-	  {
-	    tree t = make_ssa_name (TREE_TYPE (aligned_addr));
-	    gimple *g = gimple_build_assign (t, aligned_addr);
-	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
-	    aligned_addr = t;
-	  }
-	/* Use the build2 helper to set up the mem_ref.  The MEM_REF could also
-	   take an offset, but since we've already incorporated the offset
-	   above, here we just pass in a zero.  */
-	gimple *g
-	  = gimple_build_assign (lhs, build2 (MEM_REF, lhs_type, aligned_addr,
-					      build_int_cst (arg1_type, 0)));
-	gimple_set_location (g, loc);
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-    /* Vector stores.  */
-    case RS6000_BIF_STVX_V16QI:
-    case RS6000_BIF_STVX_V8HI:
-    case RS6000_BIF_STVX_V4SI:
-    case RS6000_BIF_STVX_V4SF:
-    case RS6000_BIF_STVX_V2DI:
-    case RS6000_BIF_STVX_V2DF:
-      {
-	arg0 = gimple_call_arg (stmt, 0); /* Value to be stored.  */
-	arg1 = gimple_call_arg (stmt, 1); /* Offset.  */
-	tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address.  */
-	location_t loc = gimple_location (stmt);
-	tree arg0_type = TREE_TYPE (arg0);
-	/* Use ptr_type_node (no TBAA) for the arg2_type.
-	   FIXME: (Richard)  "A proper fix would be to transition this type as
-	   seen from the frontend to GIMPLE, for example in a similar way we
-	   do for MEM_REFs by piggy-backing that on an extra argument, a
-	   constant zero pointer of the alias pointer type to use (which would
-	   also serve as a type indicator of the store itself).  I'd use a
-	   target specific internal function for this (not sure if we can have
-	   those target specific, but I guess if it's folded away then that's
-	   fine) and get away with the overload set."  */
-	tree arg2_type = ptr_type_node;
-	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
-	   the tree using the value from arg0.  The resulting type will match
-	   the type of arg2.  */
-	gimple_seq stmts = NULL;
-	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
-	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
-				       arg2_type, arg2, temp_offset);
-	/* Mask off any lower bits from the address.  */
-	tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
-					  arg2_type, temp_addr,
-					  build_int_cst (arg2_type, -16));
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	if (!is_gimple_mem_ref_addr (aligned_addr))
-	  {
-	    tree t = make_ssa_name (TREE_TYPE (aligned_addr));
-	    gimple *g = gimple_build_assign (t, aligned_addr);
-	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
-	    aligned_addr = t;
-	  }
-	/* The desired gimple result should be similar to:
-	   MEM[(__vector floatD.1407 *)_1] = vf1D.2697;  */
-	gimple *g
-	  = gimple_build_assign (build2 (MEM_REF, arg0_type, aligned_addr,
-					 build_int_cst (arg2_type, 0)), arg0);
-	gimple_set_location (g, loc);
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* unaligned Vector loads.  */
-    case RS6000_BIF_LXVW4X_V16QI:
-    case RS6000_BIF_LXVW4X_V8HI:
-    case RS6000_BIF_LXVW4X_V4SF:
-    case RS6000_BIF_LXVW4X_V4SI:
-    case RS6000_BIF_LXVD2X_V2DF:
-    case RS6000_BIF_LXVD2X_V2DI:
-      {
-	arg0 = gimple_call_arg (stmt, 0);  // offset
-	arg1 = gimple_call_arg (stmt, 1);  // address
-	lhs = gimple_call_lhs (stmt);
-	location_t loc = gimple_location (stmt);
-	/* Since arg1 may be cast to a different type, just use ptr_type_node
-	   here instead of trying to enforce TBAA on pointer types.  */
-	tree arg1_type = ptr_type_node;
-	tree lhs_type = TREE_TYPE (lhs);
-	/* In GIMPLE the type of the MEM_REF specifies the alignment.  The
-	  required alignment (power) is 4 bytes regardless of data type.  */
-	tree align_ltype = build_aligned_type (lhs_type, 4);
-	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
-	   the tree using the value from arg0.  The resulting type will match
-	   the type of arg1.  */
-	gimple_seq stmts = NULL;
-	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
-	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
-				       arg1_type, arg1, temp_offset);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	if (!is_gimple_mem_ref_addr (temp_addr))
-	  {
-	    tree t = make_ssa_name (TREE_TYPE (temp_addr));
-	    gimple *g = gimple_build_assign (t, temp_addr);
-	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
-	    temp_addr = t;
-	  }
-	/* Use the build2 helper to set up the mem_ref.  The MEM_REF could also
-	   take an offset, but since we've already incorporated the offset
-	   above, here we just pass in a zero.  */
-	gimple *g;
-	g = gimple_build_assign (lhs, build2 (MEM_REF, align_ltype, temp_addr,
-					      build_int_cst (arg1_type, 0)));
-	gimple_set_location (g, loc);
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* unaligned Vector stores.  */
-    case RS6000_BIF_STXVW4X_V16QI:
-    case RS6000_BIF_STXVW4X_V8HI:
-    case RS6000_BIF_STXVW4X_V4SF:
-    case RS6000_BIF_STXVW4X_V4SI:
-    case RS6000_BIF_STXVD2X_V2DF:
-    case RS6000_BIF_STXVD2X_V2DI:
-      {
-	arg0 = gimple_call_arg (stmt, 0); /* Value to be stored.  */
-	arg1 = gimple_call_arg (stmt, 1); /* Offset.  */
-	tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address.  */
-	location_t loc = gimple_location (stmt);
-	tree arg0_type = TREE_TYPE (arg0);
-	/* Use ptr_type_node (no TBAA) for the arg2_type.  */
-	tree arg2_type = ptr_type_node;
-	/* In GIMPLE the type of the MEM_REF specifies the alignment.  The
-	   required alignment (power) is 4 bytes regardless of data type.  */
-	tree align_stype = build_aligned_type (arg0_type, 4);
-	/* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'.  Create
-	   the tree using the value from arg1.  */
-	gimple_seq stmts = NULL;
-	tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
-	tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
-				       arg2_type, arg2, temp_offset);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	if (!is_gimple_mem_ref_addr (temp_addr))
-	  {
-	    tree t = make_ssa_name (TREE_TYPE (temp_addr));
-	    gimple *g = gimple_build_assign (t, temp_addr);
-	    gsi_insert_before (gsi, g, GSI_SAME_STMT);
-	    temp_addr = t;
-	  }
-	gimple *g;
-	g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr,
-					 build_int_cst (arg2_type, 0)), arg0);
-	gimple_set_location (g, loc);
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* Vector Fused multiply-add (fma).  */
-    case RS6000_BIF_VMADDFP:
-    case RS6000_BIF_XVMADDDP:
-    case RS6000_BIF_XVMADDSP:
-    case RS6000_BIF_VMLADDUHM:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	arg1 = gimple_call_arg (stmt, 1);
-	tree arg2 = gimple_call_arg (stmt, 2);
-	lhs = gimple_call_lhs (stmt);
-	gcall *g = gimple_build_call_internal (IFN_FMA, 3, arg0, arg1, arg2);
-	gimple_call_set_lhs (g, lhs);
-	gimple_call_set_nothrow (g, true);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* Vector compares; EQ, NE, GE, GT, LE.  */
-    case RS6000_BIF_VCMPEQUB:
-    case RS6000_BIF_VCMPEQUH:
-    case RS6000_BIF_VCMPEQUW:
-    case RS6000_BIF_VCMPEQUD:
-    /* We deliberately omit RS6000_BIF_VCMPEQUT for now, because gimple
-       folding produces worse code for 128-bit compares.  */
-      fold_compare_helper (gsi, EQ_EXPR, stmt);
-      return true;
-
-    case RS6000_BIF_VCMPNEB:
-    case RS6000_BIF_VCMPNEH:
-    case RS6000_BIF_VCMPNEW:
-    /* We deliberately omit RS6000_BIF_VCMPNET for now, because gimple
-       folding produces worse code for 128-bit compares.  */
-      fold_compare_helper (gsi, NE_EXPR, stmt);
-      return true;
-
-    case RS6000_BIF_CMPGE_16QI:
-    case RS6000_BIF_CMPGE_U16QI:
-    case RS6000_BIF_CMPGE_8HI:
-    case RS6000_BIF_CMPGE_U8HI:
-    case RS6000_BIF_CMPGE_4SI:
-    case RS6000_BIF_CMPGE_U4SI:
-    case RS6000_BIF_CMPGE_2DI:
-    case RS6000_BIF_CMPGE_U2DI:
-    /* We deliberately omit RS6000_BIF_CMPGE_1TI and RS6000_BIF_CMPGE_U1TI
-       for now, because gimple folding produces worse code for 128-bit
-       compares.  */
-      fold_compare_helper (gsi, GE_EXPR, stmt);
-      return true;
-
-    case RS6000_BIF_VCMPGTSB:
-    case RS6000_BIF_VCMPGTUB:
-    case RS6000_BIF_VCMPGTSH:
-    case RS6000_BIF_VCMPGTUH:
-    case RS6000_BIF_VCMPGTSW:
-    case RS6000_BIF_VCMPGTUW:
-    case RS6000_BIF_VCMPGTUD:
-    case RS6000_BIF_VCMPGTSD:
-    /* We deliberately omit RS6000_BIF_VCMPGTUT and RS6000_BIF_VCMPGTST
-       for now, because gimple folding produces worse code for 128-bit
-       compares.  */
-      fold_compare_helper (gsi, GT_EXPR, stmt);
-      return true;
-
-    case RS6000_BIF_CMPLE_16QI:
-    case RS6000_BIF_CMPLE_U16QI:
-    case RS6000_BIF_CMPLE_8HI:
-    case RS6000_BIF_CMPLE_U8HI:
-    case RS6000_BIF_CMPLE_4SI:
-    case RS6000_BIF_CMPLE_U4SI:
-    case RS6000_BIF_CMPLE_2DI:
-    case RS6000_BIF_CMPLE_U2DI:
-    /* We deliberately omit RS6000_BIF_CMPLE_1TI and RS6000_BIF_CMPLE_U1TI
-       for now, because gimple folding produces worse code for 128-bit
-       compares.  */
-      fold_compare_helper (gsi, LE_EXPR, stmt);
-      return true;
-
-    /* flavors of vec_splat_[us]{8,16,32}.  */
-    case RS6000_BIF_VSPLTISB:
-    case RS6000_BIF_VSPLTISH:
-    case RS6000_BIF_VSPLTISW:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	lhs = gimple_call_lhs (stmt);
-
-	/* Only fold the vec_splat_*() if the lower bits of arg 0 is a
-	   5-bit signed constant in range -16 to +15.  */
-	if (TREE_CODE (arg0) != INTEGER_CST
-	    || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
-	  return false;
-	gimple_seq stmts = NULL;
-	location_t loc = gimple_location (stmt);
-	tree splat_value = gimple_convert (&stmts, loc,
-					   TREE_TYPE (TREE_TYPE (lhs)), arg0);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	tree splat_tree = build_vector_from_val (TREE_TYPE (lhs), splat_value);
-	g = gimple_build_assign (lhs, splat_tree);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* Flavors of vec_splat.  */
-    /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...};  */
-    case RS6000_BIF_VSPLTB:
-    case RS6000_BIF_VSPLTH:
-    case RS6000_BIF_VSPLTW:
-    case RS6000_BIF_XXSPLTD_V2DI:
-    case RS6000_BIF_XXSPLTD_V2DF:
-      {
-	arg0 = gimple_call_arg (stmt, 0); /* input vector.  */
-	arg1 = gimple_call_arg (stmt, 1); /* index into arg0.  */
-	/* Only fold the vec_splat_*() if arg1 is both a constant value and
-	   is a valid index into the arg0 vector.  */
-	unsigned int n_elts = VECTOR_CST_NELTS (arg0);
-	if (TREE_CODE (arg1) != INTEGER_CST
-	    || TREE_INT_CST_LOW (arg1) > (n_elts -1))
-	  return false;
-	lhs = gimple_call_lhs (stmt);
-	tree lhs_type = TREE_TYPE (lhs);
-	tree arg0_type = TREE_TYPE (arg0);
-	tree splat;
-	if (TREE_CODE (arg0) == VECTOR_CST)
-	  splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1));
-	else
-	  {
-	    /* Determine (in bits) the length and start location of the
-	       splat value for a call to the tree_vec_extract helper.  */
-	    int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type))
-				  * BITS_PER_UNIT / n_elts;
-	    int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size;
-	    tree len = build_int_cst (bitsizetype, splat_elem_size);
-	    tree start = build_int_cst (bitsizetype, splat_start_bit);
-	    splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0,
-				      len, start);
-	  }
-	/* And finally, build the new vector.  */
-	tree splat_tree = build_vector_from_val (lhs_type, splat);
-	g = gimple_build_assign (lhs, splat_tree);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* vec_mergel (integrals).  */
-    case RS6000_BIF_VMRGLH:
-    case RS6000_BIF_VMRGLW:
-    case RS6000_BIF_XXMRGLW_4SI:
-    case RS6000_BIF_VMRGLB:
-    case RS6000_BIF_VEC_MERGEL_V2DI:
-    case RS6000_BIF_XXMRGLW_4SF:
-    case RS6000_BIF_VEC_MERGEL_V2DF:
-      fold_mergehl_helper (gsi, stmt, 1);
-      return true;
-    /* vec_mergeh (integrals).  */
-    case RS6000_BIF_VMRGHH:
-    case RS6000_BIF_VMRGHW:
-    case RS6000_BIF_XXMRGHW_4SI:
-    case RS6000_BIF_VMRGHB:
-    case RS6000_BIF_VEC_MERGEH_V2DI:
-    case RS6000_BIF_XXMRGHW_4SF:
-    case RS6000_BIF_VEC_MERGEH_V2DF:
-      fold_mergehl_helper (gsi, stmt, 0);
-      return true;
-
-    /* Flavors of vec_mergee.  */
-    case RS6000_BIF_VMRGEW_V4SI:
-    case RS6000_BIF_VMRGEW_V2DI:
-    case RS6000_BIF_VMRGEW_V4SF:
-    case RS6000_BIF_VMRGEW_V2DF:
-      fold_mergeeo_helper (gsi, stmt, 0);
-      return true;
-    /* Flavors of vec_mergeo.  */
-    case RS6000_BIF_VMRGOW_V4SI:
-    case RS6000_BIF_VMRGOW_V2DI:
-    case RS6000_BIF_VMRGOW_V4SF:
-    case RS6000_BIF_VMRGOW_V2DF:
-      fold_mergeeo_helper (gsi, stmt, 1);
-      return true;
-
-    /* d = vec_pack (a, b) */
-    case RS6000_BIF_VPKUDUM:
-    case RS6000_BIF_VPKUHUM:
-    case RS6000_BIF_VPKUWUM:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	arg1 = gimple_call_arg (stmt, 1);
-	lhs = gimple_call_lhs (stmt);
-	gimple *g = gimple_build_assign (lhs, VEC_PACK_TRUNC_EXPR, arg0, arg1);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    /* d = vec_unpackh (a) */
-    /* Note that the UNPACK_{HI,LO}_EXPR used in the gimple_build_assign call
-       in this code is sensitive to endian-ness, and needs to be inverted to
-       handle both LE and BE targets.  */
-    case RS6000_BIF_VUPKHSB:
-    case RS6000_BIF_VUPKHSH:
-    case RS6000_BIF_VUPKHSW:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	lhs = gimple_call_lhs (stmt);
-	if (BYTES_BIG_ENDIAN)
-	  g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
-	else
-	  g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-    /* d = vec_unpackl (a) */
-    case RS6000_BIF_VUPKLSB:
-    case RS6000_BIF_VUPKLSH:
-    case RS6000_BIF_VUPKLSW:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	lhs = gimple_call_lhs (stmt);
-	if (BYTES_BIG_ENDIAN)
-	  g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
-	else
-	  g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
-	gimple_set_location (g, gimple_location (stmt));
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-    /* There is no gimple type corresponding with pixel, so just return.  */
-    case RS6000_BIF_VUPKHPX:
-    case RS6000_BIF_VUPKLPX:
-      return false;
-
-    /* vec_perm.  */
-    case RS6000_BIF_VPERM_16QI:
-    case RS6000_BIF_VPERM_8HI:
-    case RS6000_BIF_VPERM_4SI:
-    case RS6000_BIF_VPERM_2DI:
-    case RS6000_BIF_VPERM_4SF:
-    case RS6000_BIF_VPERM_2DF:
-    case RS6000_BIF_VPERM_16QI_UNS:
-    case RS6000_BIF_VPERM_8HI_UNS:
-    case RS6000_BIF_VPERM_4SI_UNS:
-    case RS6000_BIF_VPERM_2DI_UNS:
-      {
-	arg0 = gimple_call_arg (stmt, 0);
-	arg1 = gimple_call_arg (stmt, 1);
-	tree permute = gimple_call_arg (stmt, 2);
-	lhs = gimple_call_lhs (stmt);
-	location_t loc = gimple_location (stmt);
-	gimple_seq stmts = NULL;
-	// convert arg0 and arg1 to match the type of the permute
-	// for the VEC_PERM_EXPR operation.
-	tree permute_type = (TREE_TYPE (permute));
-	tree arg0_ptype = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
-					permute_type, arg0);
-	tree arg1_ptype = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
-					permute_type, arg1);
-	tree lhs_ptype = gimple_build (&stmts, loc, VEC_PERM_EXPR,
-				      permute_type, arg0_ptype, arg1_ptype,
-				      permute);
-	// Convert the result back to the desired lhs type upon completion.
-	tree temp = gimple_build (&stmts, loc, VIEW_CONVERT_EXPR,
-				  TREE_TYPE (lhs), lhs_ptype);
-	gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
-	g = gimple_build_assign (lhs, temp);
-	gimple_set_location (g, loc);
-	gsi_replace (gsi, g, true);
-	return true;
-      }
-
-    default:
-      if (TARGET_DEBUG_BUILTIN)
-	fprintf (stderr, "gimple builtin intrinsic not matched:%d %s %s\n",
-		 fn_code, fn_name1, fn_name2);
-      break;
-    }
-
-  return false;
-}
-
-/* Expand ALTIVEC_BUILTIN_MASK_FOR_LOAD.  */
-rtx
-rs6000_expand_ldst_mask (rtx target, tree arg0)
-{
-  int icode2 = BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
-				: (int) CODE_FOR_altivec_lvsl_direct;
-  machine_mode tmode = insn_data[icode2].operand[0].mode;
-  machine_mode mode = insn_data[icode2].operand[1].mode;
-
-  gcc_assert (TARGET_ALTIVEC);
-
-  gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg0)));
-  rtx op = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
-  rtx addr = memory_address (mode, op);
-  /* We need to negate the address.  */
-  op = gen_reg_rtx (GET_MODE (addr));
-  emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr)));
-  op = gen_rtx_MEM (mode, op);
-
-  if (target == 0
-      || GET_MODE (target) != tmode
-      || !insn_data[icode2].operand[0].predicate (target, tmode))
-    target = gen_reg_rtx (tmode);
-
-  rtx pat = GEN_FCN (icode2) (target, op);
-  if (!pat)
-    return 0;
-  emit_insn (pat);
-
-  return target;
-}
-
-/* Expand the CPU builtin in FCODE and store the result in TARGET.  */
-static rtx
-cpu_expand_builtin (enum rs6000_gen_builtins fcode,
-		    tree exp ATTRIBUTE_UNUSED, rtx target)
-{
-  /* __builtin_cpu_init () is a nop, so expand to nothing.  */
-  if (fcode == RS6000_BIF_CPU_INIT)
-    return const0_rtx;
-
-  if (target == 0 || GET_MODE (target) != SImode)
-    target = gen_reg_rtx (SImode);
-
-  /* TODO: Factor the #ifdef'd code into a separate function.  */
-#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
-  tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
-  /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back
-     to a STRING_CST.  */
-  if (TREE_CODE (arg) == ARRAY_REF
-      && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST
-      && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST
-      && compare_tree_int (TREE_OPERAND (arg, 1), 0) == 0)
-    arg = TREE_OPERAND (arg, 0);
-
-  if (TREE_CODE (arg) != STRING_CST)
-    {
-      error ("builtin %qs only accepts a string argument",
-	     rs6000_builtin_info[(size_t) fcode].bifname);
-      return const0_rtx;
-    }
-
-  if (fcode == RS6000_BIF_CPU_IS)
-    {
-      const char *cpu = TREE_STRING_POINTER (arg);
-      rtx cpuid = NULL_RTX;
-      for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++)
-	if (strcmp (cpu, cpu_is_info[i].cpu) == 0)
-	  {
-	    /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM.  */
-	    cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM);
-	    break;
-	  }
-      if (cpuid == NULL_RTX)
-	{
-	  /* Invalid CPU argument.  */
-	  error ("cpu %qs is an invalid argument to builtin %qs",
-		 cpu, rs6000_builtin_info[(size_t) fcode].bifname);
-	  return const0_rtx;
-	}
-
-      rtx platform = gen_reg_rtx (SImode);
-      rtx address = gen_rtx_PLUS (Pmode,
-				  gen_rtx_REG (Pmode, TLS_REGNUM),
-				  GEN_INT (TCB_PLATFORM_OFFSET));
-      rtx tcbmem = gen_const_mem (SImode, address);
-      emit_move_insn (platform, tcbmem);
-      emit_insn (gen_eqsi3 (target, platform, cpuid));
-    }
-  else if (fcode == RS6000_BIF_CPU_SUPPORTS)
-    {
-      const char *hwcap = TREE_STRING_POINTER (arg);
-      rtx mask = NULL_RTX;
-      int hwcap_offset;
-      for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++)
-	if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0)
-	  {
-	    mask = GEN_INT (cpu_supports_info[i].mask);
-	    hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id);
-	    break;
-	  }
-      if (mask == NULL_RTX)
-	{
-	  /* Invalid HWCAP argument.  */
-	  error ("%s %qs is an invalid argument to builtin %qs",
-		 "hwcap", hwcap,
-		 rs6000_builtin_info[(size_t) fcode].bifname);
-	  return const0_rtx;
-	}
-
-      rtx tcb_hwcap = gen_reg_rtx (SImode);
-      rtx address = gen_rtx_PLUS (Pmode,
-				  gen_rtx_REG (Pmode, TLS_REGNUM),
-				  GEN_INT (hwcap_offset));
-      rtx tcbmem = gen_const_mem (SImode, address);
-      emit_move_insn (tcb_hwcap, tcbmem);
-      rtx scratch1 = gen_reg_rtx (SImode);
-      emit_insn (gen_rtx_SET (scratch1,
-			      gen_rtx_AND (SImode, tcb_hwcap, mask)));
-      rtx scratch2 = gen_reg_rtx (SImode);
-      emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
-      emit_insn (gen_rtx_SET (target,
-			      gen_rtx_XOR (SImode, scratch2, const1_rtx)));
-    }
-  else
-    gcc_unreachable ();
-
-  /* Record that we have expanded a CPU builtin, so that we can later
-     emit a reference to the special symbol exported by LIBC to ensure we
-     do not link against an old LIBC that doesn't support this feature.  */
-  cpu_builtin_p = true;
-
-#else
-  warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware "
-	   "capability bits", rs6000_builtin_info[(size_t) fcode].bifname);
-
-  /* For old LIBCs, always return FALSE.  */
-  emit_move_insn (target, GEN_INT (0));
-#endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
-
-  return target;
-}
-
-/* For the element-reversing load/store built-ins, produce the correct
-   insn_code depending on the target endianness.  */
-static insn_code
-elemrev_icode (rs6000_gen_builtins fcode)
-{
-  switch (fcode)
-    {
-    case RS6000_BIF_ST_ELEMREV_V1TI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
-			      : CODE_FOR_vsx_st_elemrev_v1ti;
-
-    case RS6000_BIF_ST_ELEMREV_V2DF:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
-			      : CODE_FOR_vsx_st_elemrev_v2df;
-
-    case RS6000_BIF_ST_ELEMREV_V2DI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
-			      : CODE_FOR_vsx_st_elemrev_v2di;
-
-    case RS6000_BIF_ST_ELEMREV_V4SF:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
-			      : CODE_FOR_vsx_st_elemrev_v4sf;
-
-    case RS6000_BIF_ST_ELEMREV_V4SI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
-			      : CODE_FOR_vsx_st_elemrev_v4si;
-
-    case RS6000_BIF_ST_ELEMREV_V8HI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
-			      : CODE_FOR_vsx_st_elemrev_v8hi;
-
-    case RS6000_BIF_ST_ELEMREV_V16QI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
-			      : CODE_FOR_vsx_st_elemrev_v16qi;
-
-    case RS6000_BIF_LD_ELEMREV_V2DF:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
-			      : CODE_FOR_vsx_ld_elemrev_v2df;
-
-    case RS6000_BIF_LD_ELEMREV_V1TI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
-			      : CODE_FOR_vsx_ld_elemrev_v1ti;
-
-    case RS6000_BIF_LD_ELEMREV_V2DI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
-			      : CODE_FOR_vsx_ld_elemrev_v2di;
-
-    case RS6000_BIF_LD_ELEMREV_V4SF:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
-			      : CODE_FOR_vsx_ld_elemrev_v4sf;
-
-    case RS6000_BIF_LD_ELEMREV_V4SI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
-			      : CODE_FOR_vsx_ld_elemrev_v4si;
-
-    case RS6000_BIF_LD_ELEMREV_V8HI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
-			      : CODE_FOR_vsx_ld_elemrev_v8hi;
-
-    case RS6000_BIF_LD_ELEMREV_V16QI:
-      return BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
-			      : CODE_FOR_vsx_ld_elemrev_v16qi;
-    default:
-      ;
-    }
-
-  gcc_unreachable ();
-}
-
-/* Expand an AltiVec vector load builtin, and return the expanded rtx.  */
-static rtx
-ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode)
-{
-  if (target == 0
-      || GET_MODE (target) != tmode
-      || !insn_data[icode].operand[0].predicate (target, tmode))
-    target = gen_reg_rtx (tmode);
-
-  op[1] = copy_to_mode_reg (Pmode, op[1]);
-
-  /* These CELL built-ins use BLKmode instead of tmode for historical
-     (i.e., unknown) reasons.  TODO: Is this necessary?  */
-  bool blk = (icode == CODE_FOR_altivec_lvlx
-	      || icode == CODE_FOR_altivec_lvlxl
-	      || icode == CODE_FOR_altivec_lvrx
-	      || icode == CODE_FOR_altivec_lvrxl);
-
-  /* For LVX, express the RTL accurately by ANDing the address with -16.
-     LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
-     so the raw address is fine.  */
-  /* TODO: That statement seems wrong, as the UNSPECs don't surround the
-     memory expression, so a latent bug may lie here.  The &-16 is likely
-     needed for all VMX-style loads.  */
-  if (icode == CODE_FOR_altivec_lvx_v1ti
-      || icode == CODE_FOR_altivec_lvx_v2df
-      || icode == CODE_FOR_altivec_lvx_v2di
-      || icode == CODE_FOR_altivec_lvx_v4sf
-      || icode == CODE_FOR_altivec_lvx_v4si
-      || icode == CODE_FOR_altivec_lvx_v8hi
-      || icode == CODE_FOR_altivec_lvx_v16qi)
-    {
-      rtx rawaddr;
-      if (op[0] == const0_rtx)
-	rawaddr = op[1];
-      else
-	{
-	  op[0] = copy_to_mode_reg (Pmode, op[0]);
-	  rawaddr = gen_rtx_PLUS (Pmode, op[1], op[0]);
-	}
-      rtx addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
-      addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
-
-      emit_insn (gen_rtx_SET (target, addr));
-    }
-  else
-    {
-      rtx addr;
-      if (op[0] == const0_rtx)
-	addr = gen_rtx_MEM (blk ? BLKmode : tmode, op[1]);
-      else
-	{
-	  op[0] = copy_to_mode_reg (Pmode, op[0]);
-	  addr = gen_rtx_MEM (blk ? BLKmode : tmode,
-			      gen_rtx_PLUS (Pmode, op[1], op[0]));
-	}
-
-      rtx pat = GEN_FCN (icode) (target, addr);
-      if (!pat)
-	return 0;
-      emit_insn (pat);
-    }
-
-  return target;
-}
-
-/* Expand a builtin function that loads a scalar into a vector register
-   with sign extension, and return the expanded rtx.  */
-static rtx
-lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op,
-		       machine_mode tmode, machine_mode smode)
-{
-  rtx pat, addr;
-  op[1] = copy_to_mode_reg (Pmode, op[1]);
-
-  if (op[0] == const0_rtx)
-    addr = gen_rtx_MEM (tmode, op[1]);
-  else
-    {
-      op[0] = copy_to_mode_reg (Pmode, op[0]);
-      addr = gen_rtx_MEM (smode,
-			  gen_rtx_PLUS (Pmode, op[1], op[0]));
-    }
-
-  rtx discratch = gen_reg_rtx (V2DImode);
-  rtx tiscratch = gen_reg_rtx (TImode);
-
-  /* Emit the lxvr*x insn.  */
-  pat = GEN_FCN (icode) (tiscratch, addr);
-  if (!pat)
-    return 0;
-  emit_insn (pat);
-
-  /* Emit a sign extension from V16QI,V8HI,V4SI to V2DI.  */
-  rtx temp1;
-  if (icode == CODE_FOR_vsx_lxvrbx)
-    {
-      temp1  = simplify_gen_subreg (V16QImode, tiscratch, TImode, 0);
-      emit_insn (gen_vsx_sign_extend_qi_v2di (discratch, temp1));
-    }
-  else if (icode == CODE_FOR_vsx_lxvrhx)
-    {
-      temp1  = simplify_gen_subreg (V8HImode, tiscratch, TImode, 0);
-      emit_insn (gen_vsx_sign_extend_hi_v2di (discratch, temp1));
-    }
-  else if (icode == CODE_FOR_vsx_lxvrwx)
-    {
-      temp1  = simplify_gen_subreg (V4SImode, tiscratch, TImode, 0);
-      emit_insn (gen_vsx_sign_extend_si_v2di (discratch, temp1));
-    }
-  else if (icode == CODE_FOR_vsx_lxvrdx)
-    discratch = simplify_gen_subreg (V2DImode, tiscratch, TImode, 0);
-  else
-    gcc_unreachable ();
-
-  /* Emit the sign extension from V2DI (double) to TI (quad).  */
-  rtx temp2 = simplify_gen_subreg (TImode, discratch, V2DImode, 0);
-  emit_insn (gen_extendditi2_vector (target, temp2));
-
-  return target;
-}
-
-/* Expand a builtin function that loads a scalar into a vector register
-   with zero extension, and return the expanded rtx.  */
-static rtx
-lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op,
-		       machine_mode tmode, machine_mode smode)
-{
-  rtx pat, addr;
-  op[1] = copy_to_mode_reg (Pmode, op[1]);
-
-  if (op[0] == const0_rtx)
-    addr = gen_rtx_MEM (tmode, op[1]);
-  else
-    {
-      op[0] = copy_to_mode_reg (Pmode, op[0]);
-      addr = gen_rtx_MEM (smode,
-			  gen_rtx_PLUS (Pmode, op[1], op[0]));
-    }
-
-  pat = GEN_FCN (icode) (target, addr);
-  if (!pat)
-    return 0;
-  emit_insn (pat);
-  return target;
-}
-
-/* Expand an AltiVec vector store builtin, and return the expanded rtx.  */
-static rtx
-stv_expand_builtin (insn_code icode, rtx *op,
-		    machine_mode tmode, machine_mode smode)
-{
-  op[2] = copy_to_mode_reg (Pmode, op[2]);
-
-  /* For STVX, express the RTL accurately by ANDing the address with -16.
-     STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
-     so the raw address is fine.  */
-  /* TODO: That statement seems wrong, as the UNSPECs don't surround the
-     memory expression, so a latent bug may lie here.  The &-16 is likely
-     needed for all VMX-style stores.  */
-  if (icode == CODE_FOR_altivec_stvx_v2df
-      || icode == CODE_FOR_altivec_stvx_v2di
-      || icode == CODE_FOR_altivec_stvx_v4sf
-      || icode == CODE_FOR_altivec_stvx_v4si
-      || icode == CODE_FOR_altivec_stvx_v8hi
-      || icode == CODE_FOR_altivec_stvx_v16qi)
-    {
-      rtx rawaddr;
-      if (op[1] == const0_rtx)
-	rawaddr = op[2];
-      else
-	{
-	  op[1] = copy_to_mode_reg (Pmode, op[1]);
-	  rawaddr = gen_rtx_PLUS (Pmode, op[2], op[1]);
-	}
-
-      rtx addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
-      addr = gen_rtx_MEM (tmode, addr);
-      op[0] = copy_to_mode_reg (tmode, op[0]);
-      emit_insn (gen_rtx_SET (addr, op[0]));
-    }
-  else if (icode == CODE_FOR_vsx_stxvrbx
-	   || icode == CODE_FOR_vsx_stxvrhx
-	   || icode == CODE_FOR_vsx_stxvrwx
-	   || icode == CODE_FOR_vsx_stxvrdx)
-    {
-      rtx truncrtx = gen_rtx_TRUNCATE (tmode, op[0]);
-      op[0] = copy_to_mode_reg (E_TImode, truncrtx);
-
-      rtx addr;
-      if (op[1] == const0_rtx)
-	addr = gen_rtx_MEM (Pmode, op[2]);
-      else
-	{
-	  op[1] = copy_to_mode_reg (Pmode, op[1]);
-	  addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
-	}
-      rtx pat = GEN_FCN (icode) (addr, op[0]);
-      if (pat)
-	emit_insn (pat);
-    }
-  else
-    {
-      if (!insn_data[icode].operand[1].predicate (op[0], smode))
-	op[0] = copy_to_mode_reg (smode, op[0]);
-
-      rtx addr;
-      if (op[1] == const0_rtx)
-	addr = gen_rtx_MEM (tmode, op[2]);
-      else
-	{
-	  op[1] = copy_to_mode_reg (Pmode, op[1]);
-	  addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op[2], op[1]));
-	}
-
-      rtx pat = GEN_FCN (icode) (addr, op[0]);
-      if (pat)
-	emit_insn (pat);
-    }
-
-  return NULL_RTX;
-}
-
-/* Expand the MMA built-in in EXP, and return it.  */
-static rtx
-mma_expand_builtin (tree exp, rtx target, insn_code icode,
-		    rs6000_gen_builtins fcode)
-{
-  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
-  machine_mode tmode = VOIDmode;
-  rtx op[MAX_MMA_OPERANDS];
-  unsigned nopnds = 0;
-
-  if (!void_func)
-    {
-      tmode = insn_data[icode].operand[0].mode;
-      if (!(target
-	    && GET_MODE (target) == tmode
-	    && insn_data[icode].operand[0].predicate (target, tmode)))
-	target = gen_reg_rtx (tmode);
-      op[nopnds++] = target;
-    }
-  else
-    target = const0_rtx;
-
-  call_expr_arg_iterator iter;
-  tree arg;
-  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
-    {
-      if (arg == error_mark_node)
-	return const0_rtx;
-
-      rtx opnd;
-      const struct insn_operand_data *insn_op;
-      insn_op = &insn_data[icode].operand[nopnds];
-      if (TREE_CODE (arg) == ADDR_EXPR
-	  && MEM_P (DECL_RTL (TREE_OPERAND (arg, 0))))
-	opnd = DECL_RTL (TREE_OPERAND (arg, 0));
-      else
-	opnd = expand_normal (arg);
-
-      if (!insn_op->predicate (opnd, insn_op->mode))
-	{
-	  /* TODO: This use of constraints needs explanation.  */
-	  if (!strcmp (insn_op->constraint, "n"))
-	    {
-	      if (!CONST_INT_P (opnd))
-		error ("argument %d must be an unsigned literal", nopnds);
-	      else
-		error ("argument %d is an unsigned literal that is "
-		       "out of range", nopnds);
-	      return const0_rtx;
-	    }
-	  opnd = copy_to_mode_reg (insn_op->mode, opnd);
-	}
-
-      /* Some MMA instructions have INOUT accumulator operands, so force
-	 their target register to be the same as their input register.  */
-      if (!void_func
-	  && nopnds == 1
-	  && !strcmp (insn_op->constraint, "0")
-	  && insn_op->mode == tmode
-	  && REG_P (opnd)
-	  && insn_data[icode].operand[0].predicate (opnd, tmode))
-	target = op[0] = opnd;
-
-      op[nopnds++] = opnd;
-    }
-
-  rtx pat;
-  switch (nopnds)
-    {
-    case 1:
-      pat = GEN_FCN (icode) (op[0]);
-      break;
-    case 2:
-      pat = GEN_FCN (icode) (op[0], op[1]);
-      break;
-    case 3:
-      /* The ASSEMBLE builtin source operands are reversed in little-endian
-	 mode, so reorder them.  */
-      if (fcode == RS6000_BIF_ASSEMBLE_PAIR_V_INTERNAL && !WORDS_BIG_ENDIAN)
-	std::swap (op[1], op[2]);
-      pat = GEN_FCN (icode) (op[0], op[1], op[2]);
-      break;
-    case 4:
-      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
-      break;
-    case 5:
-      /* The ASSEMBLE builtin source operands are reversed in little-endian
-	 mode, so reorder them.  */
-      if (fcode == RS6000_BIF_ASSEMBLE_ACC_INTERNAL && !WORDS_BIG_ENDIAN)
-	{
-	  std::swap (op[1], op[4]);
-	  std::swap (op[2], op[3]);
-	}
-      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
-      break;
-    case 6:
-      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
-      break;
-    case 7:
-      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5], op[6]);
-      break;
-    default:
-      gcc_unreachable ();
-    }
-
-  if (!pat)
-    return NULL_RTX;
-
-  emit_insn (pat);
-  return target;
-}
-
-/* Return the appropriate SPR number associated with the given builtin.  */
-static inline HOST_WIDE_INT
-htm_spr_num (enum rs6000_gen_builtins code)
-{
-  if (code == RS6000_BIF_GET_TFHAR
-      || code == RS6000_BIF_SET_TFHAR)
-    return TFHAR_SPR;
-  else if (code == RS6000_BIF_GET_TFIAR
-	   || code == RS6000_BIF_SET_TFIAR)
-    return TFIAR_SPR;
-  else if (code == RS6000_BIF_GET_TEXASR
-	   || code == RS6000_BIF_SET_TEXASR)
-    return TEXASR_SPR;
-  gcc_assert (code == RS6000_BIF_GET_TEXASRU
-	      || code == RS6000_BIF_SET_TEXASRU);
-  return TEXASRU_SPR;
-}
-
-/* Expand the HTM builtin in EXP and store the result in TARGET.
-   Return the expanded rtx.  */
-static rtx
-htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode,
-		    tree exp, rtx target)
-{
-  if (!TARGET_POWERPC64
-      && (fcode == RS6000_BIF_TABORTDC
-	  || fcode == RS6000_BIF_TABORTDCI))
-    {
-      error ("builtin %qs is only valid in 64-bit mode", bifaddr->bifname);
-      return const0_rtx;
-    }
-
-  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
-  bool uses_spr = bif_is_htmspr (*bifaddr);
-  insn_code icode = bifaddr->icode;
-
-  if (uses_spr)
-    icode = rs6000_htm_spr_icode (nonvoid);
-
-  rtx op[MAX_HTM_OPERANDS];
-  int nopnds = 0;
-  const insn_operand_data *insn_op = &insn_data[icode].operand[0];
-
-  if (nonvoid)
-    {
-      machine_mode tmode = (uses_spr) ? insn_op->mode : E_SImode;
-      if (!target
-	  || GET_MODE (target) != tmode
-	  || (uses_spr && !insn_op->predicate (target, tmode)))
-	target = gen_reg_rtx (tmode);
-      if (uses_spr)
-	op[nopnds++] = target;
-    }
-
-  tree arg;
-  call_expr_arg_iterator iter;
-
-  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
-    {
-      if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS)
-	return const0_rtx;
-
-      insn_op = &insn_data[icode].operand[nopnds];
-      op[nopnds] = expand_normal (arg);
-
-      if (!insn_op->predicate (op[nopnds], insn_op->mode))
-	{
-	  /* TODO: This use of constraints could use explanation.
-	     This happens a couple of places, perhaps make that a
-	     function to document what's happening.  */
-	  if (!strcmp (insn_op->constraint, "n"))
-	    {
-	      int arg_num = nonvoid ? nopnds : nopnds + 1;
-	      if (!CONST_INT_P (op[nopnds]))
-		error ("argument %d must be an unsigned literal", arg_num);
-	      else
-		error ("argument %d is an unsigned literal that is "
-		       "out of range", arg_num);
-	      return const0_rtx;
-	    }
-	  op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
-	}
-
-      nopnds++;
-    }
-
-  /* Handle the builtins for extended mnemonics.  These accept
-     no arguments, but map to builtins that take arguments.  */
-  switch (fcode)
-    {
-    case RS6000_BIF_TENDALL:  /* Alias for: tend. 1  */
-    case RS6000_BIF_TRESUME:  /* Alias for: tsr. 1  */
-      op[nopnds++] = GEN_INT (1);
-      break;
-    case RS6000_BIF_TSUSPEND: /* Alias for: tsr. 0  */
-      op[nopnds++] = GEN_INT (0);
-      break;
-    default:
-      break;
-    }
-
-  /* If this builtin accesses SPRs, then pass in the appropriate
-     SPR number and SPR regno as the last two operands.  */
-  rtx cr = NULL_RTX;
-  if (uses_spr)
-    {
-      machine_mode mode = TARGET_POWERPC64 ? DImode : SImode;
-      op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode));
-    }
-  /* If this builtin accesses a CR field, then pass in a scratch
-     CR field as the last operand.  */
-  else if (bif_is_htmcr (*bifaddr))
-    {
-      cr = gen_reg_rtx (CCmode);
-      op[nopnds++] = cr;
-    }
-
-  rtx pat;
-  switch (nopnds)
-    {
-    case 1:
-      pat = GEN_FCN (icode) (op[0]);
-      break;
-    case 2:
-      pat = GEN_FCN (icode) (op[0], op[1]);
-      break;
-    case 3:
-      pat = GEN_FCN (icode) (op[0], op[1], op[2]);
-      break;
-    case 4:
-      pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
-      break;
-    default:
-      gcc_unreachable ();
-    }
-  if (!pat)
-    return NULL_RTX;
-  emit_insn (pat);
-
-  if (bif_is_htmcr (*bifaddr))
-    {
-      if (fcode == RS6000_BIF_TBEGIN)
-	{
-	  /* Emit code to set TARGET to true or false depending on
-	     whether the tbegin. instruction succeeded or failed
-	     to start a transaction.  We do this by placing the 1's
-	     complement of CR's EQ bit into TARGET.  */
-	  rtx scratch = gen_reg_rtx (SImode);
-	  emit_insn (gen_rtx_SET (scratch,
-				  gen_rtx_EQ (SImode, cr,
-					      const0_rtx)));
-	  emit_insn (gen_rtx_SET (target,
-				  gen_rtx_XOR (SImode, scratch,
-					       GEN_INT (1))));
-	}
-      else
-	{
-	  /* Emit code to copy the 4-bit condition register field
-	     CR into the least significant end of register TARGET.  */
-	  rtx scratch1 = gen_reg_rtx (SImode);
-	  rtx scratch2 = gen_reg_rtx (SImode);
-	  rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0);
-	  emit_insn (gen_movcc (subreg, cr));
-	  emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28)));
-	  emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf)));
-	}
-    }
-
-  if (nonvoid)
-    return target;
-  return const0_rtx;
-}
-
-/* Expand an expression EXP that calls a built-in function,
-   with result going to TARGET if that's convenient
-   (and in mode MODE if that's convenient).
-   SUBTARGET may be used as the target for computing one of EXP's operands.
-   IGNORE is nonzero if the value is to be ignored.
-   Use the new builtin infrastructure.  */
-rtx
-rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
-		       machine_mode /* mode */, int ignore)
-{
-  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  enum rs6000_gen_builtins fcode
-    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
-  size_t uns_fcode = (size_t)fcode;
-  enum insn_code icode = rs6000_builtin_info[uns_fcode].icode;
-
-  /* TODO: The following commentary and code is inherited from the original
-     builtin processing code.  The commentary is a bit confusing, with the
-     intent being that KFmode is always IEEE-128, IFmode is always IBM
-     double-double, and TFmode is the current long double.  The code is
-     confusing in that it converts from KFmode to TFmode pattern names,
-     when the other direction is more intuitive.  Try to address this.  */
-
-  /* We have two different modes (KFmode, TFmode) that are the IEEE
-     128-bit floating point type, depending on whether long double is the
-     IBM extended double (KFmode) or long double is IEEE 128-bit (TFmode).
-     It is simpler if we only define one variant of the built-in function,
-     and switch the code when defining it, rather than defining two built-
-     ins and using the overload table in rs6000-c.cc to switch between the
-     two.  If we don't have the proper assembler, don't do this switch
-     because CODE_FOR_*kf* and CODE_FOR_*tf* will be CODE_FOR_nothing.  */
-  if (FLOAT128_IEEE_P (TFmode))
-    switch (icode)
-      {
-      case CODE_FOR_sqrtkf2_odd:
-	icode = CODE_FOR_sqrttf2_odd;
-	break;
-      case CODE_FOR_trunckfdf2_odd:
-	icode = CODE_FOR_trunctfdf2_odd;
-	break;
-      case CODE_FOR_addkf3_odd:
-	icode = CODE_FOR_addtf3_odd;
-	break;
-      case CODE_FOR_subkf3_odd:
-	icode = CODE_FOR_subtf3_odd;
-	break;
-      case CODE_FOR_mulkf3_odd:
-	icode = CODE_FOR_multf3_odd;
-	break;
-      case CODE_FOR_divkf3_odd:
-	icode = CODE_FOR_divtf3_odd;
-	break;
-      case CODE_FOR_fmakf4_odd:
-	icode = CODE_FOR_fmatf4_odd;
-	break;
-      case CODE_FOR_xsxexpqp_kf:
-	icode = CODE_FOR_xsxexpqp_tf;
-	break;
-      case CODE_FOR_xsxsigqp_kf:
-	icode = CODE_FOR_xsxsigqp_tf;
-	break;
-      case CODE_FOR_xststdcnegqp_kf:
-	icode = CODE_FOR_xststdcnegqp_tf;
-	break;
-      case CODE_FOR_xsiexpqp_kf:
-	icode = CODE_FOR_xsiexpqp_tf;
-	break;
-      case CODE_FOR_xsiexpqpf_kf:
-	icode = CODE_FOR_xsiexpqpf_tf;
-	break;
-      case CODE_FOR_xststdcqp_kf:
-	icode = CODE_FOR_xststdcqp_tf;
-	break;
-      case CODE_FOR_xscmpexpqp_eq_kf:
-	icode = CODE_FOR_xscmpexpqp_eq_tf;
-	break;
-      case CODE_FOR_xscmpexpqp_lt_kf:
-	icode = CODE_FOR_xscmpexpqp_lt_tf;
-	break;
-      case CODE_FOR_xscmpexpqp_gt_kf:
-	icode = CODE_FOR_xscmpexpqp_gt_tf;
-	break;
-      case CODE_FOR_xscmpexpqp_unordered_kf:
-	icode = CODE_FOR_xscmpexpqp_unordered_tf;
-	break;
-      default:
-	break;
-      }
-
-  /* In case of "#pragma target" changes, we initialize all builtins
-     but check for actual availability now, during expand time.  For
-     invalid builtins, generate a normal call.  */
-  bifdata *bifaddr = &rs6000_builtin_info[uns_fcode];
-  bif_enable e = bifaddr->enable;
-
-  if (!(e == ENB_ALWAYS
-	|| (e == ENB_P5 && TARGET_POPCNTB)
-	|| (e == ENB_P6 && TARGET_CMPB)
-	|| (e == ENB_P6_64 && TARGET_CMPB && TARGET_POWERPC64)
-	|| (e == ENB_ALTIVEC && TARGET_ALTIVEC)
-	|| (e == ENB_CELL && TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL)
-	|| (e == ENB_VSX && TARGET_VSX)
-	|| (e == ENB_P7 && TARGET_POPCNTD)
-	|| (e == ENB_P7_64 && TARGET_POPCNTD && TARGET_POWERPC64)
-	|| (e == ENB_P8 && TARGET_DIRECT_MOVE)
-	|| (e == ENB_P8V && TARGET_P8_VECTOR)
-	|| (e == ENB_P9 && TARGET_MODULO)
-	|| (e == ENB_P9_64 && TARGET_MODULO && TARGET_POWERPC64)
-	|| (e == ENB_P9V && TARGET_P9_VECTOR)
-	|| (e == ENB_IEEE128_HW && TARGET_FLOAT128_HW)
-	|| (e == ENB_DFP && TARGET_DFP)
-	|| (e == ENB_CRYPTO && TARGET_CRYPTO)
-	|| (e == ENB_HTM && TARGET_HTM)
-	|| (e == ENB_P10 && TARGET_POWER10)
-	|| (e == ENB_P10_64 && TARGET_POWER10 && TARGET_POWERPC64)
-	|| (e == ENB_MMA && TARGET_MMA)))
-    {
-      rs6000_invalid_builtin (fcode);
-      return expand_call (exp, target, ignore);
-    }
-
-  if (bif_is_nosoft (*bifaddr)
-      && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
-    {
-      error ("%qs not supported with %<-msoft-float%>",
-	     bifaddr->bifname);
-      return const0_rtx;
-    }
-
-  if (bif_is_no32bit (*bifaddr) && TARGET_32BIT)
-    {
-      error ("%qs is not supported in 32-bit mode", bifaddr->bifname);
-      return const0_rtx;
-    }
-
-  if (bif_is_ibmld (*bifaddr) && !FLOAT128_2REG_P (TFmode))
-    {
-      error ("%qs requires %<long double%> to be IBM 128-bit format",
-	     bifaddr->bifname);
-      return const0_rtx;
-    }
-
-  if (bif_is_cpu (*bifaddr))
-    return cpu_expand_builtin (fcode, exp, target);
-
-  if (bif_is_init (*bifaddr))
-    return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
-
-  if (bif_is_set (*bifaddr))
-    return altivec_expand_vec_set_builtin (exp);
-
-  if (bif_is_extract (*bifaddr))
-    return altivec_expand_vec_ext_builtin (exp, target);
-
-  if (bif_is_predicate (*bifaddr))
-    return altivec_expand_predicate_builtin (icode, exp, target);
-
-  if (bif_is_htm (*bifaddr))
-    return htm_expand_builtin (bifaddr, fcode, exp, target);
-
-  if (bif_is_32bit (*bifaddr) && TARGET_32BIT)
-    {
-      if (fcode == RS6000_BIF_MFTB)
-	icode = CODE_FOR_rs6000_mftb_si;
-      else if (fcode == RS6000_BIF_BPERMD)
-	icode = CODE_FOR_bpermd_si;
-      else if (fcode == RS6000_BIF_DARN)
-	icode = CODE_FOR_darn_64_si;
-      else if (fcode == RS6000_BIF_DARN_32)
-	icode = CODE_FOR_darn_32_si;
-      else if (fcode == RS6000_BIF_DARN_RAW)
-	icode = CODE_FOR_darn_raw_si;
-      else
-	gcc_unreachable ();
-    }
-
-  if (bif_is_endian (*bifaddr) && BYTES_BIG_ENDIAN)
-    {
-      if (fcode == RS6000_BIF_LD_ELEMREV_V1TI)
-	icode = CODE_FOR_vsx_load_v1ti;
-      else if (fcode == RS6000_BIF_LD_ELEMREV_V2DF)
-	icode = CODE_FOR_vsx_load_v2df;
-      else if (fcode == RS6000_BIF_LD_ELEMREV_V2DI)
-	icode = CODE_FOR_vsx_load_v2di;
-      else if (fcode == RS6000_BIF_LD_ELEMREV_V4SF)
-	icode = CODE_FOR_vsx_load_v4sf;
-      else if (fcode == RS6000_BIF_LD_ELEMREV_V4SI)
-	icode = CODE_FOR_vsx_load_v4si;
-      else if (fcode == RS6000_BIF_LD_ELEMREV_V8HI)
-	icode = CODE_FOR_vsx_load_v8hi;
-      else if (fcode == RS6000_BIF_LD_ELEMREV_V16QI)
-	icode = CODE_FOR_vsx_load_v16qi;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V1TI)
-	icode = CODE_FOR_vsx_store_v1ti;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V2DF)
-	icode = CODE_FOR_vsx_store_v2df;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V2DI)
-	icode = CODE_FOR_vsx_store_v2di;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V4SF)
-	icode = CODE_FOR_vsx_store_v4sf;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V4SI)
-	icode = CODE_FOR_vsx_store_v4si;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V8HI)
-	icode = CODE_FOR_vsx_store_v8hi;
-      else if (fcode == RS6000_BIF_ST_ELEMREV_V16QI)
-	icode = CODE_FOR_vsx_store_v16qi;
-      else
-	gcc_unreachable ();
-    }
-
-
-  /* TRUE iff the built-in function returns void.  */
-  bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node;
-  /* Position of first argument (0 for void-returning functions, else 1).  */
-  int k;
-  /* Modes for the return value, if any, and arguments.  */
-  const int MAX_BUILTIN_ARGS = 6;
-  machine_mode mode[MAX_BUILTIN_ARGS + 1];
-
-  if (void_func)
-    k = 0;
-  else
-    {
-      k = 1;
-      mode[0] = insn_data[icode].operand[0].mode;
-    }
-
-  /* Tree expressions for each argument.  */
-  tree arg[MAX_BUILTIN_ARGS];
-  /* RTL expressions for each argument.  */
-  rtx op[MAX_BUILTIN_ARGS];
-
-  int nargs = bifaddr->nargs;
-  gcc_assert (nargs <= MAX_BUILTIN_ARGS);
-
-
-  for (int i = 0; i < nargs; i++)
-    {
-      arg[i] = CALL_EXPR_ARG (exp, i);
-      if (arg[i] == error_mark_node)
-	return const0_rtx;
-      STRIP_NOPS (arg[i]);
-      op[i] = expand_normal (arg[i]);
-      /* We have a couple of pesky patterns that don't specify the mode...  */
-      mode[i+k] = insn_data[icode].operand[i+k].mode;
-      if (!mode[i+k])
-	mode[i+k] = Pmode;
-    }
-
-  /* Check for restricted constant arguments.  */
-  for (int i = 0; i < 2; i++)
-    {
-      switch (bifaddr->restr[i])
-	{
-	case RES_BITS:
-	  {
-	    size_t mask = 1;
-	    mask <<= bifaddr->restr_val1[i];
-	    mask--;
-	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
-	    STRIP_NOPS (restr_arg);
-	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
-		  && (TREE_INT_CST_LOW (restr_arg) & ~mask) == 0))
-	      {
-		error ("argument %d must be a %d-bit unsigned literal",
-		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i]);
-		return CONST0_RTX (mode[0]);
-	      }
-	    break;
-	  }
-	case RES_RANGE:
-	  {
-	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
-	    STRIP_NOPS (restr_arg);
-	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
-		  && IN_RANGE (tree_to_shwi (restr_arg),
-			       bifaddr->restr_val1[i],
-			       bifaddr->restr_val2[i])))
-	      {
-		error ("argument %d must be a literal between %d and %d,"
-		       " inclusive",
-		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i],
-		       bifaddr->restr_val2[i]);
-		return CONST0_RTX (mode[0]);
-	      }
-	    break;
-	  }
-	case RES_VAR_RANGE:
-	  {
-	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
-	    STRIP_NOPS (restr_arg);
-	    if (TREE_CODE (restr_arg) == INTEGER_CST
-		&& !IN_RANGE (tree_to_shwi (restr_arg),
-			      bifaddr->restr_val1[i],
-			      bifaddr->restr_val2[i]))
-	      {
-		error ("argument %d must be a variable or a literal "
-		       "between %d and %d, inclusive",
-		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i],
-		       bifaddr->restr_val2[i]);
-		return CONST0_RTX (mode[0]);
-	      }
-	    break;
-	  }
-	case RES_VALUES:
-	  {
-	    tree restr_arg = arg[bifaddr->restr_opnd[i] - 1];
-	    STRIP_NOPS (restr_arg);
-	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
-		  && (tree_to_shwi (restr_arg) == bifaddr->restr_val1[i]
-		      || tree_to_shwi (restr_arg) == bifaddr->restr_val2[i])))
-	      {
-		error ("argument %d must be either a literal %d or a "
-		       "literal %d",
-		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i],
-		       bifaddr->restr_val2[i]);
-		return CONST0_RTX (mode[0]);
-	      }
-	    break;
-	  }
-	default:
-	case RES_NONE:
-	  break;
-	}
-    }
-
-  if (bif_is_ldstmask (*bifaddr))
-    return rs6000_expand_ldst_mask (target, arg[0]);
-
-  if (bif_is_stvec (*bifaddr))
-    {
-      if (bif_is_reve (*bifaddr))
-	icode = elemrev_icode (fcode);
-      return stv_expand_builtin (icode, op, mode[0], mode[1]);
-    }
-
-  if (bif_is_ldvec (*bifaddr))
-    {
-      if (bif_is_reve (*bifaddr))
-	icode = elemrev_icode (fcode);
-      return ldv_expand_builtin (target, icode, op, mode[0]);
-    }
-
-  if (bif_is_lxvrse (*bifaddr))
-    return lxvrse_expand_builtin (target, icode, op, mode[0], mode[1]);
-
-  if (bif_is_lxvrze (*bifaddr))
-    return lxvrze_expand_builtin (target, icode, op, mode[0], mode[1]);
-
-  if (bif_is_mma (*bifaddr))
-    return mma_expand_builtin (exp, target, icode, fcode);
-
-  if (fcode == RS6000_BIF_PACK_IF
-      && TARGET_LONG_DOUBLE_128
-      && !TARGET_IEEEQUAD)
-    {
-      icode = CODE_FOR_packtf;
-      fcode = RS6000_BIF_PACK_TF;
-      uns_fcode = (size_t) fcode;
-    }
-  else if (fcode == RS6000_BIF_UNPACK_IF
-	   && TARGET_LONG_DOUBLE_128
-	   && !TARGET_IEEEQUAD)
-    {
-      icode = CODE_FOR_unpacktf;
-      fcode = RS6000_BIF_UNPACK_TF;
-      uns_fcode = (size_t) fcode;
-    }
-
-  if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node)
-    target = NULL_RTX;
-  else if (target == 0
-	   || GET_MODE (target) != mode[0]
-	   || !insn_data[icode].operand[0].predicate (target, mode[0]))
-    target = gen_reg_rtx (mode[0]);
-
-  for (int i = 0; i < nargs; i++)
-    if (!insn_data[icode].operand[i+k].predicate (op[i], mode[i+k]))
-      op[i] = copy_to_mode_reg (mode[i+k], op[i]);
-
-  rtx pat;
-
-  switch (nargs)
-    {
-    case 0:
-      pat = (void_func
-	     ? GEN_FCN (icode) ()
-	     : GEN_FCN (icode) (target));
-      break;
-    case 1:
-      pat = (void_func
-	     ? GEN_FCN (icode) (op[0])
-	     : GEN_FCN (icode) (target, op[0]));
-      break;
-    case 2:
-      pat = (void_func
-	     ? GEN_FCN (icode) (op[0], op[1])
-	     : GEN_FCN (icode) (target, op[0], op[1]));
-      break;
-    case 3:
-      pat = (void_func
-	     ? GEN_FCN (icode) (op[0], op[1], op[2])
-	     : GEN_FCN (icode) (target, op[0], op[1], op[2]));
-      break;
-    case 4:
-      pat = (void_func
-	     ? GEN_FCN (icode) (op[0], op[1], op[2], op[3])
-	     : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]));
-      break;
-    case 5:
-      pat = (void_func
-	     ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4])
-	     : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]));
-      break;
-    case 6:
-      pat = (void_func
-	     ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5])
-	     : GEN_FCN (icode) (target, op[0], op[1],
-				op[2], op[3], op[4], op[5]));
-      break;
-    default:
-      gcc_assert (MAX_BUILTIN_ARGS == 6);
-      gcc_unreachable ();
-    }
-
-  if (!pat)
-    return 0;
-
-  emit_insn (pat);
-  return target;
-}
-
-/* Create a builtin vector type with a name.  Taking care not to give
-   the canonical type a name.  */
-
-static tree
-rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts)
-{
-  tree result = build_vector_type (elt_type, num_elts);
-
-  /* Copy so we don't give the canonical type a name.  */
-  result = build_variant_type_copy (result);
-
-  add_builtin_type (name, result);
-
-  return result;
-}
-
-void
-rs6000_init_builtins (void)
-{
-  tree tdecl;
-  tree t;
-
-  if (TARGET_DEBUG_BUILTIN)
-    fprintf (stderr, "rs6000_init_builtins%s%s\n",
-	     (TARGET_ALTIVEC)	   ? ", altivec" : "",
-	     (TARGET_VSX)	   ? ", vsx"	 : "");
-
-  V2DI_type_node = rs6000_vector_type ("__vector long long",
-				       long_long_integer_type_node, 2);
-  ptr_V2DI_type_node
-    = build_pointer_type (build_qualified_type (V2DI_type_node,
-						TYPE_QUAL_CONST));
-
-  V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2);
-  ptr_V2DF_type_node
-    = build_pointer_type (build_qualified_type (V2DF_type_node,
-						TYPE_QUAL_CONST));
-
-  V4SI_type_node = rs6000_vector_type ("__vector signed int",
-				       intSI_type_node, 4);
-  ptr_V4SI_type_node
-    = build_pointer_type (build_qualified_type (V4SI_type_node,
-						TYPE_QUAL_CONST));
-
-  V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4);
-  ptr_V4SF_type_node
-    = build_pointer_type (build_qualified_type (V4SF_type_node,
-						TYPE_QUAL_CONST));
-
-  V8HI_type_node = rs6000_vector_type ("__vector signed short",
-				       intHI_type_node, 8);
-  ptr_V8HI_type_node
-    = build_pointer_type (build_qualified_type (V8HI_type_node,
-						TYPE_QUAL_CONST));
-
-  V16QI_type_node = rs6000_vector_type ("__vector signed char",
-					intQI_type_node, 16);
-  ptr_V16QI_type_node
-    = build_pointer_type (build_qualified_type (V16QI_type_node,
-						TYPE_QUAL_CONST));
-
-  unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char",
-					unsigned_intQI_type_node, 16);
-  ptr_unsigned_V16QI_type_node
-    = build_pointer_type (build_qualified_type (unsigned_V16QI_type_node,
-						TYPE_QUAL_CONST));
-
-  unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short",
-				       unsigned_intHI_type_node, 8);
-  ptr_unsigned_V8HI_type_node
-    = build_pointer_type (build_qualified_type (unsigned_V8HI_type_node,
-						TYPE_QUAL_CONST));
-
-  unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int",
-				       unsigned_intSI_type_node, 4);
-  ptr_unsigned_V4SI_type_node
-    = build_pointer_type (build_qualified_type (unsigned_V4SI_type_node,
-						TYPE_QUAL_CONST));
-
-  unsigned_V2DI_type_node
-    = rs6000_vector_type ("__vector unsigned long long",
-			  long_long_unsigned_type_node, 2);
-
-  ptr_unsigned_V2DI_type_node
-    = build_pointer_type (build_qualified_type (unsigned_V2DI_type_node,
-						TYPE_QUAL_CONST));
-
-  opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
-
-  const_str_type_node
-    = build_pointer_type (build_qualified_type (char_type_node,
-						TYPE_QUAL_CONST));
-
-  /* We use V1TI mode as a special container to hold __int128_t items that
-     must live in VSX registers.  */
-  if (intTI_type_node)
-    {
-      V1TI_type_node = rs6000_vector_type ("__vector __int128",
-					   intTI_type_node, 1);
-      ptr_V1TI_type_node
-	= build_pointer_type (build_qualified_type (V1TI_type_node,
-						    TYPE_QUAL_CONST));
-      unsigned_V1TI_type_node
-	= rs6000_vector_type ("__vector unsigned __int128",
-			      unsigned_intTI_type_node, 1);
-      ptr_unsigned_V1TI_type_node
-	= build_pointer_type (build_qualified_type (unsigned_V1TI_type_node,
-						    TYPE_QUAL_CONST));
-    }
-
-  /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
-     types, especially in C++ land.  Similarly, 'vector pixel' is distinct from
-     'vector unsigned short'.  */
-
-  bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
-  bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
-  bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
-  bool_long_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
-  pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
-
-  long_integer_type_internal_node = long_integer_type_node;
-  long_unsigned_type_internal_node = long_unsigned_type_node;
-  long_long_integer_type_internal_node = long_long_integer_type_node;
-  long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
-  intQI_type_internal_node = intQI_type_node;
-  uintQI_type_internal_node = unsigned_intQI_type_node;
-  intHI_type_internal_node = intHI_type_node;
-  uintHI_type_internal_node = unsigned_intHI_type_node;
-  intSI_type_internal_node = intSI_type_node;
-  uintSI_type_internal_node = unsigned_intSI_type_node;
-  intDI_type_internal_node = intDI_type_node;
-  uintDI_type_internal_node = unsigned_intDI_type_node;
-  intTI_type_internal_node = intTI_type_node;
-  uintTI_type_internal_node = unsigned_intTI_type_node;
-  float_type_internal_node = float_type_node;
-  double_type_internal_node = double_type_node;
-  long_double_type_internal_node = long_double_type_node;
-  dfloat64_type_internal_node = dfloat64_type_node;
-  dfloat128_type_internal_node = dfloat128_type_node;
-  void_type_internal_node = void_type_node;
-
-  ptr_intQI_type_node
-    = build_pointer_type (build_qualified_type (intQI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_uintQI_type_node
-    = build_pointer_type (build_qualified_type (uintQI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_intHI_type_node
-    = build_pointer_type (build_qualified_type (intHI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_uintHI_type_node
-    = build_pointer_type (build_qualified_type (uintHI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_intSI_type_node
-    = build_pointer_type (build_qualified_type (intSI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_uintSI_type_node
-    = build_pointer_type (build_qualified_type (uintSI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_intDI_type_node
-    = build_pointer_type (build_qualified_type (intDI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_uintDI_type_node
-    = build_pointer_type (build_qualified_type (uintDI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_intTI_type_node
-    = build_pointer_type (build_qualified_type (intTI_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_uintTI_type_node
-    = build_pointer_type (build_qualified_type (uintTI_type_internal_node,
-						TYPE_QUAL_CONST));
-
-  t = build_qualified_type (long_integer_type_internal_node, TYPE_QUAL_CONST);
-  ptr_long_integer_type_node = build_pointer_type (t);
-
-  t = build_qualified_type (long_unsigned_type_internal_node, TYPE_QUAL_CONST);
-  ptr_long_unsigned_type_node = build_pointer_type (t);
-
-  ptr_float_type_node
-    = build_pointer_type (build_qualified_type (float_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_double_type_node
-    = build_pointer_type (build_qualified_type (double_type_internal_node,
-						TYPE_QUAL_CONST));
-  ptr_long_double_type_node
-    = build_pointer_type (build_qualified_type (long_double_type_internal_node,
-						TYPE_QUAL_CONST));
-  if (dfloat64_type_node)
-    {
-      t = build_qualified_type (dfloat64_type_internal_node, TYPE_QUAL_CONST);
-      ptr_dfloat64_type_node = build_pointer_type (t);
-    }
-  else
-    ptr_dfloat64_type_node = NULL;
-
-  if (dfloat128_type_node)
-    {
-      t = build_qualified_type (dfloat128_type_internal_node, TYPE_QUAL_CONST);
-      ptr_dfloat128_type_node = build_pointer_type (t);
-    }
-  else
-    ptr_dfloat128_type_node = NULL;
-
-  t = build_qualified_type (long_long_integer_type_internal_node,
-			    TYPE_QUAL_CONST);
-  ptr_long_long_integer_type_node  = build_pointer_type (t);
-
-  t = build_qualified_type (long_long_unsigned_type_internal_node,
-			    TYPE_QUAL_CONST);
-  ptr_long_long_unsigned_type_node = build_pointer_type (t);
-
-  /* 128-bit floating point support.  KFmode is IEEE 128-bit floating point.
-     IFmode is the IBM extended 128-bit format that is a pair of doubles.
-     TFmode will be either IEEE 128-bit floating point or the IBM double-double
-     format that uses a pair of doubles, depending on the switches and
-     defaults.
-
-     If we don't support for either 128-bit IBM double double or IEEE 128-bit
-     floating point, we need make sure the type is non-zero or else self-test
-     fails during bootstrap.
-
-     Always create __ibm128 as a separate type, even if the current long double
-     format is IBM extended double.
-
-     For IEEE 128-bit floating point, always create the type __ieee128.  If the
-     user used -mfloat128, rs6000-c.cc will create a define from __float128 to
-     __ieee128.  */
-  if (TARGET_FLOAT128_TYPE)
-    {
-      if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
-	ibm128_float_type_node = long_double_type_node;
-      else
-	{
-	  ibm128_float_type_node = make_node (REAL_TYPE);
-	  TYPE_PRECISION (ibm128_float_type_node) = 128;
-	  SET_TYPE_MODE (ibm128_float_type_node, IFmode);
-	  layout_type (ibm128_float_type_node);
-	}
-      t = build_qualified_type (ibm128_float_type_node, TYPE_QUAL_CONST);
-      ptr_ibm128_float_type_node = build_pointer_type (t);
-      lang_hooks.types.register_builtin_type (ibm128_float_type_node,
-					      "__ibm128");
-
-      if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
-	ieee128_float_type_node = long_double_type_node;
-      else
-	ieee128_float_type_node = float128_type_node;
-      t = build_qualified_type (ieee128_float_type_node, TYPE_QUAL_CONST);
-      ptr_ieee128_float_type_node = build_pointer_type (t);
-      lang_hooks.types.register_builtin_type (ieee128_float_type_node,
-					      "__ieee128");
-    }
-
-  else
-    ieee128_float_type_node = ibm128_float_type_node = long_double_type_node;
-
-  /* Vector pair and vector quad support.  */
-  vector_pair_type_node = make_node (OPAQUE_TYPE);
-  SET_TYPE_MODE (vector_pair_type_node, OOmode);
-  TYPE_SIZE (vector_pair_type_node) = bitsize_int (GET_MODE_BITSIZE (OOmode));
-  TYPE_PRECISION (vector_pair_type_node) = GET_MODE_BITSIZE (OOmode);
-  TYPE_SIZE_UNIT (vector_pair_type_node) = size_int (GET_MODE_SIZE (OOmode));
-  SET_TYPE_ALIGN (vector_pair_type_node, 256);
-  TYPE_USER_ALIGN (vector_pair_type_node) = 0;
-  lang_hooks.types.register_builtin_type (vector_pair_type_node,
-					  "__vector_pair");
-  t = build_qualified_type (vector_pair_type_node, TYPE_QUAL_CONST);
-  ptr_vector_pair_type_node = build_pointer_type (t);
-
-  vector_quad_type_node = make_node (OPAQUE_TYPE);
-  SET_TYPE_MODE (vector_quad_type_node, XOmode);
-  TYPE_SIZE (vector_quad_type_node) = bitsize_int (GET_MODE_BITSIZE (XOmode));
-  TYPE_PRECISION (vector_quad_type_node) = GET_MODE_BITSIZE (XOmode);
-  TYPE_SIZE_UNIT (vector_quad_type_node) = size_int (GET_MODE_SIZE (XOmode));
-  SET_TYPE_ALIGN (vector_quad_type_node, 512);
-  TYPE_USER_ALIGN (vector_quad_type_node) = 0;
-  lang_hooks.types.register_builtin_type (vector_quad_type_node,
-					  "__vector_quad");
-  t = build_qualified_type (vector_quad_type_node, TYPE_QUAL_CONST);
-  ptr_vector_quad_type_node = build_pointer_type (t);
-
-  /* Initialize the modes for builtin_function_type, mapping a machine mode to
-     tree type node.  */
-  builtin_mode_to_type[QImode][0] = integer_type_node;
-  builtin_mode_to_type[QImode][1] = unsigned_intSI_type_node;
-  builtin_mode_to_type[HImode][0] = integer_type_node;
-  builtin_mode_to_type[HImode][1] = unsigned_intSI_type_node;
-  builtin_mode_to_type[SImode][0] = intSI_type_node;
-  builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
-  builtin_mode_to_type[DImode][0] = intDI_type_node;
-  builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
-  builtin_mode_to_type[TImode][0] = intTI_type_node;
-  builtin_mode_to_type[TImode][1] = unsigned_intTI_type_node;
-  builtin_mode_to_type[SFmode][0] = float_type_node;
-  builtin_mode_to_type[DFmode][0] = double_type_node;
-  builtin_mode_to_type[IFmode][0] = ibm128_float_type_node;
-  builtin_mode_to_type[KFmode][0] = ieee128_float_type_node;
-  builtin_mode_to_type[TFmode][0] = long_double_type_node;
-  builtin_mode_to_type[DDmode][0] = dfloat64_type_node;
-  builtin_mode_to_type[TDmode][0] = dfloat128_type_node;
-  builtin_mode_to_type[V1TImode][0] = V1TI_type_node;
-  builtin_mode_to_type[V1TImode][1] = unsigned_V1TI_type_node;
-  builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
-  builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
-  builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
-  builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
-  builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
-  builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
-  builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
-  builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
-  builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
-  builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
-  builtin_mode_to_type[OOmode][1] = vector_pair_type_node;
-  builtin_mode_to_type[XOmode][1] = vector_quad_type_node;
-
-  tdecl = add_builtin_type ("__bool char", bool_char_type_node);
-  TYPE_NAME (bool_char_type_node) = tdecl;
-
-  tdecl = add_builtin_type ("__bool short", bool_short_type_node);
-  TYPE_NAME (bool_short_type_node) = tdecl;
-
-  tdecl = add_builtin_type ("__bool int", bool_int_type_node);
-  TYPE_NAME (bool_int_type_node) = tdecl;
-
-  tdecl = add_builtin_type ("__pixel", pixel_type_node);
-  TYPE_NAME (pixel_type_node) = tdecl;
-
-  bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char",
-					     bool_char_type_node, 16);
-  ptr_bool_V16QI_type_node
-    = build_pointer_type (build_qualified_type (bool_V16QI_type_node,
-						TYPE_QUAL_CONST));
-
-  bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short",
-					    bool_short_type_node, 8);
-  ptr_bool_V8HI_type_node
-    = build_pointer_type (build_qualified_type (bool_V8HI_type_node,
-						TYPE_QUAL_CONST));
-
-  bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int",
-					    bool_int_type_node, 4);
-  ptr_bool_V4SI_type_node
-    = build_pointer_type (build_qualified_type (bool_V4SI_type_node,
-						TYPE_QUAL_CONST));
-
-  bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
-					    ? "__vector __bool long"
-					    : "__vector __bool long long",
-					    bool_long_long_type_node, 2);
-  ptr_bool_V2DI_type_node
-    = build_pointer_type (build_qualified_type (bool_V2DI_type_node,
-						TYPE_QUAL_CONST));
-
-  bool_V1TI_type_node = rs6000_vector_type ("__vector __bool __int128",
-					    intTI_type_node, 1);
-  ptr_bool_V1TI_type_node
-    = build_pointer_type (build_qualified_type (bool_V1TI_type_node,
-						TYPE_QUAL_CONST));
-
-  pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel",
-					     pixel_type_node, 8);
-  ptr_pixel_V8HI_type_node
-    = build_pointer_type (build_qualified_type (pixel_V8HI_type_node,
-						TYPE_QUAL_CONST));
-  pcvoid_type_node
-    = build_pointer_type (build_qualified_type (void_type_node,
-						TYPE_QUAL_CONST));
-
-  /* Execute the autogenerated initialization code for builtins.  */
-  rs6000_init_generated_builtins ();
-
-  if (TARGET_DEBUG_BUILTIN)
-    {
-      fprintf (stderr, "\nAutogenerated built-in functions:\n\n");
-      for (int i = 1; i < (int) RS6000_BIF_MAX; i++)
-	{
-	  bif_enable e = rs6000_builtin_info[i].enable;
-	  if (e == ENB_P5 && !TARGET_POPCNTB)
-	    continue;
-	  if (e == ENB_P6 && !TARGET_CMPB)
-	    continue;
-	  if (e == ENB_P6_64 && !(TARGET_CMPB && TARGET_POWERPC64))
-	    continue;
-	  if (e == ENB_ALTIVEC && !TARGET_ALTIVEC)
-	    continue;
-	  if (e == ENB_VSX && !TARGET_VSX)
-	    continue;
-	  if (e == ENB_P7 && !TARGET_POPCNTD)
-	    continue;
-	  if (e == ENB_P7_64 && !(TARGET_POPCNTD && TARGET_POWERPC64))
-	    continue;
-	  if (e == ENB_P8 && !TARGET_DIRECT_MOVE)
-	    continue;
-	  if (e == ENB_P8V && !TARGET_P8_VECTOR)
-	    continue;
-	  if (e == ENB_P9 && !TARGET_MODULO)
-	    continue;
-	  if (e == ENB_P9_64 && !(TARGET_MODULO && TARGET_POWERPC64))
-	    continue;
-	  if (e == ENB_P9V && !TARGET_P9_VECTOR)
-	    continue;
-	  if (e == ENB_IEEE128_HW && !TARGET_FLOAT128_HW)
-	    continue;
-	  if (e == ENB_DFP && !TARGET_DFP)
-	    continue;
-	  if (e == ENB_CRYPTO && !TARGET_CRYPTO)
-	    continue;
-	  if (e == ENB_HTM && !TARGET_HTM)
-	    continue;
-	  if (e == ENB_P10 && !TARGET_POWER10)
-	    continue;
-	  if (e == ENB_P10_64 && !(TARGET_POWER10 && TARGET_POWERPC64))
-	    continue;
-	  if (e == ENB_MMA && !TARGET_MMA)
-	    continue;
-	  tree fntype = rs6000_builtin_info[i].fntype;
-	  tree t = TREE_TYPE (fntype);
-	  fprintf (stderr, "%s %s (", rs6000_type_string (t),
-		   rs6000_builtin_info[i].bifname);
-	  t = TYPE_ARG_TYPES (fntype);
-	  while (t && TREE_VALUE (t) != void_type_node)
-	    {
-	      fprintf (stderr, "%s",
-		       rs6000_type_string (TREE_VALUE (t)));
-	      t = TREE_CHAIN (t);
-	      if (t && TREE_VALUE (t) != void_type_node)
-		fprintf (stderr, ", ");
-	    }
-	  fprintf (stderr, "); %s [%4d]\n",
-		   rs6000_builtin_info[i].attr_string, (int) i);
-	}
-      fprintf (stderr, "\nEnd autogenerated built-in functions.\n\n\n");
-     }
-
-  if (TARGET_XCOFF)
-    {
-      /* AIX libm provides clog as __clog.  */
-      if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
-	set_user_assembler_name (tdecl, "__clog");
-
-      /* When long double is 64 bit, some long double builtins of libc
-	 functions (like __builtin_frexpl) must call the double version
-	 (frexp) not the long double version (frexpl) that expects a 128 bit
-	 argument.  */
-      if (! TARGET_LONG_DOUBLE_128)
-	{
-	  if ((tdecl = builtin_decl_explicit (BUILT_IN_FMODL)) != NULL_TREE)
-	    set_user_assembler_name (tdecl, "fmod");
-	  if ((tdecl = builtin_decl_explicit (BUILT_IN_FREXPL)) != NULL_TREE)
-	    set_user_assembler_name (tdecl, "frexp");
-	  if ((tdecl = builtin_decl_explicit (BUILT_IN_LDEXPL)) != NULL_TREE)
-	    set_user_assembler_name (tdecl, "ldexp");
-	  if ((tdecl = builtin_decl_explicit (BUILT_IN_MODFL)) != NULL_TREE)
-	    set_user_assembler_name (tdecl, "modf");
-	}
-    }
-
-  altivec_builtin_mask_for_load
-    = rs6000_builtin_decls[RS6000_BIF_MASK_FOR_LOAD];
-
-#ifdef SUBTARGET_INIT_BUILTINS
-  SUBTARGET_INIT_BUILTINS;
-#endif
-
-  return;
-}
-
-tree
-rs6000_builtin_decl (unsigned code, bool /* initialize_p */)
-{
-  rs6000_gen_builtins fcode = (rs6000_gen_builtins) code;
-
-  if (fcode >= RS6000_OVLD_MAX)
-    return error_mark_node;
-
-  return rs6000_builtin_decls[code];
-}
-
 /* Return the internal arg pointer used for function incoming
    arguments.  When -fsplit-stack, the arg pointer is r12 so we need
    to copy it to a pseudo in order for it to be preserved over calls
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index 943f53e38bb..d27e1ec4a60 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -86,6 +86,10 @@
 /* This file should be included last.  */
 #include "target-def.h"
 
+extern tree rs6000_builtin_mask_for_load (void);
+extern tree rs6000_builtin_md_vectorized_function (tree, tree, tree);
+extern tree rs6000_builtin_reciprocal (tree);
+
   /* Set -mabi=ieeelongdouble on some old targets.  In the future, power server
      systems will also set long double to be IEEE 128-bit.  AIX and Darwin
      explicitly redefine TARGET_IEEEQUAD and TARGET_IEEEQUAD_DEFAULT to 0, so
@@ -105,9 +109,6 @@
 #define PCREL_SUPPORTED_BY_OS	0
 #endif
 
-/* Support targetm.vectorize.builtin_mask_for_load.  */
-tree altivec_builtin_mask_for_load;
-
 #ifdef USING_ELFOS_H
 /* Counter for labels which are to be placed in .fixup.  */
 int fixuplabelno = 0;
@@ -172,9 +173,6 @@ enum reg_class rs6000_regno_regclass[FIRST_PSEUDO_REGISTER];
 
 static int dbg_cost_ctrl;
 
-/* Built in types.  */
-tree rs6000_builtin_types[RS6000_BTI_MAX];
-
 /* Flag to say the TOC is initialized */
 int toc_initialized, need_toc_init;
 char toc_label_name[10];
@@ -203,9 +201,6 @@ enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
 /* Describe the alignment of a vector.  */
 int rs6000_vector_align[NUM_MACHINE_MODES];
 
-/* Map selected modes to types for builtins.  */
-tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
-
 /* What modes to automatically generate reciprocal divide estimate (fre) and
    reciprocal sqrt (frsqrte) for.  */
 unsigned char rs6000_recip_bits[MAX_MACHINE_MODE];
@@ -4987,18 +4982,6 @@ rs6000_option_override (void)
 }
 
 \f
-/* Implement targetm.vectorize.builtin_mask_for_load.  */
-static tree
-rs6000_builtin_mask_for_load (void)
-{
-  /* Don't use lvsl/vperm for P8 and similarly efficient machines.  */
-  if ((TARGET_ALTIVEC && !TARGET_VSX)
-      || (TARGET_VSX && !TARGET_EFFICIENT_UNALIGNED_VSX))
-    return altivec_builtin_mask_for_load;
-  else
-    return 0;
-}
-
 /* Implement LOOP_ALIGN. */
 align_flags
 rs6000_loop_align (rtx label)
@@ -5704,119 +5687,6 @@ rs6000_builtin_vectorized_function (unsigned int fn, tree type_out,
   return NULL_TREE;
 }
 
-/* Implement targetm.vectorize.builtin_md_vectorized_function.  */
-
-static tree
-rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
-				       tree type_in)
-{
-  machine_mode in_mode, out_mode;
-  int in_n, out_n;
-
-  if (TARGET_DEBUG_BUILTIN)
-    fprintf (stderr,
-	     "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n",
-	     IDENTIFIER_POINTER (DECL_NAME (fndecl)),
-	     GET_MODE_NAME (TYPE_MODE (type_out)),
-	     GET_MODE_NAME (TYPE_MODE (type_in)));
-
-  /* TODO: Should this be gcc_assert?  */
-  if (TREE_CODE (type_out) != VECTOR_TYPE
-      || TREE_CODE (type_in) != VECTOR_TYPE)
-    return NULL_TREE;
-
-  out_mode = TYPE_MODE (TREE_TYPE (type_out));
-  out_n = TYPE_VECTOR_SUBPARTS (type_out);
-  in_mode = TYPE_MODE (TREE_TYPE (type_in));
-  in_n = TYPE_VECTOR_SUBPARTS (type_in);
-
-  enum rs6000_gen_builtins fn
-    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
-  switch (fn)
-    {
-    case RS6000_BIF_RSQRTF:
-      if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
-	  && out_mode == SFmode && out_n == 4
-	  && in_mode == SFmode && in_n == 4)
-	return rs6000_builtin_decls[RS6000_BIF_VRSQRTFP];
-      break;
-    case RS6000_BIF_RSQRT:
-      if (VECTOR_UNIT_VSX_P (V2DFmode)
-	  && out_mode == DFmode && out_n == 2
-	  && in_mode == DFmode && in_n == 2)
-	return rs6000_builtin_decls[RS6000_BIF_RSQRT_2DF];
-      break;
-    case RS6000_BIF_RECIPF:
-      if (VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)
-	  && out_mode == SFmode && out_n == 4
-	  && in_mode == SFmode && in_n == 4)
-	return rs6000_builtin_decls[RS6000_BIF_VRECIPFP];
-      break;
-    case RS6000_BIF_RECIP:
-      if (VECTOR_UNIT_VSX_P (V2DFmode)
-	  && out_mode == DFmode && out_n == 2
-	  && in_mode == DFmode && in_n == 2)
-	return rs6000_builtin_decls[RS6000_BIF_RECIP_V2DF];
-      break;
-    default:
-      break;
-    }
-
-  machine_mode in_vmode = TYPE_MODE (type_in);
-  machine_mode out_vmode = TYPE_MODE (type_out);
-
-  /* Power10 supported vectorized built-in functions.  */
-  if (TARGET_POWER10
-      && in_vmode == out_vmode
-      && VECTOR_UNIT_ALTIVEC_OR_VSX_P (in_vmode))
-    {
-      machine_mode exp_mode = DImode;
-      machine_mode exp_vmode = V2DImode;
-      enum rs6000_gen_builtins bif;
-      switch (fn)
-	{
-	case RS6000_BIF_DIVWE:
-	case RS6000_BIF_DIVWEU:
-	  exp_mode = SImode;
-	  exp_vmode = V4SImode;
-	  if (fn == RS6000_BIF_DIVWE)
-	    bif = RS6000_BIF_VDIVESW;
-	  else
-	    bif = RS6000_BIF_VDIVEUW;
-	  break;
-	case RS6000_BIF_DIVDE:
-	case RS6000_BIF_DIVDEU:
-	  if (fn == RS6000_BIF_DIVDE)
-	    bif = RS6000_BIF_VDIVESD;
-	  else
-	    bif = RS6000_BIF_VDIVEUD;
-	  break;
-	case RS6000_BIF_CFUGED:
-	  bif = RS6000_BIF_VCFUGED;
-	  break;
-	case RS6000_BIF_CNTLZDM:
-	  bif = RS6000_BIF_VCLZDM;
-	  break;
-	case RS6000_BIF_CNTTZDM:
-	  bif = RS6000_BIF_VCTZDM;
-	  break;
-	case RS6000_BIF_PDEPD:
-	  bif = RS6000_BIF_VPDEPD;
-	  break;
-	case RS6000_BIF_PEXTD:
-	  bif = RS6000_BIF_VPEXTD;
-	  break;
-	default:
-	  return NULL_TREE;
-	}
-
-      if (in_mode == exp_mode && in_vmode == exp_vmode)
-	return rs6000_builtin_decls[bif];
-    }
-
-  return NULL_TREE;
-}
-
 /* Handler for the Mathematical Acceleration Subsystem (mass) interface to a
    library with vectorized intrinsics.  */
 
@@ -22558,31 +22428,6 @@ rs6000_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED,
   return allocno_class;
 }
 
-/* Returns a code for a target-specific builtin that implements
-   reciprocal of the function, or NULL_TREE if not available.  */
-
-static tree
-rs6000_builtin_reciprocal (tree fndecl)
-{
-  switch (DECL_MD_FUNCTION_CODE (fndecl))
-    {
-    case RS6000_BIF_XVSQRTDP:
-      if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
-	return NULL_TREE;
-
-      return rs6000_builtin_decls[RS6000_BIF_RSQRT_2DF];
-
-    case RS6000_BIF_XVSQRTSP:
-      if (!RS6000_RECIP_AUTO_RSQRTE_P (V4SFmode))
-	return NULL_TREE;
-
-      return rs6000_builtin_decls[RS6000_BIF_RSQRT_4SF];
-
-    default:
-      return NULL_TREE;
-    }
-}
-
 /* Load up a constant.  If the mode is a vector mode, splat the value across
    all of the vector elements.  */
 
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 5fdb8f2c82c..17af314416c 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2551,7 +2551,6 @@ enum rs6000_builtin_type_index
 extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
 
 #ifndef USED_FOR_TARGET
-extern GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
 extern GTY(()) tree altivec_builtin_mask_for_load;
 extern GTY(()) section *toc_section;
 
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 90079ced168..28b9cd66745 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -43,6 +43,10 @@ rs6000-logue.o: $(srcdir)/config/rs6000/rs6000-logue.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+rs6000-builtin.o: $(srcdir)/config/rs6000/rs6000-builtin.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 build/rs6000-gen-builtins.o: $(srcdir)/config/rs6000/rs6000-gen-builtins.cc
 build/rbtree.o: $(srcdir)/config/rs6000/rbtree.cc
 
-- 
2.27.0


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

* [PATCH 5/8] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082]
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
                   ` (3 preceding siblings ...)
  2022-01-28 17:50 ` [PATCH 4/8] rs6000: Consolidate target built-ins code Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-02-01 23:01   ` Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 6/8] rs6000: Remove -m[no-]fold-gimple flag [PR103686] Bill Schmidt
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

These built-ins were misimplemented as always having big-endian semantics.

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-18  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	PR target/95082
	* config/rs6000/rs6000-builtin.cc (rs6000_expand_builtin): Handle
	endianness for vclzlsbb and vctzlsbb.
	* config/rs6000/rs6000-builtins.def (VCLZLSBB_V16QI): Change
	default pattern and indicate a different pattern will be used for
	big endian.
	(VCLZLSBB_V4SI): Likewise.
	(VCLZLSBB_V8HI): Likewise.
	(VCTZLSBB_V16QI): Likewise.
	(VCTZLSBB_V4SI): Likewise.
	(VCTZLSBB_V8HI): Likewise.

gcc/testsuite/
	PR target/95082
	* gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c: Restrict to -mbig.
	* gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c: Likewise.
	* gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c: New.
	* gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c: New.
	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c: Restrict to -mbig.
	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c: Likewise.
	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c: New.
	* gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c: New.
---
 gcc/config/rs6000/rs6000-builtin.cc               | 12 ++++++++++++
 gcc/config/rs6000/rs6000-builtins.def             | 12 ++++++------
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c     |  2 +-
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c     |  2 +-
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c     | 15 +++++++++++++++
 .../gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c     | 15 +++++++++++++++
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c     |  2 +-
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c     |  2 +-
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c     | 15 +++++++++++++++
 .../gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c     | 15 +++++++++++++++
 10 files changed, 82 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c
 create mode 100644 gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c

diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 191a6108a5e..163287f2b67 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -3485,6 +3485,18 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
 	icode = CODE_FOR_vsx_store_v8hi;
       else if (fcode == RS6000_BIF_ST_ELEMREV_V16QI)
 	icode = CODE_FOR_vsx_store_v16qi;
+      else if (fcode == RS6000_BIF_VCLZLSBB_V16QI)
+	icode = CODE_FOR_vclzlsbb_v16qi;
+      else if (fcode == RS6000_BIF_VCLZLSBB_V4SI)
+	icode = CODE_FOR_vclzlsbb_v4si;
+      else if (fcode == RS6000_BIF_VCLZLSBB_V8HI)
+	icode = CODE_FOR_vclzlsbb_v8hi;
+      else if (fcode == RS6000_BIF_VCTZLSBB_V16QI)
+	icode = CODE_FOR_vctzlsbb_v16qi;
+      else if (fcode == RS6000_BIF_VCTZLSBB_V4SI)
+	icode = CODE_FOR_vctzlsbb_v4si;
+      else if (fcode == RS6000_BIF_VCTZLSBB_V8HI)
+	icode = CODE_FOR_vctzlsbb_v8hi;
       else
 	gcc_unreachable ();
     }
diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index cfe31c2e7de..2bb997a5279 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -2551,13 +2551,13 @@
     VBPERMD altivec_vbpermd {}
 
   const signed int __builtin_altivec_vclzlsbb_v16qi (vsc);
-    VCLZLSBB_V16QI vclzlsbb_v16qi {}
+    VCLZLSBB_V16QI vctzlsbb_v16qi {endian}
 
   const signed int __builtin_altivec_vclzlsbb_v4si (vsi);
-    VCLZLSBB_V4SI vclzlsbb_v4si {}
+    VCLZLSBB_V4SI vctzlsbb_v4si {endian}
 
   const signed int __builtin_altivec_vclzlsbb_v8hi (vss);
-    VCLZLSBB_V8HI vclzlsbb_v8hi {}
+    VCLZLSBB_V8HI vctzlsbb_v8hi {endian}
 
   const vsc __builtin_altivec_vctzb (vsc);
     VCTZB ctzv16qi2 {}
@@ -2572,13 +2572,13 @@
     VCTZW ctzv4si2 {}
 
   const signed int __builtin_altivec_vctzlsbb_v16qi (vsc);
-    VCTZLSBB_V16QI vctzlsbb_v16qi {}
+    VCTZLSBB_V16QI vclzlsbb_v16qi {endian}
 
   const signed int __builtin_altivec_vctzlsbb_v4si (vsi);
-    VCTZLSBB_V4SI vctzlsbb_v4si {}
+    VCTZLSBB_V4SI vclzlsbb_v4si {endian}
 
   const signed int __builtin_altivec_vctzlsbb_v8hi (vss);
-    VCTZLSBB_V8HI vctzlsbb_v8hi {}
+    VCTZLSBB_V8HI vclzlsbb_v8hi {endian}
 
   const signed int __builtin_altivec_vcmpaeb_p (vsc, vsc);
     VCMPAEB_P vector_ae_v16qi_p {}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c
index 0faf233425e..dc92d6fdd65 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-0.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power9" } */
+/* { dg-options "-mdejagnu-cpu=power9 -mbig" } */
 
 #include <altivec.h>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c
index 201ed17e2fd..6fefb893936 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-1.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power9" } */
+/* { dg-options "-mdejagnu-cpu=power9 -mbig" } */
 
 #include <altivec.h>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c
new file mode 100644
index 00000000000..6ee31a11aee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mlittle" } */
+
+#include <altivec.h>
+
+int
+count_leading_zero_byte_bits (vector signed char *arg1_p)
+{
+  vector signed char arg_1 = *arg1_p;
+
+  return vec_cntlz_lsbb (arg_1);
+}
+
+/* { dg-final { scan-assembler "vctzlsbb" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c
new file mode 100644
index 00000000000..6105091b016
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-4.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mlittle" } */
+
+#include <altivec.h>
+
+int
+count_leading_zero_byte_bits (vector unsigned char *arg1_p)
+{
+  vector unsigned char arg_1 = *arg1_p;
+
+  return vec_cntlz_lsbb (arg_1);
+}
+
+/* { dg-final { scan-assembler "vctzlsbb" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c
index 70a398ac401..68d6c5ff4e8 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-0.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power9" } */
+/* { dg-options "-mdejagnu-cpu=power9 -mbig" } */
 
 #include <altivec.h>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c
index f6d41e3e728..f971ea0a807 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-1.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power9" } */
+/* { dg-options "-mdejagnu-cpu=power9 -mbig" } */
 
 #include <altivec.h>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c
new file mode 100644
index 00000000000..a9245d8200c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-3.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mlittle" } */
+
+#include <altivec.h>
+
+int
+count_trailing_zero_byte_bits (vector signed char *arg1_p)
+{
+  vector signed char arg_1 = *arg1_p;
+
+  return vec_cnttz_lsbb (arg_1);
+}
+
+/* { dg-final { scan-assembler "vclzlsbb" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c
new file mode 100644
index 00000000000..71fea5306c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-4.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mdejagnu-cpu=power9 -mlittle" } */
+
+#include <altivec.h>
+
+int
+count_trailing_zero_byte_bits (vector unsigned char *arg1_p)
+{
+  vector unsigned char arg_1 = *arg1_p;
+
+  return vec_cnttz_lsbb (arg_1);
+}
+
+/* { dg-final { scan-assembler "vclzlsbb" } } */
-- 
2.27.0


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

* [PATCH 6/8] rs6000: Remove -m[no-]fold-gimple flag [PR103686]
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
                   ` (4 preceding siblings ...)
  2022-01-28 17:50 ` [PATCH 5/8] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082] Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-02-02 23:21   ` Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8 Bill Schmidt
  2022-01-28 17:50 ` [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004] Bill Schmidt
  7 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

The -m[no-]fold-gimple flag was really intended primarily for internal
testing while implementing GIMPLE folding for rs6000 vector built-in
functions.  It ended up leaking into other places, causing problems such
as PR103686 identifies.  Let's remove it.

There are a number of tests in the testsuite that require adjustment.
Some specify -mfold-gimple directly, which is the default, so that is
handled by removing the option.  Others unnecessarily specify
-mno-fold-gimple, as the tests work fine without this.  Again that is
handled by removing the option.  There are a couple of extra variants of
tests specifically for -mno-fold-gimple; for those, we can just	remove the
whole test.

gcc.target/powerpc/builtins-1.c was more problematic.  It was written in
such a way as to be extremely fragile.  For this one, I rewrote the whole
test in a different style, using individual functions to test each
built-in function.  These same tests are also largely covered by
builtins-1-be-folded.c and builtins-1-le-folded.c, so I chose to
explicitly make this test -mbig for simplicity, and use -O2 for clean code
generation.  I made some slight modifications to the expected instruction
counts as a result, and tested on both 32- and 64-bit.  Most instruction
count tests now use the {\m ... \M} style, but I wasn't able to figure out
how to get this right for vcmpequd. and vcmpgtud.  Using \. didn't do the
trick, and I got tired of messing with it.  I can change those if you
suggest the proper incantation for an opcode ending with a period.

Bootstrapped and tested on powerpc64le-linux-gnu and on
powerpc64-linux-gnu (32- and 64-bit) with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	PR target/103686
	* config/rs6000/rs6000-builtin.cc (rs6000_gimple_fold_builtin):
	Remove test for !rs6000_fold_gimple.
	* config/rs6000/rs6000.cc (rs6000_option_override_internal):
	Likewise.
	* config/rs6000/rs6000.opt (mfold-gimple): Remove.

gcc/testsuite/
	PR target/103686
	* gcc.target/powerpc/builtins-1-be-folded.c: Remove -mfold-gimple
	option.
	* gcc.target/powerpc/builtins-1-le-folded.c: Likewise.
	* gcc.target/powerpc/builtins-1.c: Rewrite to use small functions
	and restrict to -O2 -mbig for predictability.  Adjust instruction
	counts.
	* gcc.target/powerpc/builtins-5.c: Remove -mno-fold-gimple
	option.
	* gcc.target/powerpc/p8-vec-xl-xst.c: Likewise.
	* gcc.target/powerpc/pr83926.c: Likewise.
	* gcc.target/powerpc/pr86731-nogimplefold-longlong.c: Delete.
	* gcc.target/powerpc/pr86731-nogimplefold.c: Delete.
	* gcc.target/powerpc/swaps-p8-17.c: Remove -mno-fold-gimple
	option.
---
 gcc/config/rs6000/rs6000-builtin.cc           |    3 -
 gcc/config/rs6000/rs6000.cc                   |    4 -
 gcc/config/rs6000/rs6000.opt                  |    4 -
 .../gcc.target/powerpc/builtins-1-be-folded.c |    2 +-
 .../gcc.target/powerpc/builtins-1-le-folded.c |    2 +-
 gcc/testsuite/gcc.target/powerpc/builtins-1.c | 1210 +++++++++++++----
 gcc/testsuite/gcc.target/powerpc/builtins-5.c |    3 +-
 .../gcc.target/powerpc/p8-vec-xl-xst.c        |    3 +-
 gcc/testsuite/gcc.target/powerpc/pr83926.c    |    3 +-
 .../powerpc/pr86731-nogimplefold-longlong.c   |   32 -
 .../gcc.target/powerpc/pr86731-nogimplefold.c |   63 -
 .../gcc.target/powerpc/swaps-p8-17.c          |    3 +-
 12 files changed, 951 insertions(+), 381 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold-longlong.c
 delete mode 100644 gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold.c

diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc
index 163287f2b67..dc9e3a4df1d 100644
--- a/gcc/config/rs6000/rs6000-builtin.cc
+++ b/gcc/config/rs6000/rs6000-builtin.cc
@@ -1299,9 +1299,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       fprintf (stderr, "rs6000_gimple_fold_builtin %d %s %s\n",
 	       fn_code, fn_name1, fn_name2);
 
-  if (!rs6000_fold_gimple)
-    return false;
-
   /* Prevent gimple folding for code that does not have a LHS, unless it is
      allowed per the rs6000_builtin_valid_without_lhs helper function.  */
   if (!gimple_call_lhs (stmt)
diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
index d27e1ec4a60..a4acb5d1f43 100644
--- a/gcc/config/rs6000/rs6000.cc
+++ b/gcc/config/rs6000/rs6000.cc
@@ -3851,10 +3851,6 @@ rs6000_option_override_internal (bool global_init_p)
 	   & OPTION_MASK_DIRECT_MOVE))
     rs6000_isa_flags |= ~rs6000_isa_flags_explicit & OPTION_MASK_STRICT_ALIGN;
 
-  if (!rs6000_fold_gimple)
-     fprintf (stderr,
-	      "gimple folding of rs6000 builtins has been disabled.\n");
-
   /* Add some warnings for VSX.  */
   if (TARGET_VSX)
     {
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index c2a77182a9e..68c0cae6e63 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -155,10 +155,6 @@ maltivec
 Target Mask(ALTIVEC) Var(rs6000_isa_flags)
 Use AltiVec instructions.
 
-mfold-gimple
-Target Var(rs6000_fold_gimple) Init(1)
-Enable early gimple folding of builtins.
-
 mhard-dfp
 Target Mask(DFP) Var(rs6000_isa_flags)
 Use decimal floating point instructions.
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1-be-folded.c b/gcc/testsuite/gcc.target/powerpc/builtins-1-be-folded.c
index 26d10a726e5..3cc487de2ff 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-1-be-folded.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-1-be-folded.c
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { powerpc-*-* } } } */
-/* { dg-options "-mdejagnu-cpu=power8 -O2 -mfold-gimple" } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
 
 /* Based on builtins-1-le.c ; ensure that the power8 builtins are accepted by
    the compiler, at O2 with gimple folding enabled.  */
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1-le-folded.c b/gcc/testsuite/gcc.target/powerpc/builtins-1-le-folded.c
index 55a0c30ac6d..7193cd570b7 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-1-le-folded.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-1-le-folded.c
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { powerpc64le-*-* } } } */
-/* { dg-options "-mdejagnu-cpu=power8 -O2 -mfold-gimple" } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
 
 /* Based on builtins-1-le.c ; ensure that the power8 builtins are accepted by
    the compiler, at O2 with gimple folding enabled.  */
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1.c b/gcc/testsuite/gcc.target/powerpc/builtins-1.c
index 63fbd2e3be1..149f40c7a55 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-1.c
@@ -1,265 +1,953 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target powerpc_p8vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power8 -O0 -mno-fold-gimple -dp" } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2 -mbig" } */
 
 #include <altivec.h>
 
-vector double y = { 2.0, 4.0 };
-vector double z;
-
-int main ()
+vector float
+foo0 (vector float fa, vector float fb)
 {
-  vector float fa = {1.0, 2.0, 3.0, -4.0};
-  vector float fb = {-2.0, -3.0, -4.0, -5.0};
-  vector float fd = vec_and (fa, fb);
-  vector float fc = vec_cpsgn (fa, fb);
-  vector float fe = vec_mergeh (fa, fb);
-  vector float ff = vec_mergel (fa, fb);
+  return vec_and (fa, fb);
+}
 
-  vector double da = {1.0, 2.0};
-  vector double db = {-2.0, -3.0};
-  vector double dz = vec_and (da, db);
+vector float
+foo1 (vector float fa, vector float fb)
+{
+  return vec_cpsgn (fa, fb);
+}
 
-  vector signed int si_a = {1, 2, 3, 4};
-  vector unsigned int ui_a = {1, 2, 3, 4};
+vector float
+foo2 (vector float fa, vector float fb)
+{
+  return vec_mergeh (fa, fb);
+}
 
-  vector long long la = {5L, 14L};
-  vector long long lb = {3L, 86L};
-  vector long long lc = vec_and (la, lb);
-  vector bool long long ld = {0, -1};
-  vector long long le = vec_and (la, ld);
-  vector long long lf = vec_and (ld, lb);
+vector float
+foo3 (vector float fa, vector float fb)
+{
+  return vec_mergel (fa, fb);
+}
 
-  vector unsigned long long ua = {5L, 14L};
-  vector unsigned long long ub = {3L, 86L};
-  vector unsigned long long uc = vec_and (ua, ub);
-  vector bool long long ud = {0, -1};
-  vector unsigned long long ue = vec_and (ua, ud);
-  vector unsigned long long uf = vec_and (ud, ub);
+vector double
+foo4 (vector double da, vector double db)
+{
+  return vec_and (da, db);
+}
 
-  vector long long lg = vec_andc (la, lb);
-  vector long long lh = vec_andc (la, ld);
-  vector long long li = vec_andc (ld, lb);
+vector long long
+foo5 (vector long long la, vector long long lb)
+{
+  return vec_and (la, lb);
+}
 
-  vector unsigned long long ug = vec_andc (ua, ub);
-  vector unsigned long long uh = vec_andc (ua, ud);
-  vector unsigned long long ui = vec_andc (ud, ub);
+vector long long
+foo6 (vector long long la, vector bool long long ld)
+{
+  return vec_and (la, ld);
+}
 
-  vector double de = {1.0, -4.0};
-  vector double df = {-2.0, 5.0};
-  vector double dg = vec_cpsgn (de, df);
-  vector double dzw = vec_mergeh (de, df);
-  vector double dze = vec_mergel (de, df);
+vector long long
+foo7 (vector bool long long ld, vector long long lb)
+{
+  return vec_and (ld, lb);
+}
 
-  vector long long lj = vec_mergeh (la, lb);
-  vector long long lk = vec_mergeh (la, ld);
-  vector long long ll = vec_mergeh (ld, la);
+vector unsigned long long
+foo8 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_and (ua, ub);
+}
 
-  vector unsigned long long uj = vec_mergeh (ua, ub);
-  vector unsigned long long uk = vec_mergeh (ua, ud);
-  vector unsigned long long ul = vec_mergeh (ud, ua);
+vector unsigned long long
+foo9 (vector unsigned long long ua, vector bool long long ud)
+{
+  return vec_and (ua, ud);
+}
 
-  vector pixel pa = {9, 16, 25, 36, 1, 2, 3, 4};
-  vector pixel pb = {25, 36, 1, 2, 45, 3, 4, 99};
-  vector pixel pc = vec_mergeh (pa, pb);
-  vector pixel pd = vec_mergel (pa, pb);
+vector unsigned long long
+foo10 (vector bool long long ud, vector unsigned long long ub)
+{
+  return vec_and (ud, ub);
+}
 
-  vector long long lm = vec_mergel (la, lb);
-  vector long long ln = vec_mergel (la, ld);
-  vector long long lo = vec_mergel (ld, la);
+vector long long
+foo11 (vector long long la, vector long long lb)
+{
+  return vec_andc (la, lb);
+}
 
-  vector unsigned long long um = vec_mergel (ua, ub);
-  vector unsigned long long un = vec_mergel (ua, ud);
-  vector unsigned long long uo = vec_mergel (ud, ua);
+vector long long
+foo12 (vector long long la, vector bool long long ld)
+{
+  return vec_andc (la, ld);
+}
 
-  vector long long lp = vec_nor (la, lb);
-  vector long long lq = vec_nor (la, ld);
-  vector long long lr = vec_nor (ld, la);
+vector long long
+foo13 (vector bool long long ld, vector long long lb)
+{
+  return vec_andc (ld, lb);
+}
 
-  vector unsigned long long up = vec_nor (ua, ub);
-  vector unsigned long long uq = vec_nor (ua, ud);
-  vector unsigned long long ur = vec_nor (ud, ua);
+vector unsigned long long
+foo14 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_andc (ua, ub);
+}
 
-  vector unsigned char ca = {0,4,8,1,5,9,2,6,10,3,7,11,15,12,14,13};
-  vector unsigned char cbb = {5,4,8,3,1,9,2,6,10,3,7,11,15,12,14,13};
+vector unsigned long long
+foo15 (vector unsigned long long ua, vector bool long long ud)
+{
+  return vec_andc (ua, ud);
+}
 
-  vector unsigned char ucba = {5,4,8,3,1,9,2,6,10,3,7,11,15,12,14,13};
-  vector unsigned char ucbb = {5,4,8,3,1,9,2,6,10,3,7,11,15,12,14,13};
-  vector unsigned char ucbc = {5,4,8,3,1,9,2,6,10,3,7,11,15,12,14,13};
+vector unsigned long long
+foo16 (vector bool long long ud, vector unsigned long long ub)
+{
+  return vec_andc (ud, ub);
+}
 
-  vector long long lv = vec_perm (la, lb, ca);
+vector double
+foo17 (vector double de, vector double df)
+{
+  return vec_cpsgn (de, df);
+}
 
-  vector unsigned char  ucm = vec_and (ca, cbb);
-  vector unsigned char  ucn = vec_andc (ca, cbb);
-  vector unsigned char  uco = vec_mergel (ca, cbb);
+vector double
+foo18 (vector double de, vector double df)
+{
+  return vec_mergeh (de, df);
+}
 
-  vector unsigned long long uv = vec_perm (ua, ub, ca);
+vector double
+foo19 (vector double de, vector double df)
+{
+  return vec_mergel (de, df);
+}
 
-  vector long long lx = vec_sel (la, lb, uc);
-  vector long long ly = vec_sel (la, lb, ld);
+vector long long
+foo20 (vector long long la, vector long long lb)
+{
+  return vec_mergeh (la, lb);
+}
 
-  vector unsigned long long uw = vec_sel (ua, ub, lc);
-  vector unsigned long long ux = vec_sel (ua, ub, uc);
-  vector unsigned long long uy = vec_sel (ua, ub, ld);
+vector long long
+foo21 (vector long long la, vector bool long long ld)
+{
+  return vec_mergeh (la, ld);
+}
 
-  vector long long lz = vec_xor (la, lb);
-  vector long long l0 = vec_xor (la, ld);
-  vector long long l1 = vec_xor (ld, la);
+vector long long
+foo22 (vector bool long long ld, vector long long lb)
+{
+  return vec_mergeh (ld, lb);
+}
 
-  vector unsigned long long uz = vec_xor (ua, ub);
-  vector unsigned long long u0 = vec_xor (ua, ud);
-  vector unsigned long long u1 = vec_xor (ud, ua);
+vector unsigned long long
+foo23 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_mergeh (ua, ub);
+}
 
-  int ia = vec_all_eq (ua, ub);
-  int ib = vec_all_ge (ua, ub);
-  int ic = vec_all_gt (ua, ub);
-  int id = vec_all_le (ua, ub);
-  int ie = vec_all_lt (ua, ub);
-  int ig = vec_all_ne (ua, ub);
+vector unsigned long long
+foo24 (vector unsigned long long ua, vector bool long long ud)
+{
+  return vec_mergeh (ua, ud);
+}
 
-  int ih = vec_any_eq (ua, ub);
-  int ii = vec_any_ge (ua, ub);
-  int ij = vec_any_gt (ua, ub);
-  int ik = vec_any_le (ua, ub);
-  int il = vec_any_lt (ua, ub);
-  int im = vec_any_ne (ua, ub);
+vector unsigned long long
+foo25 (vector bool long long ud, vector unsigned long long ub)
+{
+  return vec_mergeh (ud, ub);
+}
 
-  vector short ssa = {9, 16, 25, 36, 1, 2, 3, 4};
-  vector short ssb = {-8, -27, -64, -125, 2, 3, 5, 3};
-  vector short sscc = vec_and (ssa, ssb);
-  vector short sscd = vec_mergeh (ssa, ssb);
-  vector short ssce = vec_mergel (ssa, ssb);
+vector pixel
+foo26 (vector pixel pa, vector pixel pb)
+{
+  return vec_mergeh (pa, pb);
+}
 
-  vector int sia = {9, 16, 25, 36};
-  vector int sib = {-8, -27, -64, -125};
-  vector int sicc = vec_and (sia, sib);
-  vector int sicd = vec_andc (sia, sib);
-  vector int sig = vec_mergel (sia, sib);
+vector pixel
+foo27 (vector pixel pa, vector pixel pb)
+{
+  return vec_mergel (pa, pb);
+}
 
-  vector unsigned int uia = {9, 16, 25, 36};
-  vector unsigned int uib = {8, 27, 64, 125};
-  vector unsigned int uicc = vec_and (uia, uib);
-  vector unsigned int uidd = vec_andc (uia, uib);
-  vector unsigned int uig = vec_mergel (uia, uib);
+vector long long
+foo28 (vector long long la, vector long long lb)
+{
+  return vec_mergel (la, lb);
+}
 
-  vector bool char bca = {0, 1, 4, 7};
-  vector bool char bcb = {-8, 9, 2, 9};
-  vector bool char bcc = vec_and (bca, bcb);
-  vector bool char bcd = vec_andc (bca, bcb);
-  vector bool char bce = vec_mergel (bca, bcb);
+vector long long
+foo29 (vector long long la, vector bool long long ld)
+{
+  return vec_mergel (la, ld);
+}
 
-  vector bool short bsa = {0, -1, -1, 0, 3, 4, 6, 7};
-  vector bool short bsb = {-1, -1, 0, -1, 0, 0, 0, 0};
-  vector bool short bscc = vec_and (bsa, bsb);
-  vector bool short bscd = vec_andc (bsa, bsb);
-  vector bool short bsce = vec_mergel (bsa, bsb);
+vector long long
+foo30 (vector bool long long ld, vector long long lb)
+{
+  return vec_mergel (ld, lb);
+}
 
-  vector bool int bia = {0, -1, -1, 0};
-  vector bool int bib = {-1, -1, 0, -1};
-  vector bool int bicc = vec_and (bia, bib);
-  vector bool int bicd = vec_andc (bia, bib);
-  vector bool int bide = vec_mergel (bia, bib);
+vector unsigned long long
+foo31 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_mergel (ua, ub);
+}
 
-  vector unsigned int uie = vec_packsu (ua, ub);
+vector unsigned long long
+foo32 (vector unsigned long long ua, vector bool long long ud)
+{
+  return vec_mergel (ua, ud);
+}
 
-  vector long long l2 = vec_cntlz (la);
-  vector unsigned long long u2 = vec_cntlz (ua);
-  vector int sie = vec_cntlz (sia);
-  vector unsigned int uif = vec_cntlz (uia);
-  vector short sszz = vec_cntlz (ssa);
+vector unsigned long long
+foo33 (vector bool long long ud, vector unsigned long long ub)
+{
+  return vec_mergel (ud, ub);
+}
 
-  vector unsigned short usa = {81, 72, 63, 54, 45, 36, 27, 18};
-  vector unsigned short usb = {81, 72, 63, 54, 45, 36, 27, 18};
-  vector unsigned short usd = vec_and (usa, usb);
-  vector unsigned short use = vec_andc (usa, usb);
-  vector unsigned short usc = vec_cntlz (usa);
-  vector unsigned short uscd = vec_mergeh (usa, usb);
-  vector unsigned short usce = vec_mergel (usa, usb);
+vector long long
+foo34 (vector long long la, vector long long lb)
+{
+  return vec_nor (la, lb);
+}
 
-  vector signed char sca = {-4, 3, -9, 15, -31, 31, 0, 0,
-		            1, 117, -36, 99, 98, 97, 96, 95};
-  vector signed char scb = vec_cntlz (sca);
-  vector signed char scc = vec_mergel (sca, scb);
+vector long long
+foo35 (vector long long la, vector bool long long ld)
+{
+  return vec_nor (la, ld);
+}
 
-  vector unsigned char uca = {4, 3, 9, 15, 30, 31, 0, 0,
-			      1, 117, 36, 99, 98, 97, 96, 95};
-  vector unsigned char cb = vec_cntlz (ca);
+vector long long
+foo36 (vector bool long long ld, vector long long lb)
+{
+  return vec_nor (ld, lb);
+}
 
-  vector double dd = vec_xl (0, &y);
-  vec_xst (dd, 0, &z);
+vector unsigned long long
+foo37 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_nor (ua, ub);
+}
 
-  vector double dzz = vec_round (dd);
-  vector double dzz1 = vec_rsqrt (dd);
-  vector double dzz2 = vec_rsqrte (dd);
+vector unsigned long long
+foo38 (vector unsigned long long ua, vector bool long long ud)
+{
+  return vec_nor (ua, ud);
+}
 
-  vector float ff1 = vec_round (fa);
-  vector float ff2 = vec_rsqrt (fa);
-  vector float ff3 = vec_rsqrte (fa);
+vector unsigned long long
+foo39 (vector bool long long ud, vector unsigned long long ub)
+{
+  return vec_nor (ud, ub);
+}
 
-  vector double dff = vec_splat (de, 0);
-  vector double dgg = vec_splat (de, 1);
-  vector long long l3 = vec_splat (l2, 0);
-  vector long long l4 = vec_splat (l2, 1);
-  vector unsigned long long u3 = vec_splat (u2, 0);
-  vector unsigned long long u4 = vec_splat (u2, 1);
-  vector bool long long l5 = vec_splat (ld, 0);
-  vector bool long long l6 = vec_splat (ld, 1);
-  vector bool long long l10 = vec_mergee (ld, ld);
-  vector bool long long l11 = vec_mergeo (ld, ld);
-  vector bool long long l15 = vec_and (ld, ld);
-  
-  vector long long l7 = vec_div (l3, l4);
-  vector unsigned long long u5 = vec_div (u3, u4);
-  vector long long l12 = vec_mergee (la, lb);
-  vector long long l13 = vec_mergeo (la, lb);
-  vector unsigned long long u8 = vec_mergee (u3, u4);
-  vector unsigned long long u9 = vec_mergeo (u3, u4);
+vector long long
+foo40 (vector long long la, vector long long lb, vector unsigned char ca)
+{
+  return vec_perm (la, lb, ca);
+}
 
-  vector long long l8 = vec_mul (l3, l4);
-  vector unsigned long long u6 = vec_mul (u3, u4);
+vector unsigned char
+foo41 (vector unsigned char ca, vector unsigned char cbb)
+{
+  return vec_and (ca, cbb);
+}
 
-  vector int sz = vec_cts (fa, 0x1F);
-  vector unsigned int usz = vec_ctu (fa, 0x1F);
+vector unsigned char
+foo42 (vector unsigned char ca, vector unsigned char cbb)
+{
+  return vec_andc (ca, cbb);
+}
 
-  vector float f1 = vec_mergee (fa, fb);
-  vector float f2 = vec_mergeo (fa, fb);
+vector unsigned char
+foo43 (vector unsigned char ca, vector unsigned char cbb)
+{
+  return vec_mergel (ca, cbb);
+}
 
-  vector double d1 = vec_mergee (da, db);
-  vector double d2 = vec_mergeo (da, db);
+vector unsigned long long
+foo44 (vector unsigned long long ua, vector unsigned long long ub,
+       vector unsigned char ca)
+{
+  return vec_perm (ua, ub, ca);
+}
 
-  vector float f3 = vec_ctf (si_a, 1);
-  vector float f4 = vec_ctf (ui_a, 2);
+vector long long
+foo45 (vector long long la, vector long long lb, vector unsigned long long uc)
+{
+  return vec_sel (la, lb, uc);
+}
 
-  vector bool char z_vbc2 = vec_splat (bca, 0);
-  vector signed char z_vsc1 = vec_splat (sca, 1);
-  vector unsigned char z_vuc1 = vec_splat (ucbc, 2);
+vector long long
+foo46 (vector long long la, vector long long lb, vector bool long long ld)
+{
+  return vec_sel (la, lb, ld);
+}
 
-  vector bool int z_vbi1 = vec_splat (bia, 3);
-  vector signed int z_vsi1 = vec_splat (sia, 1);
-  vector unsigned int z_vui1 = vec_splat (uia, 2);
+vector unsigned long long
+foo47 (vector unsigned long long ua, vector unsigned long long ub,
+       vector long long lc)
+{
+  return vec_sel (ua, ub, lc);
+}
 
-  vector bool int z_bi2 = vec_mergee (bia, bib);
-  vector signed int z_si2 = vec_mergee (sia, sib);
-  vector unsigned int z_ui2 = vec_mergee (uia, uib);
-  
-  vector bool char z_bc2 = vec_mergeh (bca, bcb);
-  vector signed char z_sc2 = vec_mergeh (sca, scb);
-  vector bool int z_bi3 = vec_mergeh (bia, bib);
-  vector signed int z_si3 = vec_mergeh (sia, sib);
-  vector unsigned int z_ui3 = vec_mergeh (uia, uib);
-  vector bool short z_bs1 = vec_mergeh (bsa, bsb);
+vector unsigned long long
+foo48 (vector unsigned long long ua, vector unsigned long long ub,
+       vector unsigned long long uc)
+{
+  return vec_sel (ua, ub, uc);
+}
 
-  vector bool int z_bi4 = vec_mergeo (bia, bib);
-  vector signed int z_si4 = vec_mergeo (sia, sib);
-  vector unsigned int z_ui4 = vec_mergeo (uia, uib);
-  
-  vector pixel int z_vp1 = vec_splat (pa, 1);
-  vector bool short z_bs2 = vec_splat (bsa, 0);
-  vector short signed int z_vss1 = vec_splat (ssa, 2);
-  vector unsigned short int z_vuss1 = vec_splat (usa, 1);
+vector unsigned long long
+foo49 (vector unsigned long long ua, vector unsigned long long ub,
+       vector bool long long ld)
+{
+  return vec_sel (ua, ub, ld);
+}
 
-  return 0;
+vector long long
+foo50 (vector long long la, vector long long lb)
+{
+  return vec_xor (la, lb);
+}
+
+vector long long
+foo51 (vector long long la, vector bool long long ld)
+{
+  return vec_xor (la, ld);
+}
+
+vector long long
+foo52 (vector bool long long ld, vector long long la)
+{
+  return vec_xor (ld, la);
+}
+
+vector unsigned long long
+foo53 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_xor (ua, ub);
+}
+
+vector unsigned long long
+foo54 (vector unsigned long long ua, vector bool long long ud)
+{
+  return vec_xor (ua, ud);
+}
+
+vector unsigned long long
+foo55 (vector bool long long ud, vector unsigned long long ua)
+{
+  return vec_xor (ud, ua);
+}
+
+int
+foo56 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_all_eq (ua, ub);
+}
+
+int
+foo57 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_all_ge (ua, ub);
+}
+
+int
+foo58 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_all_gt (ua, ub);
+}
+
+int
+foo59 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_all_le (ua, ub);
+}
+
+int
+foo60 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_all_lt (ua, ub);
+}
+
+int
+foo61 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_all_ne (ua, ub);
+}
+
+int
+foo62 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_any_eq (ua, ub);
+}
+
+int
+foo63 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_any_ge (ua, ub);
+}
+
+int
+foo64 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_any_gt (ua, ub);
+}
+
+int
+foo65 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_any_le (ua, ub);
+}
+
+int
+foo66 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_any_lt (ua, ub);
+}
+
+int
+foo67 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_any_ne (ua, ub);
+}
+
+vector short
+foo68 (vector short ssa, vector short ssb)
+{
+  return vec_and (ssa, ssb);
+}
+
+vector short
+foo69 (vector short ssa, vector short ssb)
+{
+  return vec_mergeh (ssa, ssb);
+}
+
+vector short
+foo70 (vector short ssa, vector short ssb)
+{
+  return vec_mergel (ssa, ssb);
+}
+
+vector int
+foo71 (vector int sia, vector int sib)
+{
+  return vec_and (sia, sib);
+}
+
+vector int
+foo72 (vector int sia, vector int sib)
+{
+  return vec_andc (sia, sib);
+}
+
+vector int
+foo73 (vector int sia, vector int sib)
+{
+  return vec_mergel (sia, sib);
+}
+
+vector unsigned int
+foo74 (vector unsigned int uia, vector unsigned int uib)
+{
+  return vec_and (uia, uib);
+}
+
+vector unsigned int
+foo75 (vector unsigned int uia, vector unsigned int uib)
+{
+  return vec_andc (uia, uib);
+}
+
+vector unsigned int
+foo76 (vector unsigned int uia, vector unsigned int uib)
+{
+  return vec_mergel (uia, uib);
+}
+
+vector bool char
+foo77 (vector bool char bca, vector bool char bcb)
+{
+  return vec_and (bca, bcb);
+}
+
+vector bool char
+foo78 (vector bool char bca, vector bool char bcb)
+{
+  return vec_andc (bca, bcb);
+}
+
+vector bool char
+foo79 (vector bool char bca, vector bool char bcb)
+{
+  return vec_mergel (bca, bcb);
+}
+
+vector bool short
+foo80 (vector bool short bsa, vector bool short bsb)
+{
+  return vec_and (bsa, bsb);
+}
+
+vector bool short
+foo81 (vector bool short bsa, vector bool short bsb)
+{
+  return vec_andc (bsa, bsb);
+}
+
+vector bool short
+foo82 (vector bool short bsa, vector bool short bsb)
+{
+  return vec_mergel (bsa, bsb);
+}
+
+vector bool int
+foo83 (vector bool int bia, vector bool int bib)
+{
+  return vec_and (bia, bib);
+}
+
+vector bool int
+foo84 (vector bool int bia, vector bool int bib)
+{
+  return vec_andc (bia, bib);
+}
+
+vector bool int
+foo85 (vector bool int bia, vector bool int bib)
+{
+  return vec_mergel (bia, bib);
+}
+
+vector unsigned int
+foo86 (vector unsigned long long ua, vector unsigned long long ub)
+{
+  return vec_packsu (ua, ub);
+}
+
+vector long long
+foo87 (vector long long la)
+{
+  return vec_cntlz (la);
+}
+
+vector unsigned long long
+foo88 (vector unsigned long long ua)
+{
+  return vec_cntlz (ua);
+}
+
+vector int
+foo89 (vector int sia)
+{
+  return vec_cntlz (sia);
+}
+
+vector unsigned int
+foo90 (vector unsigned int uia)
+{
+  return vec_cntlz (uia);
+}
+
+vector short
+foo91 (vector short ssa)
+{
+  return vec_cntlz (ssa);
+}
+
+vector unsigned short
+foo92 (vector unsigned short usa, vector unsigned short usb)
+{
+  return vec_and (usa, usb);
+}
+
+vector unsigned short
+foo93 (vector unsigned short usa, vector unsigned short usb)
+{
+  return vec_andc (usa, usb);
+}
+
+vector unsigned short
+foo94 (vector unsigned short usa)
+{
+  return vec_cntlz (usa);
+}
+
+vector unsigned short
+foo95 (vector unsigned short usa, vector unsigned short usb)
+{
+  return vec_mergeh (usa, usb);
+}
+
+vector unsigned short
+foo96 (vector unsigned short usa, vector unsigned short usb)
+{
+  return vec_mergel (usa, usb);
+}
+
+vector signed char
+foo97 (vector signed char sca)
+{
+  return vec_cntlz (sca);
+}
+
+vector signed char
+foo98 (vector signed char sca, vector signed char scb)
+{
+  return vec_mergel (sca, scb);
+}
+
+vector unsigned char
+foo99 (vector unsigned char ca)
+{
+  return vec_cntlz (ca);
+}
+
+vector double
+foo100 (vector double *y)
+{
+  return vec_xl (0, y);
+}
+
+void
+foo101 (vector double dd, vector double *z)
+{
+  vec_xst (dd, 0, z);
+}
+
+vector double
+foo102 (vector double dd)
+{
+  return vec_round (dd);
+}
+
+vector double
+foo103 (vector double dd)
+{
+  return vec_rsqrt (dd);
+}
+
+vector double
+foo104 (vector double dd)
+{
+  return vec_rsqrte (dd);
+}
+
+vector float
+foo105 (vector float fa)
+{
+  return vec_round (fa);
+}
+
+vector float
+foo106 (vector float fa)
+{
+  return vec_rsqrt (fa);
+}
+
+vector float
+foo107 (vector float fa)
+{
+  return vec_rsqrte (fa);
+}
+
+vector double
+foo108 (vector double de)
+{
+  return vec_splat (de, 0);
+}
+
+vector double
+foo109 (vector double de)
+{
+  return vec_splat (de, 1);
+}
+
+vector long long
+foo110 (vector long long l2)
+{
+  return vec_splat (l2, 0);
+}
+
+vector long long
+foo111 (vector long long l2)
+{
+  return vec_splat (l2, 1);
+}
+
+vector unsigned long long
+foo112 (vector unsigned long long u2)
+{
+  return vec_splat (u2, 0);
+}
+
+vector unsigned long long
+foo113 (vector unsigned long long u2)
+{
+  return vec_splat (u2, 1);
+}
+
+vector bool long long
+foo114 (vector bool long long ld)
+{
+  return vec_splat (ld, 0);
+}
+
+vector bool long long
+foo115 (vector bool long long ld)
+{
+  return vec_splat (ld, 1);
+}
+
+vector bool long long
+foo116 (vector bool long long la, vector bool long long lb)
+{
+  return vec_mergee (la, lb);
+}
+
+vector bool long long
+foo117 (vector bool long long la, vector bool long long lb)
+{
+  return vec_mergeo (la, lb);
+}
+
+vector bool long long
+foo118 (vector bool long long la, vector bool long long lb)
+{
+  return vec_and (la, lb);
+}
+
+vector long long
+foo119 (vector long long l3, vector long long l4)
+{
+  return vec_div (l3, l4);
+}
+
+vector unsigned long long
+foo120 (vector unsigned long long u3, vector unsigned long long u4)
+{
+  return vec_div (u3, u4);
+}
+
+vector long long
+foo121 (vector long long la, vector long long lb)
+{
+  return vec_mergee (la, lb);
+}
+
+vector long long
+foo122 (vector long long la, vector long long lb)
+{
+  return vec_mergeo (la, lb);
+}
+
+vector unsigned long long
+foo123 (vector unsigned long long u3, vector unsigned long long u4)
+{
+  return vec_mergee (u3, u4);
+}
+
+vector unsigned long long
+foo124 (vector unsigned long long u3, vector unsigned long long u4)
+{
+  return vec_mergeo (u3, u4);
+}
+
+vector long long
+foo125 (vector long long l3, vector long long l4)
+{
+  return vec_mul (l3, l4);
+}
+
+vector unsigned long long
+foo126 (vector unsigned long long u3, vector unsigned long long u4)
+{
+  return vec_mul (u3, u4);
+}
+
+vector int
+foo127 (vector float fa)
+{
+  return vec_cts (fa, 0x1F);
+}
+
+vector unsigned int
+foo128 (vector float fa)
+{
+  return vec_ctu (fa, 0x1F);
+}
+
+vector float
+foo129 (vector float fa, vector float fb)
+{
+  return vec_mergee (fa, fb);
+}
+
+vector float
+foo130 (vector float fa, vector float fb)
+{
+  return vec_mergeo (fa, fb);
+}
+
+vector double
+foo131 (vector double da, vector double db)
+{
+  return vec_mergee (da, db);
+}
+
+vector double
+foo132 (vector double da, vector double db)
+{
+  return vec_mergeo (da, db);
+}
+
+vector float
+foo133 (vector signed int si_a)
+{
+  return vec_ctf (si_a, 1);
+}
+
+vector float
+foo134 (vector unsigned int ui_a)
+{
+  return vec_ctf (ui_a, 2);
+}
+
+vector bool char
+foo135 (vector bool char bca)
+{
+  return vec_splat (bca, 0);
+}
+
+vector signed char
+foo136 (vector signed char sca)
+{
+  return vec_splat (sca, 1);
+}
+
+vector unsigned char
+foo137 (vector unsigned char ucbc)
+{
+  return vec_splat (ucbc, 2);
+}
+
+vector bool int
+foo138 (vector bool int bia)
+{
+  return vec_splat (bia, 3);
+}
+
+vector signed int
+foo139 (vector signed int sia)
+{
+  return vec_splat (sia, 1);
+}
+
+vector unsigned int
+foo140 (vector unsigned int uia)
+{
+  return vec_splat (uia, 2);
+}
+
+vector bool int
+foo141 (vector bool int bia, vector bool int bib)
+{
+  return vec_mergee (bia, bib);
+}
+
+vector signed int
+foo142 (vector signed int sia, vector signed int sib)
+{
+  return vec_mergee (sia, sib);
+}
+
+vector unsigned int
+foo143 (vector unsigned int uia, vector unsigned int uib)
+{
+  return vec_mergee (uia, uib);
+}
+
+vector bool char
+foo144 (vector bool char bca, vector bool char bcb)
+{
+  return vec_mergeh (bca, bcb);
+}
+
+vector signed char
+foo145 (vector signed char sca, vector signed char scb)
+{
+  return vec_mergeh (sca, scb);
+}
+
+vector bool int
+foo146 (vector bool int bia, vector bool int bib)
+{
+  return vec_mergeh (bia, bib);
+}
+
+vector signed int
+foo147 (vector signed int sia, vector signed int sib)
+{
+  return vec_mergeh (sia, sib);
+}
+
+vector unsigned int
+foo148 (vector unsigned int uia, vector unsigned int uib)
+{
+  return vec_mergeh (uia, uib);
+}
+
+vector bool short
+foo149 (vector bool short bsa, vector bool short bsb)
+{
+  return vec_mergeh (bsa, bsb);
+}
+
+vector bool int
+foo150 (vector bool int bia, vector bool int bib)
+{
+  return vec_mergeo (bia, bib);
+}
+
+vector signed int
+foo151 (vector signed int sia, vector signed int sib)
+{
+  return vec_mergeo (sia, sib);
+}
+
+vector unsigned int
+foo152 (vector unsigned int uia, vector unsigned int uib)
+{
+  return vec_mergeo (uia, uib);
+}
+
+vector pixel
+foo153 (vector pixel pa)
+{
+  return vec_splat (pa, 1);
+}
+
+vector bool short
+foo154 (vector bool short bsa)
+{
+  return vec_splat (bsa, 0);
+}
+
+vector signed short
+foo155 (vector signed short ssa)
+{
+  return vec_splat (ssa, 2);
+}
+
+vector unsigned short
+foo156 (vector unsigned short usa)
+{
+  return vec_splat (usa, 1);
 }
 
 /* Expected results:
@@ -278,13 +966,13 @@ int main ()
    vec_and             xxland
    vec_andc            xxlandc
    vec_cntlz           vclzd, vclzb, vclzw, vclzh
-   vec_cpsgn           xvcpsgnsp           
-   vec_ctf             xvmuldp 
+   vec_cpsgn           xvcpsgnsp, xvcpsgndp
+   vec_ctf             vcfux, vcfsx
    vec_cts             vctsxs
    vec_ctu             vctuxs
-   vec_div             divd, divdu | __divdi3(), __udivdi3()
-   vec_mergel          vmrghb, vmrghh, xxmrghw
-   vec_mergeh          xxmrglw, vmrglh, vmrglb
+   vec_div             divd, divdu | __divdi3, __udivdi3
+   vec_mergel          vmrglb, vmrglh, xxmrglw, xxpermdi
+   vec_mergeh          xxmrghw, vmrghh, vmrghb, xxpermdi
    vec_mul             mulld | mullw, mulhwu
    vec_nor             xxlnor
    vec_packsu          vpkudus
@@ -292,66 +980,58 @@ int main ()
    vec_round           xvrdpi
    vec_sel             xxsel
    vec_xor             xxlxor 
-   vec_rsqrt           xvrsqrtesp
-   vec_rsqrte          xvrsqrtesp
+   vec_rsqrt           xvrsqrtesp, xvrsqrtedp
+   vec_rsqrte          xvrsqrtesp, xvrsqrtedp
    vec_xl              lxvd2x
    vec_xst             stxvd2x
-   vec_splat           xxspltb, xxspltw, vsplth
-   vec_mergee          xxmrgld, vmrgow
-   vec_mergeo          xxmrghd, vmrgew  */
+   vec_splat           xxspltb | vspltb, xxspltw | vspltw, xxsplth | vsplth,
+                       xxpermdi
+   vec_mergee          xxpermdi, vmrgew
+   vec_mergeo          xxpermdi, vmrgow  */
 
-/* { dg-final { scan-assembler-times "vcmpequd" 8 } } */
-/* { dg-final { scan-assembler-times "vcmpgtud" 16 } } */
-/* { dg-final { scan-assembler-times "xxland" 30 } } */
-/* { dg-final { scan-assembler-times "xxlandc" 13 } } */
-/* { dg-final { scan-assembler-times "vclzb" 2 } } */
-/* { dg-final { scan-assembler-times "vclzd" 2 } } */
-/* { dg-final { scan-assembler-times "vclzw" 2 } } */
-/* { dg-final { scan-assembler-times "vclzh" 2 } } */
-/* { dg-final { scan-assembler-times "xvcpsgnsp" 1 } } */
-/* { dg-final { scan-assembler-times "xvcpsgndp" 1 } } */
-/* { dg-final { scan-assembler-times "xvmuldp" 2 } } */
-/* { dg-final { scan-assembler-times "xvcvdpsxds" 0 } } */
-/* { dg-final { scan-assembler-times "vctsxs" 2 } } */
-/* { dg-final { scan-assembler-times "xvcvdpuxds" 0 } } */
-/* { dg-final { scan-assembler-times "vctuxs" 2 } } */
+/* { dg-final { scan-assembler-times "vcmpequd" 4 } } */
+/* { dg-final { scan-assembler-times "vcmpgtud" 8 } } */
+/* { dg-final { scan-assembler-times {\mxxland\M} 17 } } */
+/* { dg-final { scan-assembler-times {\mxxlandc\M} 13 } } */
+/* { dg-final { scan-assembler-times {\mvclzb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvclzd\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvclzw\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvclzh\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxvcpsgnsp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxvcpsgndp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvcfsx\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvcfux\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvctsxs\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvctuxs\M} 1 } } */
 
-/* { dg-final { scan-assembler-times "vmrghb" 4 { target be } } } */
-/* { dg-final { scan-assembler-times "vmrghb" 6 { target le } } } */
-/* { dg-final { scan-assembler-times "vmrghh" 8 } } */
-/* { dg-final { scan-assembler-times "xxmrghw" 4 } } */
-/* { dg-final { scan-assembler-times "xxmrglw" 4 } } */
-/* { dg-final { scan-assembler-times "vmrglh" 8 } } */
-/* { dg-final { scan-assembler-times "xxlnor" 6 } } */
+/* { dg-final { scan-assembler-times {\mvmrghb\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvmrghh\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mxxmrghw\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mxxmrglw\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mvmrglh\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mxxlnor\M} 6 } } */
 /* { dg-final { scan-assembler-times {\mvpkudus\M} 1 } } */
-/* { dg-final { scan-assembler-times "vperm" 4 } } */
-/* { dg-final { scan-assembler-times "xvrdpi" 2 } } */
-/* { dg-final { scan-assembler-times "xxsel" 5 } } */
-/* { dg-final { scan-assembler-times "xxlxor" 6 } } */
-/* { dg-final { scan-assembler-times "divd" 8  { target lp64 } } } */
-/* { dg-final { scan-assembler-times "divdu" 2  { target lp64 } } } */
-/* { dg-final { scan-assembler-times "mulld" 4  { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\mvperm\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxvrdpi\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvrfin\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxxsel\M} 5 } } */
+/* { dg-final { scan-assembler-times {\mxxlxor\M} 6 } } */
+/* { dg-final { scan-assembler-times {\mdivd\M} 2  { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\mdivdu\M} 2  { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\mmulld\M} 4  { target lp64 } } } */
 /* check for .__divdi3 (AIX), __divdi3 (Linux) and ___divdi3 (Darwin) */
 /* { dg-final { scan-assembler-times {\mbl \.?_?__divdi3\M} 2   { target { ilp32 } } } } */
 /* check for both .__udivdi3 (AIX), __udivdi3 (Linux) and ___udivdi3 (Darwin) */
 /* { dg-final { scan-assembler-times {\mbl \.?_?__udivdi3\M} 2  { target { ilp32 } } } } */
-/* { dg-final { scan-assembler-times "mullw" 12  { target ilp32 } } } */
-/* { dg-final { scan-assembler-times "mulhwu" 4  { target ilp32 } } } */
-/* { dg-final { scan-assembler-times "xxmrgld" 0 } } */
-/* { dg-final { scan-assembler-times "xxmrghd" 0 } } */
-/* { dg-final { scan-assembler-times "xvrsqrtesp" 2 } } */
-/* { dg-final { scan-assembler-times "xvrsqrtedp" 2 } } */
-/* { dg-final { scan-assembler-times "xxspltd" 8 } } */
-/* { dg-final { scan-assembler-times "vcfsx" 2 } } */
-/* { dg-final { scan-assembler-times "vcfux" 2 } } */
-/* { dg-final { scan-assembler-times "vspltb" 6 } } */
-/* { dg-final { scan-assembler-times "vspltw" 0 } } */
-/* { dg-final { scan-assembler-times "vmrgow" 8 } } */
-/* { dg-final { scan-assembler-times "vmrglb" 4 { target le } } } */
-/* { dg-final { scan-assembler-times "vmrglb" 6 { target be } } } */
-/* { dg-final { scan-assembler-times "vmrgew" 8 } } */
-/* { dg-final { scan-assembler-times "vsplth" 8 } } */
-/* { dg-final { scan-assembler-times "vcmpequd." 8 } } */
-/* { dg-final { scan-assembler-times "vcmpgtud." 16 } } */
-/* { dg-final { scan-assembler-times "vrfin" 2 } } */
-
+/* { dg-final { scan-assembler-times {\mmullw\M} 12  { target ilp32 } } } */
+/* { dg-final { scan-assembler-times {\mxvrsqrtesp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mxvrsqrtedp\M} 2 } } */
+/* { dg-final { scan-assembler-times {\mvcfsx\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvcfux\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mvspltb|xxspltb\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mvspltw|xxspltw\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mvmrgow\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mvmrglb\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mvmrgew\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mvsplth|xxsplth\M} 4 } } */
+/* { dg-final { scan-assembler-times {\mxxpermdi\M} 44 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-5.c b/gcc/testsuite/gcc.target/powerpc/builtins-5.c
index 9c25329fb1e..c6c7ebf3aef 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-5.c
@@ -1,7 +1,6 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target powerpc_p8vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power8 -O0 -mno-fold-gimple -dp" } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
+/* { dg-options "-mdejagnu-cpu=power8 -O0 -dp" } */
 
 #include <altivec.h>
 
diff --git a/gcc/testsuite/gcc.target/powerpc/p8-vec-xl-xst.c b/gcc/testsuite/gcc.target/powerpc/p8-vec-xl-xst.c
index 75340b09afc..ed31e608296 100644
--- a/gcc/testsuite/gcc.target/powerpc/p8-vec-xl-xst.c
+++ b/gcc/testsuite/gcc.target/powerpc/p8-vec-xl-xst.c
@@ -1,8 +1,7 @@
 /* { dg-do compile { target { le } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
 /* { dg-require-effective-target powerpc_p8vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power8 -O2 -mno-fold-gimple" } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
+/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
 
 /* Verify fix for problem where vec_xl and vec_xst are not recognized
    for the vector char and vector short cases on P8 only.  */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr83926.c b/gcc/testsuite/gcc.target/powerpc/pr83926.c
index 2490e1d48ba..038238d13cf 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr83926.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr83926.c
@@ -1,6 +1,5 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
-/* { dg-options "-O2 -mdejagnu-cpu=power8 -mno-fold-gimple" } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
+/* { dg-options "-O2 -mdejagnu-cpu=power8" } */
 
 __attribute__ ((altivec(vector__))) long long
 sdiv (__attribute__ ((altivec(vector__))) long long a,
diff --git a/gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold-longlong.c b/gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold-longlong.c
deleted file mode 100644
index 2c463120676..00000000000
--- a/gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold-longlong.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* PR86731.  Verify that the rs6000 gimple-folding code handles the
-   left shift operation properly.  This is a testcase variation that
-   explicitly disables gimple folding.  */
-
-/* { dg-do compile } */
-/* { dg-require-effective-target powerpc_p8vector_ok } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-maltivec -O3 -fwrapv -mno-fold-gimple -mpower8-vector " } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
-
-
-#include <altivec.h>
-
-vector unsigned long long splatu4(void)
-{
-        vector unsigned long long mzero = {-1,-1};
-        return (vector unsigned long long) vec_sl(mzero, mzero);
-}
-
-vector signed long long splats4(void)
-{
-        vector unsigned long long mzero = {-1,-1};
-        return (vector signed long long) vec_sl(mzero, mzero);
-}
-
-/* Codegen will consist of splat and shift instructions for most types.
-   Noted variations:  if gimple folding is disabled, or if -fwrapv is not specified, the
-   long long tests will generate a vspltisw+vsld pair, versus generating a lvx.  */
-/* { dg-final { scan-assembler-times {\mvspltis[bhw]\M|\mxxspltib\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mvsl[bhwd]\M} 2 } } */
-/* { dg-final { scan-assembler-times {\mlvx\M} 0 } } */
-
diff --git a/gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold.c b/gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold.c
deleted file mode 100644
index d424b0c488e..00000000000
--- a/gcc/testsuite/gcc.target/powerpc/pr86731-nogimplefold.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* PR86731.  Verify that the rs6000 gimple-folding code handles the
-   left shift operation properly.  This is a testcase variation that
-   explicitly disables gimple folding.  */
-
-/* { dg-do compile } */
-/* { dg-require-effective-target powerpc_altivec_ok } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-maltivec -O3 -fwrapv -mno-fold-gimple" } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
-
-
-#include <altivec.h>
-/* original test as reported.  */
-vector unsigned int splat(void)
-{
-        vector unsigned int mzero = vec_splat_u32(-1);
-        return (vector unsigned int) vec_sl(mzero, mzero);
-}
-
-/* more testcase variations.  */
-vector unsigned char splatu1(void)
-{
-        vector unsigned char mzero = vec_splat_u8(-1);
-        return (vector unsigned char) vec_sl(mzero, mzero);
-}
-
-vector unsigned short splatu2(void)
-{
-        vector unsigned short mzero = vec_splat_u16(-1);
-        return (vector unsigned short) vec_sl(mzero, mzero);
-}
-
-vector unsigned int splatu3(void)
-{
-        vector unsigned int mzero = vec_splat_u32(-1);
-        return (vector unsigned int) vec_sl(mzero, mzero);
-}
-
-vector signed char splats1(void)
-{
-        vector unsigned char mzero = vec_splat_u8(-1);
-        return (vector signed char) vec_sl(mzero, mzero);
-}
-
-vector signed short splats2(void)
-{
-        vector unsigned short mzero = vec_splat_u16(-1);
-        return (vector signed short) vec_sl(mzero, mzero);
-}
-
-vector signed int splats3(void)
-{
-        vector unsigned int mzero = vec_splat_u32(-1);
-        return (vector signed int) vec_sl(mzero, mzero);
-}
-
-/* Codegen will consist of splat and shift instructions for most types.
-   Noted variations:  if gimple folding is disabled, or if -fwrapv is not specified, the
-   long long tests will generate a vspltisw+vsld pair, versus generating a lvx.  */
-/* { dg-final { scan-assembler-times {\mvspltis[bhw]\M|\mxxspltib\M} 7 } } */
-/* { dg-final { scan-assembler-times {\mvsl[bhwd]\M} 7 } } */
-/* { dg-final { scan-assembler-times {\mlvx\M} 0 } } */
-
diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c
index 5edbca46f9f..342ccd64a04 100644
--- a/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c
+++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-17.c
@@ -1,7 +1,6 @@
 /* { dg-do compile { target { le } } } */
 /* { dg-require-effective-target powerpc_p8vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power8 -O1 -mno-fold-gimple" } */
-/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */
+/* { dg-options "-mdejagnu-cpu=power8 -O1" } */
 /* { dg-final { scan-assembler "lxvd2x" } } */
 /* { dg-final { scan-assembler "xxpermdi" } } */
 
-- 
2.27.0


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

* [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
                   ` (5 preceding siblings ...)
  2022-01-28 17:50 ` [PATCH 6/8] rs6000: Remove -m[no-]fold-gimple flag [PR103686] Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-02-07 15:48   ` Bill Schmidt
  2022-03-30 18:04   ` Segher Boessenkool
  2022-01-28 17:50 ` [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004] Bill Schmidt
  7 siblings, 2 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

As the subject states.  Fixing this is accomplished by moving the built-ins
to the correct stanzas, [altivec] and [vsx].

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-builtin.def (NEG_V16QI): Move to [altivec]
	stanza.
	(NEG_V4SF): Likewise.
	(NEG_V4SI): Likewise.
	(NEG_V8HI): Likewise.
	(NEG_V2DF): Move to [vsx] stanza.
	(NEG_V2DI): Likewise.
---
 gcc/config/rs6000/rs6000-builtins.def | 36 +++++++++++++--------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index 2bb997a5279..c8f0cf332eb 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -410,6 +410,18 @@
   const vss __builtin_altivec_nabs_v8hi (vss);
     NABS_V8HI nabsv8hi2 {}
 
+  const vsc __builtin_altivec_neg_v16qi (vsc);
+    NEG_V16QI negv16qi2 {}
+
+  const vf __builtin_altivec_neg_v4sf (vf);
+    NEG_V4SF negv4sf2 {}
+
+  const vsi __builtin_altivec_neg_v4si (vsi);
+    NEG_V4SI negv4si2 {}
+
+  const vss __builtin_altivec_neg_v8hi (vss);
+    NEG_V8HI negv8hi2 {}
+
   void __builtin_altivec_stvebx (vsc, signed long, void *);
     STVEBX altivec_stvebx {stvec}
 
@@ -1175,6 +1187,12 @@
   const vsll __builtin_altivec_nabs_v2di (vsll);
     NABS_V2DI nabsv2di2 {}
 
+  const vd __builtin_altivec_neg_v2df (vd);
+    NEG_V2DF negv2df2 {}
+
+  const vsll __builtin_altivec_neg_v2di (vsll);
+    NEG_V2DI negv2di2 {}
+
   void __builtin_altivec_stvx_v2df (vd, signed long, void *);
     STVX_V2DF altivec_stvx_v2df {stvec}
 
@@ -2118,24 +2136,6 @@
   const vus __builtin_altivec_nand_v8hi_uns (vus, vus);
     NAND_V8HI_UNS nandv8hi3 {}
 
-  const vsc __builtin_altivec_neg_v16qi (vsc);
-    NEG_V16QI negv16qi2 {}
-
-  const vd __builtin_altivec_neg_v2df (vd);
-    NEG_V2DF negv2df2 {}
-
-  const vsll __builtin_altivec_neg_v2di (vsll);
-    NEG_V2DI negv2di2 {}
-
-  const vf __builtin_altivec_neg_v4sf (vf);
-    NEG_V4SF negv4sf2 {}
-
-  const vsi __builtin_altivec_neg_v4si (vsi);
-    NEG_V4SI negv4si2 {}
-
-  const vss __builtin_altivec_neg_v8hi (vss);
-    NEG_V8HI negv8hi2 {}
-
   const vsc __builtin_altivec_orc_v16qi (vsc, vsc);
     ORC_V16QI orcv16qi3 {}
 
-- 
2.27.0


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

* [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]
  2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
                   ` (6 preceding siblings ...)
  2022-01-28 17:50 ` [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8 Bill Schmidt
@ 2022-01-28 17:50 ` Bill Schmidt
  2022-03-15 13:18   ` rs6000 patch ping: " Jakub Jelinek
  2022-03-30 17:41   ` will schmidt
  7 siblings, 2 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 17:50 UTC (permalink / raw)
  To: gcc-patches; +Cc: segher, dje.gcc

PR104004 caught some misses on my part in converting to the new built-in
function infrastructure.  In particular, I forgot to mark all of the "nosoft"
built-ins, and one of those should also have been marked "no32bit".

Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
Is this okay for trunk?

Thanks,
Bill


2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-builtin.def (MFFSL): Mark nosoft.
	(MTFSB0): Likewise.
	(MTFSB1): Likewise.
	(SET_FPSCR_RN): Likewise.
	(SET_FPSCR_DRN): Mark nosoft and no32bit.
---
 gcc/config/rs6000/rs6000-builtins.def | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
index c8f0cf332eb..98619a649e3 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -215,7 +215,7 @@
 ; processors, this builtin automatically falls back to mffs on older
 ; platforms.  Thus it appears here in the [always] stanza.
   double __builtin_mffsl ();
-    MFFSL rs6000_mffsl {}
+    MFFSL rs6000_mffsl {nosoft}
 
 ; This is redundant with __builtin_pack_ibm128, as it requires long
 ; double to be __ibm128.  Should probably be deprecated.
@@ -226,10 +226,10 @@
     MFTB rs6000_mftb_di {32bit}
 
   void __builtin_mtfsb0 (const int<0,31>);
-    MTFSB0 rs6000_mtfsb0 {}
+    MTFSB0 rs6000_mtfsb0 {nosoft}
 
   void __builtin_mtfsb1 (const int<0,31>);
-    MTFSB1 rs6000_mtfsb1 {}
+    MTFSB1 rs6000_mtfsb1 {nosoft}
 
   void __builtin_mtfsf (const int<0,255>, double);
     MTFSF rs6000_mtfsf {}
@@ -238,7 +238,7 @@
     PACK_IF packif {}
 
   void __builtin_set_fpscr_rn (const int[0,3]);
-    SET_FPSCR_RN rs6000_set_fpscr_rn {}
+    SET_FPSCR_RN rs6000_set_fpscr_rn {nosoft}
 
   const double __builtin_unpack_ibm128 (__ibm128, const int<0,1>);
     UNPACK_IF unpackif {}
@@ -2969,7 +2969,7 @@
     PACK_TD packtd {}
 
   void __builtin_set_fpscr_drn (const int[0,7]);
-    SET_FPSCR_DRN rs6000_set_fpscr_drn {}
+    SET_FPSCR_DRN rs6000_set_fpscr_drn {nosoft,no32bit}
 
   const unsigned long long __builtin_unpack_dec128 (_Decimal128, \
                                                     const int<0,1>);
-- 
2.27.0


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

* Re: [PATCH 1/8] rs6000: More factoring of overload processing
  2022-01-28 17:50 ` [PATCH 1/8] rs6000: More factoring of overload processing Bill Schmidt
@ 2022-01-28 19:11   ` Segher Boessenkool
  2022-01-28 21:19     ` Bill Schmidt
  2022-02-01 14:49     ` [PATCH v2 " Bill Schmidt
  0 siblings, 2 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-28 19:11 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 11:50:19AM -0600, Bill Schmidt wrote:
> This patch continues the refactoring started with r12-6014.

ab3f5b71dc6e

> +     and the generic code will issue the appropriate error message.  Skip
> +     this test for functions where we don't fully describe all the possible
> +     overload signatures in rs6000-overload.def (because they aren't relevant
> +     to the expansion here).  If we don't, we get confusing error messages.  */
> +  if (fcode != RS6000_OVLD_VEC_PROMOTE
> +      && fcode != RS6000_OVLD_VEC_SPLATS
> +      && fcode != RS6000_OVLD_VEC_EXTRACT
> +      && fcode != RS6000_OVLD_VEC_INSERT
> +      && fcode != RS6000_OVLD_VEC_STEP
> +      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
>      return NULL;

Can you expand a bit on this, give an example for example?  It is very
hard to understand this code, the way it depends on code following many
lines later.

> +    default:
> +      ;

Don't.

I like this better than a BS break statement, but it is just as stupid.

If you need this, you don't want a switch statement, but some number of
if statements.  You cannot use a switch as a shorthand for this because
we have a silly warning and -Werror for this use.

You probably get easier to understand code that way, too, you can get
rid of the above (just do some early returns), etc.


Segher

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

* Re: [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names
  2022-01-28 17:50 ` [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names Bill Schmidt
@ 2022-01-28 20:32   ` Segher Boessenkool
  2022-01-28 21:21     ` Bill Schmidt
  0 siblings, 1 reply; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-28 20:32 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 11:50:20AM -0600, Bill Schmidt wrote:
> It was recently pointed out that we get anomalous behavior when using
> __attribute__((target)) to select a CPU.  As an example, when building for
> -mcpu=power8 but using __attribute__((target("mcpu=power10")), it is legal
> to call __builtin_vec_mod, but not vec_mod, even though these are
> equivalent.  This is because the equivalence is established with a #define
> that is guarded by #ifdef _ARCH_PWR10.

Yeah that is bad.

> This goofy behavior occurs with both the old builtins support and the
> new.  One of the goals of the new builtins support was to make sure all
> appropriate interfaces are available using __attribute__((target)), so I
> failed in this respect.  This patch corrects the problem by removing the
> apply.  For example, #ifdef __PPU__ is still appropriate.

"By removing the apply"...  What does that mean?

Nice cleanup (and nice bugfix of course).  Okay for trunk (with that
comment improved a bit perhaps).  Thanks!


Segher

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

* Re: [PATCH 1/8] rs6000: More factoring of overload processing
  2022-01-28 19:11   ` Segher Boessenkool
@ 2022-01-28 21:19     ` Bill Schmidt
  2022-01-28 23:09       ` Segher Boessenkool
  2022-02-01 14:49     ` [PATCH v2 " Bill Schmidt
  1 sibling, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 21:19 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc


On 1/28/22 1:11 PM, Segher Boessenkool wrote:
> On Fri, Jan 28, 2022 at 11:50:19AM -0600, Bill Schmidt wrote:
>> This patch continues the refactoring started with r12-6014.
> ab3f5b71dc6e
>
>> +     and the generic code will issue the appropriate error message.  Skip
>> +     this test for functions where we don't fully describe all the possible
>> +     overload signatures in rs6000-overload.def (because they aren't relevant
>> +     to the expansion here).  If we don't, we get confusing error messages.  */
>> +  if (fcode != RS6000_OVLD_VEC_PROMOTE
>> +      && fcode != RS6000_OVLD_VEC_SPLATS
>> +      && fcode != RS6000_OVLD_VEC_EXTRACT
>> +      && fcode != RS6000_OVLD_VEC_INSERT
>> +      && fcode != RS6000_OVLD_VEC_STEP
>> +      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
>>      return NULL;
> Can you expand a bit on this, give an example for example?  It is very
> hard to understand this code, the way it depends on code following many
> lines later.

Sure, sorry.

This check gives up if the number of arguments doesn't match the prototype.
It gives a fairly generic error message.  That part of it has always been
in here.

Now, I moved this check forward relative to the big switch statement on
fcode, because there are redundant checks for the number of arguments
in each of the resolve_vec_* helper functions.  This allowed me to simplify
those a bit.

Now, it turns out that this doesn't work so well for functions that aren't
fully described in rs6000-overload.def.  For example, for vec_splats we
have:

; There are no actual builtins for vec_splats.  There is special handling for
; this in altivec_resolve_overloaded_builtin in rs6000-c.cc, where the call
; is replaced by a constructor.  The single overload here causes
; __builtin_vec_splats to be registered with the front end so that can happen.
[VEC_SPLATS, vec_splats, __builtin_vec_splats]
  vsi __builtin_vec_splats (vsi);
    ABS_V4SI SPLATS_FAKERY

So even though __builtin_vec_splats accepts all vector types, the
infrastructure cheats and just records one prototype.  We end up getting
an error message that refers to this specific prototype even when we are
handling a different argument type.  That is completely confusing to the
user.  So I felt I was starting to get too deep for a simple refactoring
patch, and gave up on early number-of-arguments checking for the special
cases that use the _FAKERY technique.

That's probably still not clear, but maybe clearer?

>
>> +    default:
>> +      ;
> Don't.
>
> I like this better than a BS break statement, but it is just as stupid.
>
> If you need this, you don't want a switch statement, but some number of
> if statements.  You cannot use a switch as a shorthand for this because
> we have a silly warning and -Werror for this use.
>
> You probably get easier to understand code that way, too, you can get
> rid of the above (just do some early returns), etc.

If I understand correctly, you'd like me to resubmit this in if-then-else
form.  That's fine, just want to be sure that's what you want.

Thanks for the review!
Bill

>
>
> Segher

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

* Re: [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names
  2022-01-28 20:32   ` Segher Boessenkool
@ 2022-01-28 21:21     ` Bill Schmidt
  0 siblings, 0 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-01-28 21:21 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc


On 1/28/22 2:32 PM, Segher Boessenkool wrote:
> On Fri, Jan 28, 2022 at 11:50:20AM -0600, Bill Schmidt wrote:
>> It was recently pointed out that we get anomalous behavior when using
>> __attribute__((target)) to select a CPU.  As an example, when building for
>> -mcpu=power8 but using __attribute__((target("mcpu=power10")), it is legal
>> to call __builtin_vec_mod, but not vec_mod, even though these are
>> equivalent.  This is because the equivalence is established with a #define
>> that is guarded by #ifdef _ARCH_PWR10.
> Yeah that is bad.
>
>> This goofy behavior occurs with both the old builtins support and the
>> new.  One of the goals of the new builtins support was to make sure all
>> appropriate interfaces are available using __attribute__((target)), so I
>> failed in this respect.  This patch corrects the problem by removing the
>> apply.  For example, #ifdef __PPU__ is still appropriate.
> "By removing the apply"...  What does that mean?

Er, wow.  Meant to say "by removing the #define."  Strange error... will fix.

Thanks for catching that!
Bill

>
> Nice cleanup (and nice bugfix of course).  Okay for trunk (with that
> comment improved a bit perhaps).  Thanks!
>
>
> Segher

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

* Re: [PATCH 1/8] rs6000: More factoring of overload processing
  2022-01-28 21:19     ` Bill Schmidt
@ 2022-01-28 23:09       ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-28 23:09 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 03:19:48PM -0600, Bill Schmidt wrote:
> On 1/28/22 1:11 PM, Segher Boessenkool wrote:
> > On Fri, Jan 28, 2022 at 11:50:19AM -0600, Bill Schmidt wrote:
> >> +     and the generic code will issue the appropriate error message.  Skip
> >> +     this test for functions where we don't fully describe all the possible
> >> +     overload signatures in rs6000-overload.def (because they aren't relevant
> >> +     to the expansion here).  If we don't, we get confusing error messages.  */
> >> +  if (fcode != RS6000_OVLD_VEC_PROMOTE
> >> +      && fcode != RS6000_OVLD_VEC_SPLATS
> >> +      && fcode != RS6000_OVLD_VEC_EXTRACT
> >> +      && fcode != RS6000_OVLD_VEC_INSERT
> >> +      && fcode != RS6000_OVLD_VEC_STEP
> >> +      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
> >>      return NULL;
> > Can you expand a bit on this, give an example for example?  It is very
> > hard to understand this code, the way it depends on code following many
> > lines later.
> 
> Sure, sorry.
> 
> This check gives up if the number of arguments doesn't match the prototype.
> It gives a fairly generic error message.  That part of it has always been
> in here.
> 
> Now, I moved this check forward relative to the big switch statement on
> fcode, because there are redundant checks for the number of arguments
> in each of the resolve_vec_* helper functions.  This allowed me to simplify
> those a bit.
> 
> Now, it turns out that this doesn't work so well for functions that aren't
> fully described in rs6000-overload.def.  For example, for vec_splats we
> have:
> 
> ; There are no actual builtins for vec_splats.  There is special handling for
> ; this in altivec_resolve_overloaded_builtin in rs6000-c.cc, where the call
> ; is replaced by a constructor.  The single overload here causes
> ; __builtin_vec_splats to be registered with the front end so that can happen.
> [VEC_SPLATS, vec_splats, __builtin_vec_splats]
>   vsi __builtin_vec_splats (vsi);
>     ABS_V4SI SPLATS_FAKERY
> 
> So even though __builtin_vec_splats accepts all vector types, the
> infrastructure cheats and just records one prototype.  We end up getting
> an error message that refers to this specific prototype even when we are
> handling a different argument type.  That is completely confusing to the
> user.  So I felt I was starting to get too deep for a simple refactoring
> patch, and gave up on early number-of-arguments checking for the special
> cases that use the _FAKERY technique.
> 
> That's probably still not clear, but maybe clearer?

Much better, thanks!

So put a comment before the code handling the arg checking for
vec_splats etc. saying just that?  Or the much condensed form "these
codes should be handled separately because <bla>" :-)  (And the larger
explanation in the commit message -- there you can talk about the old
code / old situation as well :-) )

> >> +    default:
> >> +      ;
> > Don't.
> >
> > I like this better than a BS break statement, but it is just as stupid.
> >
> > If you need this, you don't want a switch statement, but some number of
> > if statements.  You cannot use a switch as a shorthand for this because
> > we have a silly warning and -Werror for this use.
> >
> > You probably get easier to understand code that way, too, you can get
> > rid of the above (just do some early returns), etc.
> 
> If I understand correctly, you'd like me to resubmit this in if-then-else
> form.  That's fine, just want to be sure that's what you want.

Yes please.  This is new code, so let's please keep it as readable as
possible.  Since you need to redo some of it anyway as well...


Segher

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

* Re: [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form
  2022-01-28 17:50 ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
@ 2022-01-28 23:24   ` Segher Boessenkool
  2022-01-31 17:21     ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
  0 siblings, 1 reply; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-28 23:24 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 11:50:21AM -0600, Bill Schmidt wrote:
> When introducing the new built-in support, I tried to match as many
> existing error messages as possible.  One common form was "argument X must
> be a Y-bit unsigned literal".  Another was "argument X must be a literal
> between X' and  Y', inclusive".  During reviews, Segher requested that I
> eventually convert all messages of the first form into the second form for
> consistency.  That's what this patch does, replacing all <x>-form
> constraints (first form) with <x,y>-form constraints (second form).

Well, I asked for the error messages to be clearer and more consistent
like that.  I don't think changing our source code like this is an
improvement (*we* know what a 5-bit signed number is).  Do you think
after your patch it is clearer and we will make fewer errors?


Segher

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

* Re: [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form
  2022-01-28 23:24   ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
@ 2022-01-31 17:21     ` Bill Schmidt
  2022-01-31 17:28       ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
  0 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-31 17:21 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

On 1/28/22 5:24 PM, Segher Boessenkool wrote:
> On Fri, Jan 28, 2022 at 11:50:21AM -0600, Bill Schmidt wrote:
>> When introducing the new built-in support, I tried to match as many
>> existing error messages as possible.  One common form was "argument X must
>> be a Y-bit unsigned literal".  Another was "argument X must be a literal
>> between X' and  Y', inclusive".  During reviews, Segher requested that I
>> eventually convert all messages of the first form into the second form for
>> consistency.  That's what this patch does, replacing all <x>-form
>> constraints (first form) with <x,y>-form constraints (second form).
> Well, I asked for the error messages to be clearer and more consistent
> like that.  I don't think changing our source code like this is an
> improvement (*we* know what a 5-bit signed number is).  Do you think
> after your patch it is clearer and we will make fewer errors?

No, I don't think the patch is a particular improvement.  It sounds like
I may have misinterpreted what you were looking for here.  Please let me
know what I might do differently.

For example, if we leave the <x> format in place in the source, I could
change the error messages that we produce to calculate the minimum and
maximum allowed values.  Then we'd still have the changes to the test
cases, but fewer changes to the source.  Thoughts?

Thanks,
Bill

>
> Segher

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

* Re: [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form
  2022-01-31 17:21     ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
@ 2022-01-31 17:28       ` Segher Boessenkool
  2022-01-31 17:31         ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
  2022-02-01 14:53         ` [PATCH v2 3/8] rs6000: Unify error messages for built-in constant restrictions Bill Schmidt
  0 siblings, 2 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-31 17:28 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Mon, Jan 31, 2022 at 11:21:32AM -0600, Bill Schmidt wrote:
> On 1/28/22 5:24 PM, Segher Boessenkool wrote:
> > On Fri, Jan 28, 2022 at 11:50:21AM -0600, Bill Schmidt wrote:
> >> When introducing the new built-in support, I tried to match as many
> >> existing error messages as possible.  One common form was "argument X must
> >> be a Y-bit unsigned literal".  Another was "argument X must be a literal
> >> between X' and  Y', inclusive".  During reviews, Segher requested that I
> >> eventually convert all messages of the first form into the second form for
> >> consistency.  That's what this patch does, replacing all <x>-form
> >> constraints (first form) with <x,y>-form constraints (second form).
> > Well, I asked for the error messages to be clearer and more consistent
> > like that.  I don't think changing our source code like this is an
> > improvement (*we* know what a 5-bit signed number is).  Do you think
> > after your patch it is clearer and we will make fewer errors?
> 
> No, I don't think the patch is a particular improvement.  It sounds like
> I may have misinterpreted what you were looking for here.  Please let me
> know what I might do differently.
> 
> For example, if we leave the <x> format in place in the source, I could
> change the error messages that we produce to calculate the minimum and
> maximum allowed values.  Then we'd still have the changes to the test
> cases, but fewer changes to the source.  Thoughts?

That is exactly what I asked for, and what I still think is the best
option.  I haven't tried it out though, so there may be arguments
against this :-)


Segher

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

* Re: [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form
  2022-01-31 17:28       ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
@ 2022-01-31 17:31         ` Bill Schmidt
  2022-02-01 14:53         ` [PATCH v2 3/8] rs6000: Unify error messages for built-in constant restrictions Bill Schmidt
  1 sibling, 0 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-01-31 17:31 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

On 1/31/22 11:28 AM, Segher Boessenkool wrote:
> On Mon, Jan 31, 2022 at 11:21:32AM -0600, Bill Schmidt wrote:
>> On 1/28/22 5:24 PM, Segher Boessenkool wrote:
>>> On Fri, Jan 28, 2022 at 11:50:21AM -0600, Bill Schmidt wrote:
>>>> When introducing the new built-in support, I tried to match as many
>>>> existing error messages as possible.  One common form was "argument X must
>>>> be a Y-bit unsigned literal".  Another was "argument X must be a literal
>>>> between X' and  Y', inclusive".  During reviews, Segher requested that I
>>>> eventually convert all messages of the first form into the second form for
>>>> consistency.  That's what this patch does, replacing all <x>-form
>>>> constraints (first form) with <x,y>-form constraints (second form).
>>> Well, I asked for the error messages to be clearer and more consistent
>>> like that.  I don't think changing our source code like this is an
>>> improvement (*we* know what a 5-bit signed number is).  Do you think
>>> after your patch it is clearer and we will make fewer errors?
>> No, I don't think the patch is a particular improvement.  It sounds like
>> I may have misinterpreted what you were looking for here.  Please let me
>> know what I might do differently.
>>
>> For example, if we leave the <x> format in place in the source, I could
>> change the error messages that we produce to calculate the minimum and
>> maximum allowed values.  Then we'd still have the changes to the test
>> cases, but fewer changes to the source.  Thoughts?
> That is exactly what I asked for, and what I still think is the best
> option.  I haven't tried it out though, so there may be arguments
> against this :-)

Thanks for the clarification!  I'll make a run at it.

Bill

>
> Segher

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

* Re: [PATCH 4/8] rs6000: Consolidate target built-ins code
  2022-01-28 17:50 ` [PATCH 4/8] rs6000: Consolidate target built-ins code Bill Schmidt
@ 2022-01-31 21:32   ` Segher Boessenkool
  2022-01-31 22:01     ` Bill Schmidt
  0 siblings, 1 reply; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-31 21:32 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

Hi!

On Fri, Jan 28, 2022 at 11:50:22AM -0600, Bill Schmidt wrote:
> Continuing with the refactoring effort, this patch moves as much of the
> target-specific built-in support code into a new file, rs6000-builtin.cc.
> However, we can't easily move the overloading support code out of
> rs6000-c.cc, because the build machinery understands that as a special file
> to be included with the C and C++ front ends.

And the other C-like frontends.

> This patch is just a straightforward move, with one exception.  I found
> that the builtin_mode_to_type[] array is no longer used, so I also removed
> all code having to do with it.

Oh nice, your rewrite removed the need for that array.  Great :-)

> The code in rs6000-builtin.cc is organized in related sections:
>  - General support functions
>  - Initialization support
>  - GIMPLE folding support
>  - Expansion support
> 
> Overloading support remains in rs6000-c.cc.

So, what is needed to move that as well?  Is moving that in the plan?

> 	* config/rs6000/rs6000-builtin.cc: New file, containing code moved
> 	from other files.

(You're breaking lines early again.)

> -	extra_objs="${extra_objs} rs6000-builtins.o"
> +	extra_objs="${extra_objs} rs6000-builtins.o rs6000-builtin.o"

It's pretty unfortunate that these files are named alike.  The source
files exist in different places of course, so the danger of confusion
is minimal usually.

> +/* Support targetm.vectorize.builtin_mask_for_load.  */
> +tree altivec_builtin_mask_for_load;

"Support"?  What does that mean?  Please describe what this tree is.

> +/* **** General support functions. **** */

This isn't a sentence so should not have a full stop.  (And otherwise
it should be followed by two spaces!)

> +bool
> +rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
> +{
> +  switch (rs6000_builtin_info[(size_t) fncode].enable)
> +    {
> +    case ENB_ALWAYS:
> +      return true;
> +    case ENB_P5:
> +      return TARGET_POPCNTB;
> +    case ENB_P6:
> +      return TARGET_CMPB;
> +    case ENB_P6_64:
> +      return TARGET_CMPB && TARGET_POWERPC64;
> +    case ENB_P7:
> +      return TARGET_POPCNTD;
> +    case ENB_P7_64:
> +      return TARGET_POPCNTD && TARGET_POWERPC64;
> +    case ENB_P8:
> +      return TARGET_DIRECT_MOVE;
> +    case ENB_P8V:
> +      return TARGET_P8_VECTOR;
> +    case ENB_P9:
> +      return TARGET_MODULO;
> +    case ENB_P9_64:
> +      return TARGET_MODULO && TARGET_POWERPC64;
> +    case ENB_P9V:
> +      return TARGET_P9_VECTOR;
> +    case ENB_P10:
> +      return TARGET_POWER10;
> +    case ENB_P10_64:
> +      return TARGET_POWER10 && TARGET_POWERPC64;
> +    case ENB_ALTIVEC:
> +      return TARGET_ALTIVEC;
> +    case ENB_VSX:
> +      return TARGET_VSX;
> +    case ENB_CELL:
> +      return TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL;
> +    case ENB_IEEE128_HW:
> +      return TARGET_FLOAT128_HW;
> +    case ENB_DFP:
> +      return TARGET_DFP;
> +    case ENB_CRYPTO:
> +      return TARGET_CRYPTO;
> +    case ENB_HTM:
> +      return TARGET_HTM;
> +    case ENB_MMA:
> +      return TARGET_MMA;
> +    default:
> +      gcc_unreachable ();
> +    }
> +  gcc_unreachable ();
> +}

If you rewrite this without switch it is shorter and clearer, and you do
not need to duplicate the gcc_unreachable (which the broken warning
forces you to).

> +  if (fcode >= RS6000_OVLD_MAX)
> +    return error_mark_node;

This shows that that isn't really the max, it is the number of elts in
the array, instead (maximum is inclusive).  Maybe fis that some day :-)

> +/* Implement targetm.vectorize.builtin_md_vectorized_function.  */
> +
> +tree
> +rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
> +				       tree type_in)
> +{
> +  machine_mode in_mode, out_mode;
> +  int in_n, out_n;
> +
> +  if (TARGET_DEBUG_BUILTIN)
> +    fprintf (stderr,
> +	     "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n",
> +	     IDENTIFIER_POINTER (DECL_NAME (fndecl)),
> +	     GET_MODE_NAME (TYPE_MODE (type_out)),
> +	     GET_MODE_NAME (TYPE_MODE (type_in)));
> +
> +  /* TODO: Should this be gcc_assert?  */
> +  if (TREE_CODE (type_out) != VECTOR_TYPE
> +      || TREE_CODE (type_in) != VECTOR_TYPE)
> +    return NULL_TREE;

Yes, as target.def says.

> +  enum rs6000_gen_builtins fn
> +    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);

You could write
       = (decltype (fn)) DECL_MD_FUNCTION_CODE (fndecl);
btw.

> +    default:
> +      break;

Another wart :-(

The -Wswitch* warnings this works around should not be part of -Wall
imo, not even of -Wextra :-(

> +static
> +const char *rs6000_type_string (tree type_node)
> +{
> +  if (type_node == void_type_node)
> +    return "void";
> +  else if (type_node == long_integer_type_node)
> +    return "long";

You do not need the "else" btw.  Getting rid of that will make the code
easier to read.

> +void
> +rs6000_init_builtins (void)
> +{
> +  tree tdecl;
> +  tree t;

Don't declare things long before they are used please.

...

Bah, I am commenting on existing code...  Please do not mix code
movement and other things in the same patch.  In the (very few!) cases
where you need things to stay together for bisectability, you can still
submit it as multiple patches (and you have that, that is how you write
it in the first place!), just comment that you need to check in a few
patches together.

Is it a big hassle to do that now, for this patch?


Segher

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

* Re: [PATCH 4/8] rs6000: Consolidate target built-ins code
  2022-01-31 21:32   ` Segher Boessenkool
@ 2022-01-31 22:01     ` Bill Schmidt
  2022-01-31 22:33       ` Segher Boessenkool
  0 siblings, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-01-31 22:01 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

Hi Segher,

On 1/31/22 3:32 PM, Segher Boessenkool wrote:
> Hi!
>
> On Fri, Jan 28, 2022 at 11:50:22AM -0600, Bill Schmidt wrote:
>> Continuing with the refactoring effort, this patch moves as much of the
>> target-specific built-in support code into a new file, rs6000-builtin.cc.
>> However, we can't easily move the overloading support code out of
>> rs6000-c.cc, because the build machinery understands that as a special file
>> to be included with the C and C++ front ends.
> And the other C-like frontends.
>
>> This patch is just a straightforward move, with one exception.  I found
>> that the builtin_mode_to_type[] array is no longer used, so I also removed
>> all code having to do with it.
> Oh nice, your rewrite removed the need for that array.  Great :-)
>
>> The code in rs6000-builtin.cc is organized in related sections:
>>  - General support functions
>>  - Initialization support
>>  - GIMPLE folding support
>>  - Expansion support
>>
>> Overloading support remains in rs6000-c.cc.
> So, what is needed to move that as well?  Is moving that in the plan?

No, as explained above, that code needs to stay in the "special" file
that the build machinery understands.  It looks very difficult to
tease that apart, so I've given up on that.  Sorry!

>
>> 	* config/rs6000/rs6000-builtin.cc: New file, containing code moved
>> 	from other files.
> (You're breaking lines early again.)
>
>> -	extra_objs="${extra_objs} rs6000-builtins.o"
>> +	extra_objs="${extra_objs} rs6000-builtins.o rs6000-builtin.o"
> It's pretty unfortunate that these files are named alike.  The source
> files exist in different places of course, so the danger of confusion
> is minimal usually.
>
>> +/* Support targetm.vectorize.builtin_mask_for_load.  */
>> +tree altivec_builtin_mask_for_load;
> "Support"?  What does that mean?  Please describe what this tree is.

That comment is just moved.  There's a target hook from the vectorizer
for Altivec-style unaligned load masking.  The target needs to provide
a built-in function for this.  The tree contains its function decl.
I can change the comment.

>
>> +/* **** General support functions. **** */
> This isn't a sentence so should not have a full stop.  (And otherwise
> it should be followed by two spaces!)
>
>> +bool
>> +rs6000_builtin_is_supported (enum rs6000_gen_builtins fncode)
>> +{
>> +  switch (rs6000_builtin_info[(size_t) fncode].enable)
>> +    {
>> +    case ENB_ALWAYS:
>> +      return true;
>> +    case ENB_P5:
>> +      return TARGET_POPCNTB;
>> +    case ENB_P6:
>> +      return TARGET_CMPB;
>> +    case ENB_P6_64:
>> +      return TARGET_CMPB && TARGET_POWERPC64;
>> +    case ENB_P7:
>> +      return TARGET_POPCNTD;
>> +    case ENB_P7_64:
>> +      return TARGET_POPCNTD && TARGET_POWERPC64;
>> +    case ENB_P8:
>> +      return TARGET_DIRECT_MOVE;
>> +    case ENB_P8V:
>> +      return TARGET_P8_VECTOR;
>> +    case ENB_P9:
>> +      return TARGET_MODULO;
>> +    case ENB_P9_64:
>> +      return TARGET_MODULO && TARGET_POWERPC64;
>> +    case ENB_P9V:
>> +      return TARGET_P9_VECTOR;
>> +    case ENB_P10:
>> +      return TARGET_POWER10;
>> +    case ENB_P10_64:
>> +      return TARGET_POWER10 && TARGET_POWERPC64;
>> +    case ENB_ALTIVEC:
>> +      return TARGET_ALTIVEC;
>> +    case ENB_VSX:
>> +      return TARGET_VSX;
>> +    case ENB_CELL:
>> +      return TARGET_ALTIVEC && rs6000_cpu == PROCESSOR_CELL;
>> +    case ENB_IEEE128_HW:
>> +      return TARGET_FLOAT128_HW;
>> +    case ENB_DFP:
>> +      return TARGET_DFP;
>> +    case ENB_CRYPTO:
>> +      return TARGET_CRYPTO;
>> +    case ENB_HTM:
>> +      return TARGET_HTM;
>> +    case ENB_MMA:
>> +      return TARGET_MMA;
>> +    default:
>> +      gcc_unreachable ();
>> +    }
>> +  gcc_unreachable ();
>> +}
> If you rewrite this without switch it is shorter and clearer, and you do
> not need to duplicate the gcc_unreachable (which the broken warning
> forces you to).
>
>> +  if (fcode >= RS6000_OVLD_MAX)
>> +    return error_mark_node;
> This shows that that isn't really the max, it is the number of elts in
> the array, instead (maximum is inclusive).  Maybe fis that some day :-)
>
>> +/* Implement targetm.vectorize.builtin_md_vectorized_function.  */
>> +
>> +tree
>> +rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
>> +				       tree type_in)
>> +{
>> +  machine_mode in_mode, out_mode;
>> +  int in_n, out_n;
>> +
>> +  if (TARGET_DEBUG_BUILTIN)
>> +    fprintf (stderr,
>> +	     "rs6000_builtin_md_vectorized_function (%s, %s, %s)\n",
>> +	     IDENTIFIER_POINTER (DECL_NAME (fndecl)),
>> +	     GET_MODE_NAME (TYPE_MODE (type_out)),
>> +	     GET_MODE_NAME (TYPE_MODE (type_in)));
>> +
>> +  /* TODO: Should this be gcc_assert?  */
>> +  if (TREE_CODE (type_out) != VECTOR_TYPE
>> +      || TREE_CODE (type_in) != VECTOR_TYPE)
>> +    return NULL_TREE;
> Yes, as target.def says.
>
>> +  enum rs6000_gen_builtins fn
>> +    = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl);
> You could write
>        = (decltype (fn)) DECL_MD_FUNCTION_CODE (fndecl);
> btw.
>
>> +    default:
>> +      break;
> Another wart :-(
>
> The -Wswitch* warnings this works around should not be part of -Wall
> imo, not even of -Wextra :-(
>
>> +static
>> +const char *rs6000_type_string (tree type_node)
>> +{
>> +  if (type_node == void_type_node)
>> +    return "void";
>> +  else if (type_node == long_integer_type_node)
>> +    return "long";
> You do not need the "else" btw.  Getting rid of that will make the code
> easier to read.
>
>> +void
>> +rs6000_init_builtins (void)
>> +{
>> +  tree tdecl;
>> +  tree t;
> Don't declare things long before they are used please.
>
> ...
>
> Bah, I am commenting on existing code...  Please do not mix code
> movement and other things in the same patch.  In the (very few!) cases
> where you need things to stay together for bisectability, you can still
> submit it as multiple patches (and you have that, that is how you write
> it in the first place!), just comment that you need to check in a few
> patches together.

This entire patch is just moving code.  I already separated that out
from everything else.  The only exception is the one I called out at
the beginning, that removing the builtin_mode_to_type[] array should
have been done previously, and it's convenient to just delete it as
part of this patch.

So I can change these other things that you mention, but that isn't
really the point of this patch, so...  I guess please advise. :-)

Thanks,
Bill

>
> Is it a big hassle to do that now, for this patch?
>
>
> Segher

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

* Re: [PATCH 4/8] rs6000: Consolidate target built-ins code
  2022-01-31 22:01     ` Bill Schmidt
@ 2022-01-31 22:33       ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-01-31 22:33 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Mon, Jan 31, 2022 at 04:01:58PM -0600, Bill Schmidt wrote:
> On 1/31/22 3:32 PM, Segher Boessenkool wrote:
> > On Fri, Jan 28, 2022 at 11:50:22AM -0600, Bill Schmidt wrote:
> >> Overloading support remains in rs6000-c.cc.
> > So, what is needed to move that as well?  Is moving that in the plan?
> 
> No, as explained above, that code needs to stay in the "special" file
> that the build machinery understands.  It looks very difficult to
> tease that apart, so I've given up on that.  Sorry!

Heh.  And you don't see that as a challenge?  Oh well, I could try :-)

> >> +/* Support targetm.vectorize.builtin_mask_for_load.  */
> >> +tree altivec_builtin_mask_for_load;
> > "Support"?  What does that mean?  Please describe what this tree is.
> 
> That comment is just moved.

Yes, but that isn't clear in your patch (series).

> This entire patch is just moving code.

Not according to the changelog!

It is hard to find the five, six, ten places with modification in an
1800-line patch (or what was it).

> I already separated that out
> from everything else.  The only exception is the one I called out at
> the beginning, that removing the builtin_mode_to_type[] array should
> have been done previously, and it's convenient to just delete it as
> part of this patch.
> 
> So I can change these other things that you mention, but that isn't
> really the point of this patch, so...  I guess please advise. :-)

Please make it less work for me to review your patches than it took you
to write them!  This often means you have to spend a bit more time and
thought on it.  As a side effect that makes better patches, you have
something to win here as well (apart from your patches being reviewed
easier :-) )


Segher

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

* [PATCH v2 1/8] rs6000: More factoring of overload processing
  2022-01-28 19:11   ` Segher Boessenkool
  2022-01-28 21:19     ` Bill Schmidt
@ 2022-02-01 14:49     ` Bill Schmidt
  2022-02-01 21:48       ` Segher Boessenkool
  1 sibling, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-02-01 14:49 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

Hi,

I've modified the previous patch to add more explanatory commentary about
the number-of-arguments test that was previously confusing, and to convert
the switch into an if-then-else chain.  The rest of the patch is unchanged.
Bootstrapped and tested on powerpc64le-linux-gnu.  Is this okay for trunk?

Remainder of commit message follows:

This patch continues the refactoring started with r12-6014.  I had previously
noted that the resolve_vec* routines can be further simplified by processing
the argument list earlier, so that all routines can use the arrays of arguments
and types.  I found that this was useful for some of the routines, but not for
all of them.

For several of the special-cased overloads, we don't specify all of the
possible type combinations in rs6000-overload.def, because the types don't
matter for the expansion we do.  For these, we can't use generic error message
handling when the number of arguments is incorrect, because the result is
misleading error messages that indicate argument types are wrong.

So this patch goes halfway and improves the factoring on the remaining special
cases, but leaves vec_splats, vec_promote, vec_extract, vec_insert, and
vec_step alone.

Thanks!
Bill


2022-01-31  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-c.cc (resolve_vec_mul): Accept args and types
	parameters instead of arglist and nargs.  Simplify accordingly.  Remove
	unnecessary test for argument count mismatch.
	(resolve_vec_cmpne): Likewise.
	(resolve_vec_adde_sube): Likewise.
	(resolve_vec_addec_subec): Likewise.
	(altivec_resolve_overloaded_builtin): Move overload special handling
	after the gathering of arguments into args[] and types[] and the test
	for correct number of arguments.  Don't perform the test for correct
	number of arguments for certain special cases.  Call the other special
	cases with args and types instead of arglist and nargs.
---
 gcc/config/rs6000/rs6000-c.cc | 297 ++++++++++++++--------------------
 1 file changed, 120 insertions(+), 177 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index 145421ab8f2..4911e5f509c 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -939,37 +939,25 @@ altivec_build_resolved_builtin (tree *args, int n, tree fntype, tree ret_type,
 enum resolution { unresolved, resolved, resolved_bad };
 
 /* Resolve an overloaded vec_mul call and return a tree expression for the
-   resolved call if successful.  NARGS is the number of arguments to the call.
-   ARGLIST contains the arguments.  RES must be set to indicate the status of
+   resolved call if successful.  ARGS contains the arguments to the call.
+   TYPES contains their types.  RES must be set to indicate the status of
    the resolution attempt.  LOC contains statement location information.  */
 
 static tree
-resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
-		 location_t loc)
+resolve_vec_mul (resolution *res, tree *args, tree *types, location_t loc)
 {
   /* vec_mul needs to be special cased because there are no instructions for it
      for the {un}signed char, {un}signed short, and {un}signed int types.  */
-  if (nargs != 2)
-    {
-      error ("builtin %qs only accepts 2 arguments", "vec_mul");
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
 
   /* Both arguments must be vectors and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
     case E_QImode:
     case E_HImode:
@@ -978,21 +966,21 @@ resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
     case E_TImode:
       /* For scalar types just use a multiply expression.  */
       *res = resolved;
-      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0,
-			      fold_convert (TREE_TYPE (arg0), arg1));
+      return fold_build2_loc (loc, MULT_EXPR, types[0], args[0],
+			      fold_convert (types[0], args[1]));
     case E_SFmode:
       {
 	/* For floats use the xvmulsp instruction directly.  */
 	*res = resolved;
 	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULSP];
-	return build_call_expr (call, 2, arg0, arg1);
+	return build_call_expr (call, 2, args[0], args[1]);
       }
     case E_DFmode:
       {
 	/* For doubles use the xvmuldp instruction directly.  */
 	*res = resolved;
 	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULDP];
-	return build_call_expr (call, 2, arg0, arg1);
+	return build_call_expr (call, 2, args[0], args[1]);
       }
     /* Other types are errors.  */
     default:
@@ -1002,37 +990,25 @@ resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
 }
 
 /* Resolve an overloaded vec_cmpne call and return a tree expression for the
-   resolved call if successful.  NARGS is the number of arguments to the call.
-   ARGLIST contains the arguments.  RES must be set to indicate the status of
+   resolved call if successful.  ARGS contains the arguments to the call.
+   TYPES contains their types.  RES must be set to indicate the status of
    the resolution attempt.  LOC contains statement location information.  */
 
 static tree
-resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
-		   location_t loc)
+resolve_vec_cmpne (resolution *res, tree *args, tree *types, location_t loc)
 {
   /* vec_cmpne needs to be special cased because there are no instructions
      for it (prior to power 9).  */
-  if (nargs != 2)
-    {
-      error ("builtin %qs only accepts 2 arguments", "vec_cmpne");
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
 
   /* Both arguments must be vectors and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (arg0_type));
+  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (types[0]));
 
   /* Power9 instructions provide the most efficient implementation of
      ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode
@@ -1060,8 +1036,8 @@ resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
 	    /* call = vec_cmpeq (va, vb)
 	       result = vec_nor (call, call).  */
 	    vec<tree, va_gc> *params = make_tree_vector ();
-	    vec_safe_push (params, arg0);
-	    vec_safe_push (params, arg1);
+	    vec_safe_push (params, args[0]);
+	    vec_safe_push (params, args[1]);
 	    tree decl = rs6000_builtin_decls[RS6000_OVLD_VEC_CMPEQ];
 	    tree call = altivec_resolve_overloaded_builtin (loc, decl, params);
 	    /* Use save_expr to ensure that operands used more than once
@@ -1088,46 +1064,30 @@ resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
   return error_mark_node;
 }
 
-/* Resolve an overloaded vec_adde or vec_sube call and return a tree
-   expression for the resolved call if successful.  NARGS is the number of
-   arguments to the call.  ARGLIST contains the arguments.  RES must be set
-   to indicate the status of the resolution attempt.  LOC contains statement
-   location information.  */
+/* Resolve an overloaded vec_adde or vec_sube call and return a tree expression
+   for the resolved call if successful.  ARGS contains the arguments to the
+   call.  TYPES contains their arguments.  RES must be set to indicate the
+   status of the resolution attempt.  LOC contains statement location
+   information.  */
 
 static tree
 resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
-		       vec<tree, va_gc> *arglist, unsigned nargs,
-		       location_t loc)
+		       tree *args, tree *types, location_t loc)
 {
   /* vec_adde needs to be special cased because there is no instruction
      for the {un}signed int version.  */
-  if (nargs != 3)
-    {
-      const char *name;
-      name = fcode == RS6000_OVLD_VEC_ADDE ? "vec_adde" : "vec_sube";
-      error ("builtin %qs only accepts 3 arguments", name);
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
-  tree arg2 = (*arglist)[2];
-  tree arg2_type = TREE_TYPE (arg2);
 
   /* All 3 arguments must be vectors of (signed or unsigned) (int or
      __int128) and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type)
-      || !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1])
+      || !lang_hooks.types_compatible_p (types[1], types[2]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
       /* For {un}signed ints,
 	 vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
@@ -1137,8 +1097,8 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
     case E_SImode:
       {
 	vec<tree, va_gc> *params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree add_sub_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDE)
@@ -1148,10 +1108,10 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
 
 	tree call = altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
 							params);
-	tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
-	tree ones_vector = build_vector_from_val (arg0_type, const1);
-	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
-					 arg2, ones_vector);
+	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
+	tree ones_vector = build_vector_from_val (types[0], const1);
+	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
+					 args[2], ones_vector);
 	params = make_tree_vector ();
 	vec_safe_push (params, call);
 	vec_safe_push (params, and_expr);
@@ -1175,45 +1135,29 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
 }
 
 /* Resolve an overloaded vec_addec or vec_subec call and return a tree
-   expression for the resolved call if successful.  NARGS is the number of
-   arguments to the call.  ARGLIST contains the arguments.  RES must be set
-   to indicate the status of the resolution attempt.  LOC contains statement
-   location information.  */
+   expression for the resolved call if successful.  ARGS contains the arguments
+   to the call.  TYPES contains their types.  RES must be set to indicate the
+   status of the resolution attempt.  LOC contains statement location
+   information.  */
 
 static tree
 resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
-			 vec<tree, va_gc> *arglist, unsigned nargs,
-			 location_t loc)
+			 tree *args, tree *types, location_t loc)
 {
   /* vec_addec and vec_subec needs to be special cased because there is
      no instruction for the (un)signed int version.  */
-  if (nargs != 3)
-    {
-      const char *name;
-      name = fcode == RS6000_OVLD_VEC_ADDEC ? "vec_addec" : "vec_subec";
-      error ("builtin %qs only accepts 3 arguments", name);
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
-  tree arg2 = (*arglist)[2];
-  tree arg2_type = TREE_TYPE (arg2);
 
   /* All 3 arguments must be vectors of (signed or unsigned) (int or
      __int128) and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type)
-      || !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1])
+      || !lang_hooks.types_compatible_p (types[1], types[2]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
       /* For {un}signed ints,
 	   vec_addec (va, vb, carryv) ==
@@ -1224,11 +1168,11 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
       {
 	/* Use save_expr to ensure that operands used more than once that may
 	   have side effects (like calls) are only evaluated once.  */
-	arg0 = save_expr (arg0);
-	arg1 = save_expr (arg1);
+	args[0] = save_expr (args[0]);
+	args[1] = save_expr (args[1]);
 	vec<tree, va_gc> *params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree as_c_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDEC)
@@ -1239,8 +1183,8 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
 	tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
 							 params);
 	params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree as_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDEC)
@@ -1250,10 +1194,10 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
 
 	tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin,
 							 params);
-	tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
-	tree ones_vector = build_vector_from_val (arg0_type, const1);
-	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
-					 arg2, ones_vector);
+	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
+	tree ones_vector = build_vector_from_val (types[0], const1);
+	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
+					 args[2], ones_vector);
 	params = make_tree_vector ();
 	vec_safe_push (params, call2);
 	vec_safe_push (params, and_expr);
@@ -1783,78 +1727,15 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 	     "%<vec_lvsr%> is deprecated for little endian; use "
 	     "assignment for unaligned loads and stores");
 
-  /* Some overloads require special handling.  */
-  /* FIXME: Could we simplify the helper functions if we gathered arguments
-     and types into arrays first?  */
-  tree returned_expr = NULL;
-  resolution res = unresolved;
-  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
-  unsigned int nargs = vec_safe_length (arglist);
-
-  switch (fcode)
-    {
-    case RS6000_OVLD_VEC_MUL:
-      returned_expr = resolve_vec_mul (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_CMPNE:
-      returned_expr = resolve_vec_cmpne (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_ADDE:
-    case RS6000_OVLD_VEC_SUBE:
-      returned_expr = resolve_vec_adde_sube (&res, fcode, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_ADDEC:
-    case RS6000_OVLD_VEC_SUBEC:
-      returned_expr = resolve_vec_addec_subec (&res, fcode, arglist, nargs,
-					       loc);
-      break;
-
-    case RS6000_OVLD_VEC_SPLATS:
-    case RS6000_OVLD_VEC_PROMOTE:
-      returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
-      break;
-
-    case RS6000_OVLD_VEC_EXTRACT:
-      returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_INSERT:
-      returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_STEP:
-      returned_expr = resolve_vec_step (&res, arglist, nargs);
-      break;
-
-    default:
-      ;
-    }
-
-  if (res == resolved)
-    return returned_expr;
-
-  /* "Regular" built-in functions and overloaded functions share a namespace
-     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
-     only has information for the overloaded functions, so we need an
-     adjusted index for that.  */
-  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
-
-  if (res == resolved_bad)
-    {
-      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
-      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
-      return error_mark_node;
-    }
-
   /* Gather the arguments and their types into arrays for easier handling.  */
   tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   tree types[MAX_OVLD_ARGS];
   tree args[MAX_OVLD_ARGS];
   unsigned int n;
 
+  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
+  unsigned int nargs = vec_safe_length (arglist);
+
   for (n = 0;
        !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs;
        fnargs = TREE_CHAIN (fnargs), n++)
@@ -1915,10 +1796,72 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
     }
 
   /* If the number of arguments did not match the prototype, return NULL
-     and the generic code will issue the appropriate error message.  */
-  if (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs)
+     and the generic code will issue the appropriate error message.  Skip
+     this test for functions where we don't fully describe all the possible
+     overload signatures in rs6000-overload.def (because they aren't relevant
+     to the expansion here).  If we don't, we get confusing error messages.  */
+  /* As an example, for vec_splats we have:
+
+; There are no actual builtins for vec_splats.  There is special handling for
+; this in altivec_resolve_overloaded_builtin in rs6000-c.cc, where the call
+; is replaced by a constructor.  The single overload here causes
+; __builtin_vec_splats to be registered with the front end so that can happen.
+[VEC_SPLATS, vec_splats, __builtin_vec_splats]
+  vsi __builtin_vec_splats (vsi);
+    ABS_V4SI SPLATS_FAKERY
+
+    So even though __builtin_vec_splats accepts all vector types, the
+    infrastructure cheats and just records one prototype.  We end up getting
+    an error message that refers to this specific prototype even when we
+    are handling a different argument type.  That is completely confusing
+    to the user, so it's best to let these cases be handled individually
+    in the resolve_vec_splats, etc., helper functions.  */
+
+  if (fcode != RS6000_OVLD_VEC_PROMOTE
+      && fcode != RS6000_OVLD_VEC_SPLATS
+      && fcode != RS6000_OVLD_VEC_EXTRACT
+      && fcode != RS6000_OVLD_VEC_INSERT
+      && fcode != RS6000_OVLD_VEC_STEP
+      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
     return NULL;
 
+  /* Some overloads require special handling.  */
+  tree returned_expr = NULL;
+  resolution res = unresolved;
+
+  if (fcode == RS6000_OVLD_VEC_MUL)
+    returned_expr = resolve_vec_mul (&res, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_CMPNE)
+    returned_expr = resolve_vec_cmpne (&res, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
+    returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
+    returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
+    returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
+  else if (fcode == RS6000_OVLD_VEC_EXTRACT)
+    returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
+  else if (fcode == RS6000_OVLD_VEC_INSERT)
+    returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
+  else if (fcode == RS6000_OVLD_VEC_STEP)
+    returned_expr = resolve_vec_step (&res, arglist, nargs);
+
+  if (res == resolved)
+    return returned_expr;
+
+  /* "Regular" built-in functions and overloaded functions share a namespace
+     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
+     only has information for the overloaded functions, so we need an
+     adjusted index for that.  */
+  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
+
+  if (res == resolved_bad)
+    {
+      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
+      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
+      return error_mark_node;
+    }
+
   bool unsupported_builtin = false;
   rs6000_gen_builtins instance_code;
   bool supported = false;
-- 
2.27.0



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

* [PATCH v2 3/8] rs6000: Unify error messages for built-in constant restrictions
  2022-01-31 17:28       ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
  2022-01-31 17:31         ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
@ 2022-02-01 14:53         ` Bill Schmidt
  2022-02-01 22:16           ` Segher Boessenkool
  1 sibling, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-02-01 14:53 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

Hi!

As discussed, I simplified this patch by just changing how the error
message is produced:

We currently give different error messages for built-in functions that
violate range restrictions on their arguments, depending on whether we
record them as requiring an n-bit literal or a literal between two values.
It's better to be consistent.  Change the error message for the n-bit
literal to look like the other one.

Bootstrapped and tested on powerpc64le-linux-gnu.  Is this okay for trunk?

Thanks!
Bill


2022-01-31  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-call.cc (rs6000_expand_builtin): Revise
	error message for RES_BITS case.

gcc/testsuite/
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c:
	Adjust error messages.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-1.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-2.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-3.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr80315-4.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr82015.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/pr91903.c: Likewise.
	* gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c:
	Likewise.
	* gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c: Likewise.
---
 gcc/config/rs6000/rs6000-call.cc              |  6 +-
 .../powerpc/bfp/scalar-test-data-class-10.c   |  2 +-
 .../powerpc/bfp/scalar-test-data-class-2.c    |  2 +-
 .../powerpc/bfp/scalar-test-data-class-3.c    |  2 +-
 .../powerpc/bfp/scalar-test-data-class-4.c    |  2 +-
 .../powerpc/bfp/scalar-test-data-class-5.c    |  2 +-
 .../powerpc/bfp/scalar-test-data-class-9.c    |  2 +-
 .../powerpc/bfp/vec-test-data-class-4.c       |  2 +-
 .../powerpc/bfp/vec-test-data-class-5.c       |  2 +-
 .../powerpc/bfp/vec-test-data-class-6.c       |  2 +-
 .../powerpc/bfp/vec-test-data-class-7.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-12.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-14.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-17.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-19.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-2.c        |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-22.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-24.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-27.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-29.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-32.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-34.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-37.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-39.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-4.c        |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-42.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-44.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-47.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-49.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-52.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-54.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-57.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-59.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-62.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-64.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-67.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-69.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-7.c        |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-72.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-74.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-77.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-79.c       |  2 +-
 .../gcc.target/powerpc/dfp/dtstsfi-9.c        |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-1.c  |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-2.c  |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-3.c  |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr80315-4.c  |  2 +-
 gcc/testsuite/gcc.target/powerpc/pr82015.c    |  4 +-
 gcc/testsuite/gcc.target/powerpc/pr91903.c    | 60 +++++++++----------
 .../powerpc/test_fpscr_rn_builtin_error.c     |  8 +--
 .../gcc.target/powerpc/vec-ternarylogic-10.c  |  6 +-
 51 files changed, 89 insertions(+), 87 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-call.cc b/gcc/config/rs6000/rs6000-call.cc
index e002e1f2b70..70358731b44 100644
--- a/gcc/config/rs6000/rs6000-call.cc
+++ b/gcc/config/rs6000/rs6000-call.cc
@@ -5729,8 +5729,10 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
 	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
 		  && (TREE_INT_CST_LOW (restr_arg) & ~mask) == 0))
 	      {
-		error ("argument %d must be a %d-bit unsigned literal",
-		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i]);
+		unsigned p = ((unsigned) 1 << bifaddr->restr_val1[i]) - 1;
+		error ("argument %d must be a literal between 0 and %d,"
+		       " inclusive",
+		       bifaddr->restr_opnd[i], p);
 		return CONST0_RTX (mode[0]);
 	      }
 	    break;
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
index 2e3643c6c09..fcf6a9dca79 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-10.c
@@ -13,6 +13,6 @@ test_data_class (__ieee128 *p, const int condition_flag)
 {
   __ieee128 source = *p;
 
-  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
index 59f03a30484..9130c9714bf 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-2.c
@@ -10,6 +10,6 @@ test_data_class (double *p)
 {
   double source = *p;
 
-  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
index d3d94261d28..b863bb2bc27 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-3.c
@@ -10,6 +10,6 @@ test_data_class (float *p)
 {
   float source = *p;
 
-  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
index 210fa411f9e..83ddffa77a3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-4.c
@@ -10,6 +10,6 @@ test_data_class (double *p, const int condition_flag)
 {
   double source = *p;
 
-  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
index b66f0a27e8c..101a919c9e4 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-5.c
@@ -10,6 +10,6 @@ test_data_class (float *p, const int condition_flag)
 {
   float source = *p;
 
-  return scalar_test_data_class (source, condition_flag);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, condition_flag);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
index cfa9a9c3939..f87851c2c5f 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-9.c
@@ -13,6 +13,6 @@ test_data_class (__ieee128 *p)
 
   /* IEEE 128-bit floating point operations are only supported
      on 64-bit targets.  */
-  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return scalar_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
index 56ce5f9ebe7..448406c0d47 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-4.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector float *p)
 {
   __vector float source = *p;
 
-  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
index 11624c98a38..64a52a15439 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-5.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector double *p)
 {
   __vector double source = *p;
 
-  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, 256);	/* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
index 2c7e9deb7a2..5f35e0e368a 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-6.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector float *p, int condition_flag)
 {
   __vector float source = *p;
 
-  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
index 86eff8d66ba..bda2c6d9db3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-7.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector double *p, int condition_flag)
 {
   __vector double source = *p;
 
-  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a 7-bit unsigned literal" } */
+  return vec_test_data_class (source, condition_flag); /* { dg-error "argument 2 must be a literal between 0 and 127, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
index 350b4c10205..4feb3918767 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-12.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
index 011d20039d0..ef4d6ad707b 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-14.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
index 28033dbac18..5a9ab5126fc 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-17.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
index 092b9c0f7c5..f1918a251c2 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-19.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
index 4b72fa8edc3..b353d63f5a5 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-2.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
index 15d7a352fdf..464dc66d457 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-22.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
index f6ed00a73dd..6e5e07b1c88 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-24.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
index 8e3954d6b93..d8760cefc94 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-27.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
index f6c0ede46cc..fed06bbbb6c 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-29.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
index d24f3982ee9..868146c8f53 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-32.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
index b6620c51f2a..de174998d21 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-34.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
index dc4c8ecdd00..1e5ff356ceb 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-37.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
index 1aee9efe919..b5f886d861a 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-39.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_gt_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_gt_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
index 6397aae3e56..ad840bf5465 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-4.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
index fc6b3568d09..586c86f2ab7 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-42.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
index b896865e6bb..dc01b7fc614 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-44.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
index edfac68b0e8..9ff41263531 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-47.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
index e7b50dc108e..5040ac87ed6 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-49.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
index c9431b5ea1a..a79e6b5dbb1 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-52.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
index 2fdb58f6748..5e9a93fd05e 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-54.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
index 275bf8d0ac2..ec2abc6499f 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-57.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
index e1da3d810ef..6f63d0f831f 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-59.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_eq_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_eq_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
index 44aaab201f9..4786be7bb48 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-62.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
index fb3331162c7..c406d4d1ca8 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-64.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
index 59471cfb645..d7b3b6f01ac 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-67.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
index c9e1721b3d6..bc9ced3ceb0 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-69.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
index d0d3f23c853..dcfe162c832 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-7.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
index 725cc5432b9..04d950e3df5 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-72.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_dd (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_dd (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
index c6ffd51d9f4..369312d84ea 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-74.c
@@ -8,6 +8,6 @@ int doTestBCDSignificance (_Decimal64 *p, unsigned int significance)
 {
   _Decimal64 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_dd (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_dd (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
index d279bfb5751..ca6c739a045 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-77.c
@@ -8,7 +8,7 @@ int doTestBCDSignificance (_Decimal128 *p)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_td (65, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_td (65, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
 
 
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
index b88b5a86bcb..9ee60cfe8e2 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-79.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_ov_td (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_ov_td (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
index b2073f56b05..9a9ff3899f2 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-9.c
@@ -8,5 +8,5 @@ int doTestBCDSignificance (_Decimal128 *p, unsigned int significance)
 {
   _Decimal128 source = *p;
 
-  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a 6-bit unsigned literal" } */
+  return __builtin_dfp_dtstsfi_lt (significance, source);	/* { dg-error "argument 1 must be a literal between 0 and 63, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-1.c b/gcc/testsuite/gcc.target/powerpc/pr80315-1.c
index f37f1f169a2..7198611258f 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-1.c
@@ -10,6 +10,6 @@ main()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = __builtin_crypto_vshasigmaw (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = __builtin_crypto_vshasigmaw (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-2.c b/gcc/testsuite/gcc.target/powerpc/pr80315-2.c
index 0819a0511b7..0f77f775ad3 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-2.c
@@ -10,6 +10,6 @@ main ()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = __builtin_crypto_vshasigmad (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = __builtin_crypto_vshasigmad (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return 0;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-3.c b/gcc/testsuite/gcc.target/powerpc/pr80315-3.c
index cc2e46cf5cb..398c512274d 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-3.c
@@ -12,6 +12,6 @@ main ()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return res;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80315-4.c b/gcc/testsuite/gcc.target/powerpc/pr80315-4.c
index ac12910741b..4326ff64c18 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80315-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80315-4.c
@@ -12,6 +12,6 @@ main ()
   int mask;
 
   /* Argument 2 must be 0 or 1.  Argument 3 must be in range 0..15.  */
-  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a 4-bit unsigned literal} } */
+  res = vec_shasigma_be (test, 1, 0xff); /* { dg-error {argument 3 must be a literal between 0 and 15, inclusive} } */
   return res;
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr82015.c b/gcc/testsuite/gcc.target/powerpc/pr82015.c
index ec939e96bb8..40f1c7d2a5c 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr82015.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr82015.c
@@ -5,10 +5,10 @@
 
 unsigned long foo_11(__vector __int128_t *p)
 {
-  return __builtin_unpack_vector_int128(*p, 11); /* { dg-error "argument 2 must be a 1-bit unsigned literal" } */
+  return __builtin_unpack_vector_int128(*p, 11); /* { dg-error "argument 2 must be a literal between 0 and 1, inclusive" } */
 }
 
 unsigned long foo_n(__vector __int128_t *p, unsigned long n)
 {
-  return __builtin_unpack_vector_int128(*p, n);	/* { dg-error "argument 2 must be a 1-bit unsigned literal" } */
+  return __builtin_unpack_vector_int128(*p, n);	/* { dg-error "argument 2 must be a literal between 0 and 1, inclusive" } */
 }
diff --git a/gcc/testsuite/gcc.target/powerpc/pr91903.c b/gcc/testsuite/gcc.target/powerpc/pr91903.c
index 3045d07da7d..7f9470ee905 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr91903.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr91903.c
@@ -12,62 +12,62 @@ vector signed int retsi;
 
 void test_int(vector signed int a, const int b)
 {
-	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retf = vec_ctf(a,1);
 	retf = vec_ctf(a,31);
-	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 void test_uint(vector unsigned int a, const int b)
 {
-	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retf = vec_ctf(a,1);
 	retf = vec_ctf(a,31);
-	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retf = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retf = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 void test_longlong(vector signed long long a, const int b,int x)
 {
-	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal"  } */
-	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive"  } */
+	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retd = vec_ctf(a,1);
 	retd = vec_ctf(a,31);
-	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 void test_ulonglong(vector unsigned long long a, const int b,int x)
 {
-	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retd = vec_ctf(a,1);
 	retd = vec_ctf(a,31);
-	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retd = vec_ctf(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retd = vec_ctf(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
 
 void test_cts_1(vector float a, const int b)
 {
-	retsi = vec_cts(a,b); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,-1); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,-31); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,-32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retsi = vec_cts(a,b); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,-1); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,-31); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,-32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 	retsi = vec_cts(a,1);
 	retsi = vec_cts(a,31);
-	retsi = vec_cts(a,32); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
-	retsi = vec_cts(a,42); /* { dg-error "argument 2 must be a 5-bit unsigned literal" } */
+	retsi = vec_cts(a,32); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
+	retsi = vec_cts(a,42); /* { dg-error "argument 2 must be a literal between 0 and 31, inclusive" } */
 }
 
diff --git a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c
index 10391b71008..62152c677ec 100644
--- a/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c
+++ b/gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin_error.c
@@ -8,11 +8,11 @@ int main ()
      int arguments.  The builtins __builtin_set_fpscr_rn() also supports a
      variable as an argument but can't test variable value at compile time.  */
 
-  __builtin_mtfsb0(-1);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */
-  __builtin_mtfsb0(32);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */
+  __builtin_mtfsb0(-1);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */
+  __builtin_mtfsb0(32);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */
 
-  __builtin_mtfsb1(-1);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */
-  __builtin_mtfsb1(32);  /* { dg-error "argument 1 must be a 5-bit unsigned literal" } */ 
+  __builtin_mtfsb1(-1);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */
+  __builtin_mtfsb1(32);  /* { dg-error "argument 1 must be a literal between 0 and 31, inclusive" } */ 
 
   __builtin_set_fpscr_rn(-1);  /* { dg-error "argument 1 must be a variable or a literal between 0 and 3, inclusive" } */ 
   __builtin_set_fpscr_rn(4);   /* { dg-error "argument 1 must be a variable or a literal between 0 and 3, inclusive" } */ 
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c
index 35700fcb364..d5ec14cf4ba 100644
--- a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c
+++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c
@@ -28,7 +28,7 @@ doTests00000001 (vector unsigned __int128 a_sources [],
 	  vector unsigned __int128 b = b_sources [j];
 	  vector unsigned __int128 c = c_sources [k];
 	  vector unsigned __int128 result;
-	  result = vec_ternarylogic (a, b, c, 0xfff); /* { dg-error "8-bit unsigned literal" } */
+	  result = vec_ternarylogic (a, b, c, 0xfff); /* { dg-error "literal between 0 and 255, inclusive" } */
 	  vector unsigned __int128 intended = (a & b & c);
 	  if (!vector_equal (result, intended))
 	    abort ();
@@ -47,7 +47,7 @@ doTests11100101 (vector unsigned __int128 a_sources [],
 	  vector unsigned __int128 b = b_sources [j];
 	  vector unsigned __int128 c = c_sources [k];
 	  vector unsigned __int128 result;
-	  result = vec_ternarylogic (a, b, c, -1); /* { dg-error "8-bit unsigned literal" } */
+	  result = vec_ternarylogic (a, b, c, -1); /* { dg-error "literal between 0 and 255, inclusive" } */
 	  vector unsigned __int128 intended = { 0 };
 	  // Supposed to be a ? c: nand (b,c)
 	  for (int l = 0; l < 1; l++)
@@ -80,7 +80,7 @@ doTests11110011 (vector unsigned __int128 a_sources [],
 	  vector unsigned __int128 b = b_sources [j];
 	  vector unsigned __int128 c = c_sources [k];
 	  vector unsigned __int128 result;
-	  result = vec_ternarylogic (a, b, c, i);  /* { dg-error "8-bit unsigned literal" } */
+	  result = vec_ternarylogic (a, b, c, i);  /* { dg-error "literal between 0 and 255, inclusive" } */
 	  vector unsigned __int128 intended = { 0 };
 	  for (int i = 0; i < 1; i++)
 	    intended [i] = b [i] | ~(a [i] & c [i]);
-- 
2.27.0



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

* Re: [PATCH v2 1/8] rs6000: More factoring of overload processing
  2022-02-01 14:49     ` [PATCH v2 " Bill Schmidt
@ 2022-02-01 21:48       ` Segher Boessenkool
  2022-02-02 18:46         ` Bill Schmidt
  2022-02-03 14:44         ` [PATCH v3 " Bill Schmidt
  0 siblings, 2 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-02-01 21:48 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Tue, Feb 01, 2022 at 08:49:34AM -0600, Bill Schmidt wrote:
> I've modified the previous patch to add more explanatory commentary about
> the number-of-arguments test that was previously confusing, and to convert
> the switch into an if-then-else chain.  The rest of the patch is unchanged.
> Bootstrapped and tested on powerpc64le-linux-gnu.  Is this okay for trunk?

> gcc/
> 	* config/rs6000/rs6000-c.cc (resolve_vec_mul): Accept args and types
> 	parameters instead of arglist and nargs.  Simplify accordingly.  Remove
> 	unnecessary test for argument count mismatch.
> 	(resolve_vec_cmpne): Likewise.
> 	(resolve_vec_adde_sube): Likewise.
> 	(resolve_vec_addec_subec): Likewise.
> 	(altivec_resolve_overloaded_builtin): Move overload special handling
> 	after the gathering of arguments into args[] and types[] and the test
> 	for correct number of arguments.  Don't perform the test for correct
> 	number of arguments for certain special cases.  Call the other special
> 	cases with args and types instead of arglist and nargs.

> +  if (fcode != RS6000_OVLD_VEC_PROMOTE
> +      && fcode != RS6000_OVLD_VEC_SPLATS
> +      && fcode != RS6000_OVLD_VEC_EXTRACT
> +      && fcode != RS6000_OVLD_VEC_INSERT
> +      && fcode != RS6000_OVLD_VEC_STEP
> +      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
>      return NULL;

Please don't do De Morgan manually, let the compiler deal with it?
Although even with that the logic is as clear as mud.  This matters if
someone (maybe even you) will have to debug this later, or modify this.
Maybe adding some suitably named variables can clarify things  here?

> +  if (fcode == RS6000_OVLD_VEC_MUL)
> +    returned_expr = resolve_vec_mul (&res, args, types, loc);
> +  else if (fcode == RS6000_OVLD_VEC_CMPNE)
> +    returned_expr = resolve_vec_cmpne (&res, args, types, loc);
> +  else if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
> +    returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
> +  else if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
> +    returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
> +  else if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
> +    returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
> +  else if (fcode == RS6000_OVLD_VEC_EXTRACT)
> +    returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
> +  else if (fcode == RS6000_OVLD_VEC_INSERT)
> +    returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
> +  else if (fcode == RS6000_OVLD_VEC_STEP)
> +    returned_expr = resolve_vec_step (&res, arglist, nargs);
> +
> +  if (res == resolved)
> +    return returned_expr;

This is so convoluted because the functions do two things, and have two
return values (res and returned_expr).


Segher

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

* Re: [PATCH v2 3/8] rs6000: Unify error messages for built-in constant restrictions
  2022-02-01 14:53         ` [PATCH v2 3/8] rs6000: Unify error messages for built-in constant restrictions Bill Schmidt
@ 2022-02-01 22:16           ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-02-01 22:16 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Tue, Feb 01, 2022 at 08:53:52AM -0600, Bill Schmidt wrote:
> As discussed, I simplified this patch by just changing how the error
> message is produced:
> 
> We currently give different error messages for built-in functions that
> violate range restrictions on their arguments, depending on whether we
> record them as requiring an n-bit literal or a literal between two values.
> It's better to be consistent.  Change the error message for the n-bit
> literal to look like the other one.

> --- a/gcc/config/rs6000/rs6000-call.cc
> +++ b/gcc/config/rs6000/rs6000-call.cc
> @@ -5729,8 +5729,10 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */,
>  	    if (!(TREE_CODE (restr_arg) == INTEGER_CST
>  		  && (TREE_INT_CST_LOW (restr_arg) & ~mask) == 0))
>  	      {
> -		error ("argument %d must be a %d-bit unsigned literal",
> -		       bifaddr->restr_opnd[i], bifaddr->restr_val1[i]);
> +		unsigned p = ((unsigned) 1 << bifaddr->restr_val1[i]) - 1;

Don't write
  (unsigned) 1
but instead just
  1U
please.  Does it need to be 1ULL btw?  (You need this if restr_val1[i]
can be greater than or equal to 32).  (32 itself would work, but is UB
nevertheless).

Okay with that.  Thanks!


Segher

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

* Re: [PATCH 5/8] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082]
  2022-01-28 17:50 ` [PATCH 5/8] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082] Bill Schmidt
@ 2022-02-01 23:01   ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-02-01 23:01 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 11:50:23AM -0600, Bill Schmidt wrote:
> These built-ins were misimplemented as always having big-endian semantics.

> 	PR target/95082
> 	* config/rs6000/rs6000-builtin.cc (rs6000_expand_builtin): Handle
> 	endianness for vclzlsbb and vctzlsbb.
> 	* config/rs6000/rs6000-builtins.def (VCLZLSBB_V16QI): Change
> 	default pattern and indicate a different pattern will be used for
> 	big endian.
> 	(VCLZLSBB_V4SI): Likewise.
> 	(VCLZLSBB_V8HI): Likewise.
> 	(VCTZLSBB_V16QI): Likewise.
> 	(VCTZLSBB_V4SI): Likewise.
> 	(VCTZLSBB_V8HI): Likewise.

Please don't break lines early?  Changelog lines are one tab followed
by 72 chars.

The patch is fine though.  Thanks!


Segher

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

* Re: [PATCH v2 1/8] rs6000: More factoring of overload processing
  2022-02-01 21:48       ` Segher Boessenkool
@ 2022-02-02 18:46         ` Bill Schmidt
  2022-02-03 14:44         ` [PATCH v3 " Bill Schmidt
  1 sibling, 0 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-02-02 18:46 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

Hi!

On 2/1/22 3:48 PM, Segher Boessenkool wrote:
> On Tue, Feb 01, 2022 at 08:49:34AM -0600, Bill Schmidt wrote:
>> I've modified the previous patch to add more explanatory commentary about
>> the number-of-arguments test that was previously confusing, and to convert
>> the switch into an if-then-else chain.  The rest of the patch is unchanged.
>> Bootstrapped and tested on powerpc64le-linux-gnu.  Is this okay for trunk?
>> gcc/
>> 	* config/rs6000/rs6000-c.cc (resolve_vec_mul): Accept args and types
>> 	parameters instead of arglist and nargs.  Simplify accordingly.  Remove
>> 	unnecessary test for argument count mismatch.
>> 	(resolve_vec_cmpne): Likewise.
>> 	(resolve_vec_adde_sube): Likewise.
>> 	(resolve_vec_addec_subec): Likewise.
>> 	(altivec_resolve_overloaded_builtin): Move overload special handling
>> 	after the gathering of arguments into args[] and types[] and the test
>> 	for correct number of arguments.  Don't perform the test for correct
>> 	number of arguments for certain special cases.  Call the other special
>> 	cases with args and types instead of arglist and nargs.
>> +  if (fcode != RS6000_OVLD_VEC_PROMOTE
>> +      && fcode != RS6000_OVLD_VEC_SPLATS
>> +      && fcode != RS6000_OVLD_VEC_EXTRACT
>> +      && fcode != RS6000_OVLD_VEC_INSERT
>> +      && fcode != RS6000_OVLD_VEC_STEP
>> +      && (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs))
>>      return NULL;
> Please don't do De Morgan manually, let the compiler deal with it?
> Although even with that the logic is as clear as mud.  This matters if
> someone (maybe even you) will have to debug this later, or modify this.
> Maybe adding some suitably named variables can clarify things  here?

I can de-deMorgan this.  Do you want to see the patch again, or is it okay
with that change?

Thanks!
Bill

>
>> +  if (fcode == RS6000_OVLD_VEC_MUL)
>> +    returned_expr = resolve_vec_mul (&res, args, types, loc);
>> +  else if (fcode == RS6000_OVLD_VEC_CMPNE)
>> +    returned_expr = resolve_vec_cmpne (&res, args, types, loc);
>> +  else if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
>> +    returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
>> +  else if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
>> +    returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
>> +  else if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
>> +    returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
>> +  else if (fcode == RS6000_OVLD_VEC_EXTRACT)
>> +    returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
>> +  else if (fcode == RS6000_OVLD_VEC_INSERT)
>> +    returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
>> +  else if (fcode == RS6000_OVLD_VEC_STEP)
>> +    returned_expr = resolve_vec_step (&res, arglist, nargs);
>> +
>> +  if (res == resolved)
>> +    return returned_expr;
> This is so convoluted because the functions do two things, and have two
> return values (res and returned_expr).
>
>
> Segher

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

* Re: [PATCH 6/8] rs6000: Remove -m[no-]fold-gimple flag [PR103686]
  2022-01-28 17:50 ` [PATCH 6/8] rs6000: Remove -m[no-]fold-gimple flag [PR103686] Bill Schmidt
@ 2022-02-02 23:21   ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-02-02 23:21 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 11:50:24AM -0600, Bill Schmidt wrote:
> The -m[no-]fold-gimple flag was really intended primarily for internal
> testing while implementing GIMPLE folding for rs6000 vector built-in
> functions.  It ended up leaking into other places, causing problems such
> as PR103686 identifies.  Let's remove it.

Okay.  BUT:

> gcc.target/powerpc/builtins-1.c was more problematic.  It was written in
> such a way as to be extremely fragile.  For this one, I rewrote the whole
> test in a different style, using individual functions to test each
> built-in function.  These same tests are also largely covered by
> builtins-1-be-folded.c and builtins-1-le-folded.c, so I chose to
> explicitly make this test -mbig for simplicity, and use -O2 for clean code
> generation.  I made some slight modifications to the expected instruction
> counts as a result, and tested on both 32- and 64-bit.

This made the testsuite part very hard to review again.  I gave up.

In the future, please do *one* logical change per patch.  That way at
least the patches are readable (they were not now, a lot of mixed-up
context).  So first a patch rewriting this testcase, and then a separate
patch that is the meat of *this* patch.

> Most instruction
> count tests now use the {\m ... \M} style, but I wasn't able to figure out
> how to get this right for vcmpequd. and vcmpgtud.  Using \. didn't do the
> trick, and I got tired of messing with it.  I can change those if you
> suggest the proper incantation for an opcode ending with a period.

{\madd\.} does the trick.  \.\M does not make any sense (a word cannot
end in a dot, it cannot contain one in the first place).  \M\. is valid,
but add\M\. is a bit silly: it is obvious the word ends there, there is
no need to assert that :-)

Okay for trunk like that.  Thanks!


Segher

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

* [PATCH v3 1/8] rs6000: More factoring of overload processing
  2022-02-01 21:48       ` Segher Boessenkool
  2022-02-02 18:46         ` Bill Schmidt
@ 2022-02-03 14:44         ` Bill Schmidt
  2022-02-04  1:24           ` Segher Boessenkool
  1 sibling, 1 reply; 37+ messages in thread
From: Bill Schmidt @ 2022-02-03 14:44 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: gcc-patches, dje.gcc

Hi!

Although the previous patch was correct, the logic around what to do when
the number of arguments is wrong was still hard to understand.  It should
be better now.  I'm now explicitly counting the number of expected arguments
and comparing against that.  The way the argument list is represented ensures
there is always at least one element in the argument chain, by terminating
the chain with an argument type of void, which is why the previous logic was
so convoluted.

The revisions are in altivec_resolve_overloaded_builtin.  Otherwise the patch
is the same as before.  I hope this is much easier to read!  Bootstrapped and
tested on powerpc64le-linux-gnu.  Is this okay for trunk?

Original changelog message follows:

This patch continues the refactoring started with r12-6014.  I had previously
noted that the resolve_vec* routines can be further simplified by processing
the argument list earlier, so that all routines can use the arrays of arguments
and types.  I found that this was useful for some of the routines, but not for
all of them.

For several of the special-cased overloads, we don't specify all of the
possible type combinations in rs6000-overload.def, because the types don't
matter for the expansion we do.  For these, we can't use generic error message
handling when the number of arguments is incorrect, because the result is
misleading error messages that indicate argument types are wrong.

So this patch goes halfway and improves the factoring on the remaining special
cases, but leaves vec_splats, vec_promote, vec_extract, vec_insert, and
vec_step alone.

Thanks,
Bill


2022-02-02  Bill Schmidt  <wschmidt@linux.ibm.com>

gcc/
	* config/rs6000/rs6000-c.cc (resolve_vec_mul): Accept args and types
	parameters instead of arglist and nargs.  Simplify accordingly.  Remove
	unnecessary test for argument count mismatch.
	(resolve_vec_cmpne): Likewise.
	(resolve_vec_adde_sube): Likewise.
	(resolve_vec_addec_subec): Likewise.
	(altivec_resolve_overloaded_builtin): Move overload special handling
	after the gathering of arguments into args[] and types[] and the test
	for correct number of arguments.  Don't perform the test for correct
	number of arguments for certain special cases.  Call the other special
	cases with args and types instead of arglist and nargs.
---
 gcc/config/rs6000/rs6000-c.cc | 304 ++++++++++++++--------------------
 1 file changed, 127 insertions(+), 177 deletions(-)

diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc
index 145421ab8f2..15251efc209 100644
--- a/gcc/config/rs6000/rs6000-c.cc
+++ b/gcc/config/rs6000/rs6000-c.cc
@@ -939,37 +939,25 @@ altivec_build_resolved_builtin (tree *args, int n, tree fntype, tree ret_type,
 enum resolution { unresolved, resolved, resolved_bad };
 
 /* Resolve an overloaded vec_mul call and return a tree expression for the
-   resolved call if successful.  NARGS is the number of arguments to the call.
-   ARGLIST contains the arguments.  RES must be set to indicate the status of
+   resolved call if successful.  ARGS contains the arguments to the call.
+   TYPES contains their types.  RES must be set to indicate the status of
    the resolution attempt.  LOC contains statement location information.  */
 
 static tree
-resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
-		 location_t loc)
+resolve_vec_mul (resolution *res, tree *args, tree *types, location_t loc)
 {
   /* vec_mul needs to be special cased because there are no instructions for it
      for the {un}signed char, {un}signed short, and {un}signed int types.  */
-  if (nargs != 2)
-    {
-      error ("builtin %qs only accepts 2 arguments", "vec_mul");
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
 
   /* Both arguments must be vectors and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
     case E_QImode:
     case E_HImode:
@@ -978,21 +966,21 @@ resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
     case E_TImode:
       /* For scalar types just use a multiply expression.  */
       *res = resolved;
-      return fold_build2_loc (loc, MULT_EXPR, TREE_TYPE (arg0), arg0,
-			      fold_convert (TREE_TYPE (arg0), arg1));
+      return fold_build2_loc (loc, MULT_EXPR, types[0], args[0],
+			      fold_convert (types[0], args[1]));
     case E_SFmode:
       {
 	/* For floats use the xvmulsp instruction directly.  */
 	*res = resolved;
 	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULSP];
-	return build_call_expr (call, 2, arg0, arg1);
+	return build_call_expr (call, 2, args[0], args[1]);
       }
     case E_DFmode:
       {
 	/* For doubles use the xvmuldp instruction directly.  */
 	*res = resolved;
 	tree call = rs6000_builtin_decls[RS6000_BIF_XVMULDP];
-	return build_call_expr (call, 2, arg0, arg1);
+	return build_call_expr (call, 2, args[0], args[1]);
       }
     /* Other types are errors.  */
     default:
@@ -1002,37 +990,25 @@ resolve_vec_mul (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
 }
 
 /* Resolve an overloaded vec_cmpne call and return a tree expression for the
-   resolved call if successful.  NARGS is the number of arguments to the call.
-   ARGLIST contains the arguments.  RES must be set to indicate the status of
+   resolved call if successful.  ARGS contains the arguments to the call.
+   TYPES contains their types.  RES must be set to indicate the status of
    the resolution attempt.  LOC contains statement location information.  */
 
 static tree
-resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
-		   location_t loc)
+resolve_vec_cmpne (resolution *res, tree *args, tree *types, location_t loc)
 {
   /* vec_cmpne needs to be special cased because there are no instructions
      for it (prior to power 9).  */
-  if (nargs != 2)
-    {
-      error ("builtin %qs only accepts 2 arguments", "vec_cmpne");
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
 
   /* Both arguments must be vectors and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (arg0_type));
+  machine_mode arg0_elt_mode = TYPE_MODE (TREE_TYPE (types[0]));
 
   /* Power9 instructions provide the most efficient implementation of
      ALTIVEC_BUILTIN_VEC_CMPNE if the mode is not DImode or TImode
@@ -1060,8 +1036,8 @@ resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
 	    /* call = vec_cmpeq (va, vb)
 	       result = vec_nor (call, call).  */
 	    vec<tree, va_gc> *params = make_tree_vector ();
-	    vec_safe_push (params, arg0);
-	    vec_safe_push (params, arg1);
+	    vec_safe_push (params, args[0]);
+	    vec_safe_push (params, args[1]);
 	    tree decl = rs6000_builtin_decls[RS6000_OVLD_VEC_CMPEQ];
 	    tree call = altivec_resolve_overloaded_builtin (loc, decl, params);
 	    /* Use save_expr to ensure that operands used more than once
@@ -1088,46 +1064,30 @@ resolve_vec_cmpne (resolution *res, vec<tree, va_gc> *arglist, unsigned nargs,
   return error_mark_node;
 }
 
-/* Resolve an overloaded vec_adde or vec_sube call and return a tree
-   expression for the resolved call if successful.  NARGS is the number of
-   arguments to the call.  ARGLIST contains the arguments.  RES must be set
-   to indicate the status of the resolution attempt.  LOC contains statement
-   location information.  */
+/* Resolve an overloaded vec_adde or vec_sube call and return a tree expression
+   for the resolved call if successful.  ARGS contains the arguments to the
+   call.  TYPES contains their arguments.  RES must be set to indicate the
+   status of the resolution attempt.  LOC contains statement location
+   information.  */
 
 static tree
 resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
-		       vec<tree, va_gc> *arglist, unsigned nargs,
-		       location_t loc)
+		       tree *args, tree *types, location_t loc)
 {
   /* vec_adde needs to be special cased because there is no instruction
      for the {un}signed int version.  */
-  if (nargs != 3)
-    {
-      const char *name;
-      name = fcode == RS6000_OVLD_VEC_ADDE ? "vec_adde" : "vec_sube";
-      error ("builtin %qs only accepts 3 arguments", name);
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
-  tree arg2 = (*arglist)[2];
-  tree arg2_type = TREE_TYPE (arg2);
 
   /* All 3 arguments must be vectors of (signed or unsigned) (int or
      __int128) and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type)
-      || !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1])
+      || !lang_hooks.types_compatible_p (types[1], types[2]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
       /* For {un}signed ints,
 	 vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
@@ -1137,8 +1097,8 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
     case E_SImode:
       {
 	vec<tree, va_gc> *params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree add_sub_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDE)
@@ -1148,10 +1108,10 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
 
 	tree call = altivec_resolve_overloaded_builtin (loc, add_sub_builtin,
 							params);
-	tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
-	tree ones_vector = build_vector_from_val (arg0_type, const1);
-	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
-					 arg2, ones_vector);
+	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
+	tree ones_vector = build_vector_from_val (types[0], const1);
+	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
+					 args[2], ones_vector);
 	params = make_tree_vector ();
 	vec_safe_push (params, call);
 	vec_safe_push (params, and_expr);
@@ -1175,45 +1135,29 @@ resolve_vec_adde_sube (resolution *res, rs6000_gen_builtins fcode,
 }
 
 /* Resolve an overloaded vec_addec or vec_subec call and return a tree
-   expression for the resolved call if successful.  NARGS is the number of
-   arguments to the call.  ARGLIST contains the arguments.  RES must be set
-   to indicate the status of the resolution attempt.  LOC contains statement
-   location information.  */
+   expression for the resolved call if successful.  ARGS contains the arguments
+   to the call.  TYPES contains their types.  RES must be set to indicate the
+   status of the resolution attempt.  LOC contains statement location
+   information.  */
 
 static tree
 resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
-			 vec<tree, va_gc> *arglist, unsigned nargs,
-			 location_t loc)
+			 tree *args, tree *types, location_t loc)
 {
   /* vec_addec and vec_subec needs to be special cased because there is
      no instruction for the (un)signed int version.  */
-  if (nargs != 3)
-    {
-      const char *name;
-      name = fcode == RS6000_OVLD_VEC_ADDEC ? "vec_addec" : "vec_subec";
-      error ("builtin %qs only accepts 3 arguments", name);
-      *res = resolved;
-      return error_mark_node;
-    }
-
-  tree arg0 = (*arglist)[0];
-  tree arg0_type = TREE_TYPE (arg0);
-  tree arg1 = (*arglist)[1];
-  tree arg1_type = TREE_TYPE (arg1);
-  tree arg2 = (*arglist)[2];
-  tree arg2_type = TREE_TYPE (arg2);
 
   /* All 3 arguments must be vectors of (signed or unsigned) (int or
      __int128) and the types must be compatible.  */
-  if (TREE_CODE (arg0_type) != VECTOR_TYPE
-      || !lang_hooks.types_compatible_p (arg0_type, arg1_type)
-      || !lang_hooks.types_compatible_p (arg1_type, arg2_type))
+  if (TREE_CODE (types[0]) != VECTOR_TYPE
+      || !lang_hooks.types_compatible_p (types[0], types[1])
+      || !lang_hooks.types_compatible_p (types[1], types[2]))
     {
       *res = resolved_bad;
       return error_mark_node;
     }
 
-  switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+  switch (TYPE_MODE (TREE_TYPE (types[0])))
     {
       /* For {un}signed ints,
 	   vec_addec (va, vb, carryv) ==
@@ -1224,11 +1168,11 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
       {
 	/* Use save_expr to ensure that operands used more than once that may
 	   have side effects (like calls) are only evaluated once.  */
-	arg0 = save_expr (arg0);
-	arg1 = save_expr (arg1);
+	args[0] = save_expr (args[0]);
+	args[1] = save_expr (args[1]);
 	vec<tree, va_gc> *params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree as_c_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDEC)
@@ -1239,8 +1183,8 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
 	tree call1 = altivec_resolve_overloaded_builtin (loc, as_c_builtin,
 							 params);
 	params = make_tree_vector ();
-	vec_safe_push (params, arg0);
-	vec_safe_push (params, arg1);
+	vec_safe_push (params, args[0]);
+	vec_safe_push (params, args[1]);
 
 	tree as_builtin;
 	if (fcode == RS6000_OVLD_VEC_ADDEC)
@@ -1250,10 +1194,10 @@ resolve_vec_addec_subec (resolution *res, rs6000_gen_builtins fcode,
 
 	tree call2 = altivec_resolve_overloaded_builtin (loc, as_builtin,
 							 params);
-	tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
-	tree ones_vector = build_vector_from_val (arg0_type, const1);
-	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
-					 arg2, ones_vector);
+	tree const1 = build_int_cstu (TREE_TYPE (types[0]), 1);
+	tree ones_vector = build_vector_from_val (types[0], const1);
+	tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, types[0],
+					 args[2], ones_vector);
 	params = make_tree_vector ();
 	vec_safe_push (params, call2);
 	vec_safe_push (params, and_expr);
@@ -1783,78 +1727,22 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 	     "%<vec_lvsr%> is deprecated for little endian; use "
 	     "assignment for unaligned loads and stores");
 
-  /* Some overloads require special handling.  */
-  /* FIXME: Could we simplify the helper functions if we gathered arguments
-     and types into arrays first?  */
-  tree returned_expr = NULL;
-  resolution res = unresolved;
-  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
-  unsigned int nargs = vec_safe_length (arglist);
-
-  switch (fcode)
-    {
-    case RS6000_OVLD_VEC_MUL:
-      returned_expr = resolve_vec_mul (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_CMPNE:
-      returned_expr = resolve_vec_cmpne (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_ADDE:
-    case RS6000_OVLD_VEC_SUBE:
-      returned_expr = resolve_vec_adde_sube (&res, fcode, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_ADDEC:
-    case RS6000_OVLD_VEC_SUBEC:
-      returned_expr = resolve_vec_addec_subec (&res, fcode, arglist, nargs,
-					       loc);
-      break;
-
-    case RS6000_OVLD_VEC_SPLATS:
-    case RS6000_OVLD_VEC_PROMOTE:
-      returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
-      break;
-
-    case RS6000_OVLD_VEC_EXTRACT:
-      returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_INSERT:
-      returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
-      break;
-
-    case RS6000_OVLD_VEC_STEP:
-      returned_expr = resolve_vec_step (&res, arglist, nargs);
-      break;
-
-    default:
-      ;
-    }
-
-  if (res == resolved)
-    return returned_expr;
-
-  /* "Regular" built-in functions and overloaded functions share a namespace
-     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
-     only has information for the overloaded functions, so we need an
-     adjusted index for that.  */
-  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
-
-  if (res == resolved_bad)
-    {
-      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
-      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
-      return error_mark_node;
-    }
-
   /* Gather the arguments and their types into arrays for easier handling.  */
   tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
   tree types[MAX_OVLD_ARGS];
   tree args[MAX_OVLD_ARGS];
   unsigned int n;
 
+  /* Count the number of expected arguments.  */
+  unsigned expected_args = 0;
+  for (tree chain = fnargs;
+       chain && !VOID_TYPE_P (TREE_VALUE (chain));
+       chain = TREE_CHAIN (chain))
+    expected_args++;
+
+  vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
+  unsigned int nargs = vec_safe_length (arglist);
+
   for (n = 0;
        !VOID_TYPE_P (TREE_VALUE (fnargs)) && n < nargs;
        fnargs = TREE_CHAIN (fnargs), n++)
@@ -1915,10 +1803,72 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
     }
 
   /* If the number of arguments did not match the prototype, return NULL
-     and the generic code will issue the appropriate error message.  */
-  if (!VOID_TYPE_P (TREE_VALUE (fnargs)) || n < nargs)
+     and the generic code will issue the appropriate error message.  Skip
+     this test for functions where we don't fully describe all the possible
+     overload signatures in rs6000-overload.def (because they aren't relevant
+     to the expansion here).  If we don't, we get confusing error messages.  */
+  /* As an example, for vec_splats we have:
+
+; There are no actual builtins for vec_splats.  There is special handling for
+; this in altivec_resolve_overloaded_builtin in rs6000-c.cc, where the call
+; is replaced by a constructor.  The single overload here causes
+; __builtin_vec_splats to be registered with the front end so that can happen.
+[VEC_SPLATS, vec_splats, __builtin_vec_splats]
+  vsi __builtin_vec_splats (vsi);
+    ABS_V4SI SPLATS_FAKERY
+
+    So even though __builtin_vec_splats accepts all vector types, the
+    infrastructure cheats and just records one prototype.  We end up getting
+    an error message that refers to this specific prototype even when we
+    are handling a different argument type.  That is completely confusing
+    to the user, so it's best to let these cases be handled individually
+    in the resolve_vec_splats, etc., helper functions.  */
+
+  if (n != expected_args
+      && !(fcode == RS6000_OVLD_VEC_PROMOTE
+	   || fcode == RS6000_OVLD_VEC_SPLATS
+	   || fcode == RS6000_OVLD_VEC_EXTRACT
+	   || fcode == RS6000_OVLD_VEC_INSERT
+	   || fcode == RS6000_OVLD_VEC_STEP))
     return NULL;
 
+  /* Some overloads require special handling.  */
+  tree returned_expr = NULL;
+  resolution res = unresolved;
+
+  if (fcode == RS6000_OVLD_VEC_MUL)
+    returned_expr = resolve_vec_mul (&res, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_CMPNE)
+    returned_expr = resolve_vec_cmpne (&res, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_ADDE || fcode == RS6000_OVLD_VEC_SUBE)
+    returned_expr = resolve_vec_adde_sube (&res, fcode, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_ADDEC || fcode == RS6000_OVLD_VEC_SUBEC)
+    returned_expr = resolve_vec_addec_subec (&res, fcode, args, types, loc);
+  else if (fcode == RS6000_OVLD_VEC_SPLATS || fcode == RS6000_OVLD_VEC_PROMOTE)
+    returned_expr = resolve_vec_splats (&res, fcode, arglist, nargs);
+  else if (fcode == RS6000_OVLD_VEC_EXTRACT)
+    returned_expr = resolve_vec_extract (&res, arglist, nargs, loc);
+  else if (fcode == RS6000_OVLD_VEC_INSERT)
+    returned_expr = resolve_vec_insert (&res, arglist, nargs, loc);
+  else if (fcode == RS6000_OVLD_VEC_STEP)
+    returned_expr = resolve_vec_step (&res, arglist, nargs);
+
+  if (res == resolved)
+    return returned_expr;
+
+  /* "Regular" built-in functions and overloaded functions share a namespace
+     for some arrays, like rs6000_builtin_decls.  But rs6000_overload_info
+     only has information for the overloaded functions, so we need an
+     adjusted index for that.  */
+  unsigned int adj_fcode = fcode - RS6000_OVLD_NONE;
+
+  if (res == resolved_bad)
+    {
+      const char *name = rs6000_overload_info[adj_fcode].ovld_name;
+      error ("invalid parameter combination for AltiVec intrinsic %qs", name);
+      return error_mark_node;
+    }
+
   bool unsupported_builtin = false;
   rs6000_gen_builtins instance_code;
   bool supported = false;
-- 
2.27.0



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

* Re: [PATCH v3 1/8] rs6000: More factoring of overload processing
  2022-02-03 14:44         ` [PATCH v3 " Bill Schmidt
@ 2022-02-04  1:24           ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-02-04  1:24 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

Hi!

On Thu, Feb 03, 2022 at 08:44:48AM -0600, Bill Schmidt wrote:
> Although the previous patch was correct, the logic around what to do when
> the number of arguments is wrong was still hard to understand.  It should
> be better now.  I'm now explicitly counting the number of expected arguments
> and comparing against that.  The way the argument list is represented ensures
> there is always at least one element in the argument chain, by terminating
> the chain with an argument type of void, which is why the previous logic was
> so convoluted.

Aha :-)

> +  /* Count the number of expected arguments.  */
> +  unsigned expected_args = 0;
> +  for (tree chain = fnargs;
> +       chain && !VOID_TYPE_P (TREE_VALUE (chain));
> +       chain = TREE_CHAIN (chain))
> +    expected_args++;

FOREACH_FUNCTION_ARGS?

> +    So even though __builtin_vec_splats accepts all vector types, the
> +    infrastructure cheats and just records one prototype.  We end up getting
> +    an error message that refers to this specific prototype even when we
> +    are handling a different argument type.  That is completely confusing
> +    to the user, so it's best to let these cases be handled individually
> +    in the resolve_vec_splats, etc., helper functions.  */
> +
> +  if (n != expected_args
> +      && !(fcode == RS6000_OVLD_VEC_PROMOTE
> +	   || fcode == RS6000_OVLD_VEC_SPLATS
> +	   || fcode == RS6000_OVLD_VEC_EXTRACT
> +	   || fcode == RS6000_OVLD_VEC_INSERT
> +	   || fcode == RS6000_OVLD_VEC_STEP))
>      return NULL;

Even I can understand that!  Thank you! :-)

Okay for trunk.


Segher

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

* Re: [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8
  2022-01-28 17:50 ` [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8 Bill Schmidt
@ 2022-02-07 15:48   ` Bill Schmidt
  2022-03-30 18:04   ` Segher Boessenkool
  1 sibling, 0 replies; 37+ messages in thread
From: Bill Schmidt @ 2022-02-07 15:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: dje.gcc, segher

Hi Segher,

Thanks for all the reviews for this series!  I'd like to gently ping the last two patches.

BR,
Bill

On 1/28/22 11:50 AM, Bill Schmidt via Gcc-patches wrote:
> As the subject states.  Fixing this is accomplished by moving the built-ins
> to the correct stanzas, [altivec] and [vsx].
>
> Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
> Is this okay for trunk?
>
> Thanks,
> Bill
>
>
> 2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>
>
> gcc/
> 	* config/rs6000/rs6000-builtin.def (NEG_V16QI): Move to [altivec]
> 	stanza.
> 	(NEG_V4SF): Likewise.
> 	(NEG_V4SI): Likewise.
> 	(NEG_V8HI): Likewise.
> 	(NEG_V2DF): Move to [vsx] stanza.
> 	(NEG_V2DI): Likewise.
> ---
>  gcc/config/rs6000/rs6000-builtins.def | 36 +++++++++++++--------------
>  1 file changed, 18 insertions(+), 18 deletions(-)
>
> diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
> index 2bb997a5279..c8f0cf332eb 100644
> --- a/gcc/config/rs6000/rs6000-builtins.def
> +++ b/gcc/config/rs6000/rs6000-builtins.def
> @@ -410,6 +410,18 @@
>    const vss __builtin_altivec_nabs_v8hi (vss);
>      NABS_V8HI nabsv8hi2 {}
>
> +  const vsc __builtin_altivec_neg_v16qi (vsc);
> +    NEG_V16QI negv16qi2 {}
> +
> +  const vf __builtin_altivec_neg_v4sf (vf);
> +    NEG_V4SF negv4sf2 {}
> +
> +  const vsi __builtin_altivec_neg_v4si (vsi);
> +    NEG_V4SI negv4si2 {}
> +
> +  const vss __builtin_altivec_neg_v8hi (vss);
> +    NEG_V8HI negv8hi2 {}
> +
>    void __builtin_altivec_stvebx (vsc, signed long, void *);
>      STVEBX altivec_stvebx {stvec}
>
> @@ -1175,6 +1187,12 @@
>    const vsll __builtin_altivec_nabs_v2di (vsll);
>      NABS_V2DI nabsv2di2 {}
>
> +  const vd __builtin_altivec_neg_v2df (vd);
> +    NEG_V2DF negv2df2 {}
> +
> +  const vsll __builtin_altivec_neg_v2di (vsll);
> +    NEG_V2DI negv2di2 {}
> +
>    void __builtin_altivec_stvx_v2df (vd, signed long, void *);
>      STVX_V2DF altivec_stvx_v2df {stvec}
>
> @@ -2118,24 +2136,6 @@
>    const vus __builtin_altivec_nand_v8hi_uns (vus, vus);
>      NAND_V8HI_UNS nandv8hi3 {}
>
> -  const vsc __builtin_altivec_neg_v16qi (vsc);
> -    NEG_V16QI negv16qi2 {}
> -
> -  const vd __builtin_altivec_neg_v2df (vd);
> -    NEG_V2DF negv2df2 {}
> -
> -  const vsll __builtin_altivec_neg_v2di (vsll);
> -    NEG_V2DI negv2di2 {}
> -
> -  const vf __builtin_altivec_neg_v4sf (vf);
> -    NEG_V4SF negv4sf2 {}
> -
> -  const vsi __builtin_altivec_neg_v4si (vsi);
> -    NEG_V4SI negv4si2 {}
> -
> -  const vss __builtin_altivec_neg_v8hi (vss);
> -    NEG_V8HI negv8hi2 {}
> -
>    const vsc __builtin_altivec_orc_v16qi (vsc, vsc);
>      ORC_V16QI orcv16qi3 {}
>

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

* rs6000 patch ping: [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]
  2022-01-28 17:50 ` [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004] Bill Schmidt
@ 2022-03-15 13:18   ` Jakub Jelinek
  2022-03-30 12:28     ` rs6000 patch ping^2: " Jakub Jelinek
  2022-03-30 23:07     ` rs6000 patch ping: " Segher Boessenkool
  2022-03-30 17:41   ` will schmidt
  1 sibling, 2 replies; 37+ messages in thread
From: Jakub Jelinek @ 2022-03-15 13:18 UTC (permalink / raw)
  To: Segher Boessenkool, dje; +Cc: gcc-patches, bill.schmidt

On Fri, Jan 28, 2022 at 11:50:26AM -0600, Bill Schmidt via Gcc-patches wrote:
> PR104004 caught some misses on my part in converting to the new built-in
> function infrastructure.  In particular, I forgot to mark all of the "nosoft"
> built-ins, and one of those should also have been marked "no32bit".
> 
> Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
> Is this okay for trunk?
> 
> Thanks,
> Bill
> 
> 
> 2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>
> 
> gcc/
> 	* config/rs6000/rs6000-builtin.def (MFFSL): Mark nosoft.
> 	(MTFSB0): Likewise.
> 	(MTFSB1): Likewise.
> 	(SET_FPSCR_RN): Likewise.
> 	(SET_FPSCR_DRN): Mark nosoft and no32bit.

This patch fixes a P1 regression and from my (limited) understanding
doesn't depend on any other patch in the series.

Is this ok for trunk (I agree some testcase coverage would be nice)?

> diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
> index c8f0cf332eb..98619a649e3 100644
> --- a/gcc/config/rs6000/rs6000-builtins.def
> +++ b/gcc/config/rs6000/rs6000-builtins.def
> @@ -215,7 +215,7 @@
>  ; processors, this builtin automatically falls back to mffs on older
>  ; platforms.  Thus it appears here in the [always] stanza.
>    double __builtin_mffsl ();
> -    MFFSL rs6000_mffsl {}
> +    MFFSL rs6000_mffsl {nosoft}
>  
>  ; This is redundant with __builtin_pack_ibm128, as it requires long
>  ; double to be __ibm128.  Should probably be deprecated.
> @@ -226,10 +226,10 @@
>      MFTB rs6000_mftb_di {32bit}
>  
>    void __builtin_mtfsb0 (const int<0,31>);
> -    MTFSB0 rs6000_mtfsb0 {}
> +    MTFSB0 rs6000_mtfsb0 {nosoft}
>  
>    void __builtin_mtfsb1 (const int<0,31>);
> -    MTFSB1 rs6000_mtfsb1 {}
> +    MTFSB1 rs6000_mtfsb1 {nosoft}
>  
>    void __builtin_mtfsf (const int<0,255>, double);
>      MTFSF rs6000_mtfsf {}
> @@ -238,7 +238,7 @@
>      PACK_IF packif {}
>  
>    void __builtin_set_fpscr_rn (const int[0,3]);
> -    SET_FPSCR_RN rs6000_set_fpscr_rn {}
> +    SET_FPSCR_RN rs6000_set_fpscr_rn {nosoft}
>  
>    const double __builtin_unpack_ibm128 (__ibm128, const int<0,1>);
>      UNPACK_IF unpackif {}
> @@ -2969,7 +2969,7 @@
>      PACK_TD packtd {}
>  
>    void __builtin_set_fpscr_drn (const int[0,7]);
> -    SET_FPSCR_DRN rs6000_set_fpscr_drn {}
> +    SET_FPSCR_DRN rs6000_set_fpscr_drn {nosoft,no32bit}
>  
>    const unsigned long long __builtin_unpack_dec128 (_Decimal128, \
>                                                      const int<0,1>);
> -- 
> 2.27.0

	Jakub


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

* rs6000 patch ping^2: [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]
  2022-03-15 13:18   ` rs6000 patch ping: " Jakub Jelinek
@ 2022-03-30 12:28     ` Jakub Jelinek
  2022-03-30 23:07     ` rs6000 patch ping: " Segher Boessenkool
  1 sibling, 0 replies; 37+ messages in thread
From: Jakub Jelinek @ 2022-03-30 12:28 UTC (permalink / raw)
  To: Segher Boessenkool, dje, bill.schmidt, gcc-patches

On Tue, Mar 15, 2022 at 02:18:00PM +0100, Jakub Jelinek via Gcc-patches wrote:
> On Fri, Jan 28, 2022 at 11:50:26AM -0600, Bill Schmidt via Gcc-patches wrote:
> > PR104004 caught some misses on my part in converting to the new built-in
> > function infrastructure.  In particular, I forgot to mark all of the "nosoft"
> > built-ins, and one of those should also have been marked "no32bit".
> > 
> > Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
> > Is this okay for trunk?
> > 
> > Thanks,
> > Bill
> > 
> > 
> > 2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>
> > 
> > gcc/
> > 	* config/rs6000/rs6000-builtin.def (MFFSL): Mark nosoft.
> > 	(MTFSB0): Likewise.
> > 	(MTFSB1): Likewise.
> > 	(SET_FPSCR_RN): Likewise.
> > 	(SET_FPSCR_DRN): Mark nosoft and no32bit.
> 
> This patch fixes a P1 regression and from my (limited) understanding
> doesn't depend on any other patch in the series.
> 
> Is this ok for trunk (I agree some testcase coverage would be nice)?

I'd like to ping this again.

> > diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def
> > index c8f0cf332eb..98619a649e3 100644
> > --- a/gcc/config/rs6000/rs6000-builtins.def
> > +++ b/gcc/config/rs6000/rs6000-builtins.def
> > @@ -215,7 +215,7 @@
> >  ; processors, this builtin automatically falls back to mffs on older
> >  ; platforms.  Thus it appears here in the [always] stanza.
> >    double __builtin_mffsl ();
> > -    MFFSL rs6000_mffsl {}
> > +    MFFSL rs6000_mffsl {nosoft}
> >  
> >  ; This is redundant with __builtin_pack_ibm128, as it requires long
> >  ; double to be __ibm128.  Should probably be deprecated.
> > @@ -226,10 +226,10 @@
> >      MFTB rs6000_mftb_di {32bit}
> >  
> >    void __builtin_mtfsb0 (const int<0,31>);
> > -    MTFSB0 rs6000_mtfsb0 {}
> > +    MTFSB0 rs6000_mtfsb0 {nosoft}
> >  
> >    void __builtin_mtfsb1 (const int<0,31>);
> > -    MTFSB1 rs6000_mtfsb1 {}
> > +    MTFSB1 rs6000_mtfsb1 {nosoft}
> >  
> >    void __builtin_mtfsf (const int<0,255>, double);
> >      MTFSF rs6000_mtfsf {}
> > @@ -238,7 +238,7 @@
> >      PACK_IF packif {}
> >  
> >    void __builtin_set_fpscr_rn (const int[0,3]);
> > -    SET_FPSCR_RN rs6000_set_fpscr_rn {}
> > +    SET_FPSCR_RN rs6000_set_fpscr_rn {nosoft}
> >  
> >    const double __builtin_unpack_ibm128 (__ibm128, const int<0,1>);
> >      UNPACK_IF unpackif {}
> > @@ -2969,7 +2969,7 @@
> >      PACK_TD packtd {}
> >  
> >    void __builtin_set_fpscr_drn (const int[0,7]);
> > -    SET_FPSCR_DRN rs6000_set_fpscr_drn {}
> > +    SET_FPSCR_DRN rs6000_set_fpscr_drn {nosoft,no32bit}
> >  
> >    const unsigned long long __builtin_unpack_dec128 (_Decimal128, \
> >                                                      const int<0,1>);
> > -- 
> > 2.27.0
> 
> 	Jakub

	Jakub


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

* Re: [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]
  2022-01-28 17:50 ` [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004] Bill Schmidt
  2022-03-15 13:18   ` rs6000 patch ping: " Jakub Jelinek
@ 2022-03-30 17:41   ` will schmidt
  1 sibling, 0 replies; 37+ messages in thread
From: will schmidt @ 2022-03-30 17:41 UTC (permalink / raw)
  To: Bill Schmidt, gcc-patches; +Cc: dje.gcc, segher, jakub

On Fri, 2022-01-28 at 11:50 -0600, Bill Schmidt via Gcc-patches wrote:
> PR104004 caught some misses on my part in converting to the new
> built-in
> function infrastructure.  In particular, I forgot to mark all of the
> "nosoft"
> built-ins, and one of those should also have been marked "no32bit".
> 
> Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
> Is this okay for trunk?
> 
> Thanks,
> Bill
> 
Hi,

The patch here seems reasonable to me. 
There are comments/subsequent pings that include commentary about
additional test coverage.

I see all of the builtins referenced here appear to be touched by
the existing test  gcc.target/powerpc/test_fpscr_drn_builtin.c .
I could create a variation of that test forcing ! hard_dfp in case that
would help, though i'm uncertain the value there. 

Thanks
-Will

> 
> 2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>
> 
> gcc/
> 	* config/rs6000/rs6000-builtin.def (MFFSL): Mark nosoft.
> 	(MTFSB0): Likewise.
> 	(MTFSB1): Likewise.
> 	(SET_FPSCR_RN): Likewise.
> 	(SET_FPSCR_DRN): Mark nosoft and no32bit.
> ---
>  gcc/config/rs6000/rs6000-builtins.def | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/gcc/config/rs6000/rs6000-builtins.def
> b/gcc/config/rs6000/rs6000-builtins.def
> index c8f0cf332eb..98619a649e3 100644
> --- a/gcc/config/rs6000/rs6000-builtins.def
> +++ b/gcc/config/rs6000/rs6000-builtins.def
> @@ -215,7 +215,7 @@
>  ; processors, this builtin automatically falls back to mffs on older
>  ; platforms.  Thus it appears here in the [always] stanza.
>    double __builtin_mffsl ();
> -    MFFSL rs6000_mffsl {}
> +    MFFSL rs6000_mffsl {nosoft}
> 
>  ; This is redundant with __builtin_pack_ibm128, as it requires long
>  ; double to be __ibm128.  Should probably be deprecated.
> @@ -226,10 +226,10 @@
>      MFTB rs6000_mftb_di {32bit}
> 
>    void __builtin_mtfsb0 (const int<0,31>);
> -    MTFSB0 rs6000_mtfsb0 {}
> +    MTFSB0 rs6000_mtfsb0 {nosoft}
> 
>    void __builtin_mtfsb1 (const int<0,31>);
> -    MTFSB1 rs6000_mtfsb1 {}
> +    MTFSB1 rs6000_mtfsb1 {nosoft}
> 
>    void __builtin_mtfsf (const int<0,255>, double);
>      MTFSF rs6000_mtfsf {}
> @@ -238,7 +238,7 @@
>      PACK_IF packif {}
> 
>    void __builtin_set_fpscr_rn (const int[0,3]);
> -    SET_FPSCR_RN rs6000_set_fpscr_rn {}
> +    SET_FPSCR_RN rs6000_set_fpscr_rn {nosoft}
> 
>    const double __builtin_unpack_ibm128 (__ibm128, const int<0,1>);
>      UNPACK_IF unpackif {}
> @@ -2969,7 +2969,7 @@
>      PACK_TD packtd {}
> 
>    void __builtin_set_fpscr_drn (const int[0,7]);
> -    SET_FPSCR_DRN rs6000_set_fpscr_drn {}
> +    SET_FPSCR_DRN rs6000_set_fpscr_drn {nosoft,no32bit}
> 
>    const unsigned long long __builtin_unpack_dec128 (_Decimal128, \
>                                                      const int<0,1>);


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

* Re: [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8
  2022-01-28 17:50 ` [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8 Bill Schmidt
  2022-02-07 15:48   ` Bill Schmidt
@ 2022-03-30 18:04   ` Segher Boessenkool
  1 sibling, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-03-30 18:04 UTC (permalink / raw)
  To: Bill Schmidt; +Cc: gcc-patches, dje.gcc

On Fri, Jan 28, 2022 at 11:50:25AM -0600, Bill Schmidt wrote:
> As the subject states.  Fixing this is accomplished by moving the built-ins
> to the correct stanzas, [altivec] and [vsx].
> 
> Bootstrapped and tested on powerpc64le-linux-gnu with no regressions.
> Is this okay for trunk?

Okay for trunk.  Thanks!

I'll apply it myself :-)


Segher


> 2022-01-27  Bill Schmidt  <wschmidt@linux.ibm.com>
> 
> gcc/
> 	* config/rs6000/rs6000-builtin.def (NEG_V16QI): Move to [altivec]
> 	stanza.
> 	(NEG_V4SF): Likewise.
> 	(NEG_V4SI): Likewise.
> 	(NEG_V8HI): Likewise.
> 	(NEG_V2DF): Move to [vsx] stanza.
> 	(NEG_V2DI): Likewise.

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

* Re: rs6000 patch ping: [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]
  2022-03-15 13:18   ` rs6000 patch ping: " Jakub Jelinek
  2022-03-30 12:28     ` rs6000 patch ping^2: " Jakub Jelinek
@ 2022-03-30 23:07     ` Segher Boessenkool
  2022-03-31 22:17       ` Segher Boessenkool
  1 sibling, 1 reply; 37+ messages in thread
From: Segher Boessenkool @ 2022-03-30 23:07 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: dje, gcc-patches, bill.schmidt

On Tue, Mar 15, 2022 at 02:18:00PM +0100, Jakub Jelinek wrote:
> On Fri, Jan 28, 2022 at 11:50:26AM -0600, Bill Schmidt via Gcc-patches wrote:
> > PR104004 caught some misses on my part in converting to the new built-in
> > function infrastructure.  In particular, I forgot to mark all of the "nosoft"
> > built-ins, and one of those should also have been marked "no32bit".

> This patch fixes a P1 regression and from my (limited) understanding
> doesn't depend on any other patch in the series.

It depends on 3/8 which was only partially applied (or not at all even?)
It is a mess :-(

I'll look into it tomorrow.


Segher

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

* Re: rs6000 patch ping: [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004]
  2022-03-30 23:07     ` rs6000 patch ping: " Segher Boessenkool
@ 2022-03-31 22:17       ` Segher Boessenkool
  0 siblings, 0 replies; 37+ messages in thread
From: Segher Boessenkool @ 2022-03-31 22:17 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: bill.schmidt, gcc-patches, dje

On Wed, Mar 30, 2022 at 06:07:26PM -0500, Segher Boessenkool wrote:
> On Tue, Mar 15, 2022 at 02:18:00PM +0100, Jakub Jelinek wrote:
> > On Fri, Jan 28, 2022 at 11:50:26AM -0600, Bill Schmidt via Gcc-patches wrote:
> > > PR104004 caught some misses on my part in converting to the new built-in
> > > function infrastructure.  In particular, I forgot to mark all of the "nosoft"
> > > built-ins, and one of those should also have been marked "no32bit".
> 
> > This patch fixes a P1 regression and from my (limited) understanding
> > doesn't depend on any other patch in the series.
> 
> It depends on 3/8 which was only partially applied (or not at all even?)
> It is a mess :-(
> 
> I'll look into it tomorrow.

3/8 wasn't applied at all.  I did some surgery to apply this 8/8 though.


Segher

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

end of thread, other threads:[~2022-03-31 22:18 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-28 17:50 [PATCH 0/8] rs6000: Built-in function cleanups and bug fixes Bill Schmidt
2022-01-28 17:50 ` [PATCH 1/8] rs6000: More factoring of overload processing Bill Schmidt
2022-01-28 19:11   ` Segher Boessenkool
2022-01-28 21:19     ` Bill Schmidt
2022-01-28 23:09       ` Segher Boessenkool
2022-02-01 14:49     ` [PATCH v2 " Bill Schmidt
2022-02-01 21:48       ` Segher Boessenkool
2022-02-02 18:46         ` Bill Schmidt
2022-02-03 14:44         ` [PATCH v3 " Bill Schmidt
2022-02-04  1:24           ` Segher Boessenkool
2022-01-28 17:50 ` [PATCH 2/8] rs6000: Don't #ifdef "short" built-in names Bill Schmidt
2022-01-28 20:32   ` Segher Boessenkool
2022-01-28 21:21     ` Bill Schmidt
2022-01-28 17:50 ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
2022-01-28 23:24   ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
2022-01-31 17:21     ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
2022-01-31 17:28       ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x, y> form Segher Boessenkool
2022-01-31 17:31         ` [PATCH 3/8] rs6000: Convert <x> built-in constraints to <x,y> form Bill Schmidt
2022-02-01 14:53         ` [PATCH v2 3/8] rs6000: Unify error messages for built-in constant restrictions Bill Schmidt
2022-02-01 22:16           ` Segher Boessenkool
2022-01-28 17:50 ` [PATCH 4/8] rs6000: Consolidate target built-ins code Bill Schmidt
2022-01-31 21:32   ` Segher Boessenkool
2022-01-31 22:01     ` Bill Schmidt
2022-01-31 22:33       ` Segher Boessenkool
2022-01-28 17:50 ` [PATCH 5/8] rs6000: Fix LE code gen for vec_cnt[lt]z_lsbb [PR95082] Bill Schmidt
2022-02-01 23:01   ` Segher Boessenkool
2022-01-28 17:50 ` [PATCH 6/8] rs6000: Remove -m[no-]fold-gimple flag [PR103686] Bill Schmidt
2022-02-02 23:21   ` Segher Boessenkool
2022-01-28 17:50 ` [PATCH 7/8] rs6000: vec_neg built-ins wrongly require POWER8 Bill Schmidt
2022-02-07 15:48   ` Bill Schmidt
2022-03-30 18:04   ` Segher Boessenkool
2022-01-28 17:50 ` [PATCH 8/8] rs6000: Fix some missing built-in attributes [PR104004] Bill Schmidt
2022-03-15 13:18   ` rs6000 patch ping: " Jakub Jelinek
2022-03-30 12:28     ` rs6000 patch ping^2: " Jakub Jelinek
2022-03-30 23:07     ` rs6000 patch ping: " Segher Boessenkool
2022-03-31 22:17       ` Segher Boessenkool
2022-03-30 17:41   ` will schmidt

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