diff mbox

Remove target.vectorize.builtin_vec_perm

Message ID 4EA07263.4040302@redhat.com
State New
Headers show

Commit Message

Richard Henderson Oct. 20, 2011, 7:11 p.m. UTC
Since the vectorizer has been changed to emit VEC_PERM_EXPR,
I've now removed the hook and the implementations of that hook.

For the x86 target I also removed the builtins themselves.
For the rs6000 and spu targets, I've left that detail to the
port maintainers; I don't know what interfaces are actually
public.

Tested on x86_64-linux.  Committed.


r~
gcc/
+	* target.def (builtin_vec_perm): Remove.
+	* doc/tm.texi.in (TARGET_VECTORIZE_BUILTIN_VEC_PERM): Remove.
+
+	* config/i386/i386.c (ix86_expand_vec_perm_builtin): Remove.
+	(IX86_BUILTIN_VEC_PERM_*): Remove.
+	(bdesc_args): Remove vec_perm builtins
+	(ix86_expand_builtin): Likewise.
+	(ix86_expand_vec_perm_const_1): Rename from
+	ix86_expand_vec_perm_builtin_1.
+	(extract_vec_perm_cst): Merge into...
+	(ix86_vectorize_vec_perm_const_ok): ... here.  Rename from
+	ix86_vectorize_builtin_vec_perm_ok.
+	(TARGET_VECTORIZE_BUILTIN_VEC_PERM): Remove.
+
+	* config/rs6000/rs6000.c (rs6000_builtin_vec_perm): Remove.
+	(TARGET_VECTORIZE_BUILTIN_VEC_PERM): Remove.
+
+	* config/spu/spu.c (spu_builtin_vec_perm): Remove.
+	(TARGET_VECTORIZE_BUILTIN_VEC_PERM): Remove.

gcc/testsuite/
+	* gcc.target/i386/vperm-v2df.c, gcc.target/i386/vperm-v2di.c,
+	gcc.target/i386/vperm-v4sf-1.c, gcc.target/i386/vperm-v4sf-2.c, 
+	gcc.target/i386/vperm-v4si-1.c, gcc.target/i386/vperm-v4si-2.c:
+	Use __builtin_shuffle.
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4af4e59..7750356 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2509,7 +2509,6 @@  static void ix86_compute_frame_layout (struct ix86_frame *);
 static bool ix86_expand_vector_init_one_nonzero (bool, enum machine_mode,
 						 rtx, rtx, int);
 static void ix86_add_new_builtins (HOST_WIDE_INT);
-static rtx ix86_expand_vec_perm_builtin (tree);
 static tree ix86_canonical_va_list_type (tree);
 static void predict_jump (int);
 static unsigned int split_stack_prologue_scratch_regno (void);
@@ -25058,19 +25057,6 @@  enum ix86_builtins
 
   IX86_BUILTIN_CVTUDQ2PS,
 
-  IX86_BUILTIN_VEC_PERM_V2DF,
-  IX86_BUILTIN_VEC_PERM_V4SF,
-  IX86_BUILTIN_VEC_PERM_V2DI,
-  IX86_BUILTIN_VEC_PERM_V4SI,
-  IX86_BUILTIN_VEC_PERM_V8HI,
-  IX86_BUILTIN_VEC_PERM_V16QI,
-  IX86_BUILTIN_VEC_PERM_V2DI_U,
-  IX86_BUILTIN_VEC_PERM_V4SI_U,
-  IX86_BUILTIN_VEC_PERM_V8HI_U,
-  IX86_BUILTIN_VEC_PERM_V16QI_U,
-  IX86_BUILTIN_VEC_PERM_V4DF,
-  IX86_BUILTIN_VEC_PERM_V8SF,
-
   /* FMA4 instructions.  */
   IX86_BUILTIN_VFMADDSS,
   IX86_BUILTIN_VFMADDSD,
@@ -25779,19 +25765,6 @@  static const struct builtin_description bdesc_args[] =
   /* SSE2 */
   { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_shufpd, "__builtin_ia32_shufpd", IX86_BUILTIN_SHUFPD, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_INT },
 
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v2df", IX86_BUILTIN_VEC_PERM_V2DF, UNKNOWN, (int) V2DF_FTYPE_V2DF_V2DF_V2DI },
-  { OPTION_MASK_ISA_SSE, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4sf", IX86_BUILTIN_VEC_PERM_V4SF, UNKNOWN, (int) V4SF_FTYPE_V4SF_V4SF_V4SI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v2di", IX86_BUILTIN_VEC_PERM_V2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4si", IX86_BUILTIN_VEC_PERM_V4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v8hi", IX86_BUILTIN_VEC_PERM_V8HI, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v16qi", IX86_BUILTIN_VEC_PERM_V16QI, UNKNOWN, (int) V16QI_FTYPE_V16QI_V16QI_V16QI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v2di_u", IX86_BUILTIN_VEC_PERM_V2DI_U, UNKNOWN, (int) V2UDI_FTYPE_V2UDI_V2UDI_V2UDI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4si_u", IX86_BUILTIN_VEC_PERM_V4SI_U, UNKNOWN, (int) V4USI_FTYPE_V4USI_V4USI_V4USI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v8hi_u", IX86_BUILTIN_VEC_PERM_V8HI_U, UNKNOWN, (int) V8UHI_FTYPE_V8UHI_V8UHI_V8UHI },
-  { OPTION_MASK_ISA_SSE2, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v16qi_u", IX86_BUILTIN_VEC_PERM_V16QI_U, UNKNOWN, (int) V16UQI_FTYPE_V16UQI_V16UQI_V16UQI },
-  { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v4df", IX86_BUILTIN_VEC_PERM_V4DF, UNKNOWN, (int) V4DF_FTYPE_V4DF_V4DF_V4DI },
-  { OPTION_MASK_ISA_AVX, CODE_FOR_nothing, "__builtin_ia32_vec_perm_v8sf", IX86_BUILTIN_VEC_PERM_V8SF, UNKNOWN, (int) V8SF_FTYPE_V8SF_V8SF_V8SI },
-
   { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_movmskpd, "__builtin_ia32_movmskpd", IX86_BUILTIN_MOVMSKPD, UNKNOWN, (int) INT_FTYPE_V2DF  },
   { OPTION_MASK_ISA_SSE2, CODE_FOR_sse2_pmovmskb, "__builtin_ia32_pmovmskb128", IX86_BUILTIN_PMOVMSKB128, UNKNOWN, (int) INT_FTYPE_V16QI },
   { OPTION_MASK_ISA_SSE2, CODE_FOR_sqrtv2df2, "__builtin_ia32_sqrtpd", IX86_BUILTIN_SQRTPD, UNKNOWN, (int) V2DF_FTYPE_V2DF },
@@ -28700,20 +28673,6 @@  ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
     case IX86_BUILTIN_VEC_SET_V16QI:
       return ix86_expand_vec_set_builtin (exp);
 
-    case IX86_BUILTIN_VEC_PERM_V2DF:
-    case IX86_BUILTIN_VEC_PERM_V4SF:
-    case IX86_BUILTIN_VEC_PERM_V2DI:
-    case IX86_BUILTIN_VEC_PERM_V4SI:
-    case IX86_BUILTIN_VEC_PERM_V8HI:
-    case IX86_BUILTIN_VEC_PERM_V16QI:
-    case IX86_BUILTIN_VEC_PERM_V2DI_U:
-    case IX86_BUILTIN_VEC_PERM_V4SI_U:
-    case IX86_BUILTIN_VEC_PERM_V8HI_U:
-    case IX86_BUILTIN_VEC_PERM_V16QI_U:
-    case IX86_BUILTIN_VEC_PERM_V4DF:
-    case IX86_BUILTIN_VEC_PERM_V8SF:
-      return ix86_expand_vec_perm_builtin (exp);
-
     case IX86_BUILTIN_INFQ:
     case IX86_BUILTIN_HUGE_VALQ:
       {
@@ -31930,9 +31889,6 @@  struct expand_vec_perm_d
 
 static bool expand_vec_perm_1 (struct expand_vec_perm_d *d);
 static bool expand_vec_perm_broadcast_1 (struct expand_vec_perm_d *d);
-static int extract_vec_perm_cst (struct expand_vec_perm_d *, tree);
-static bool ix86_vectorize_builtin_vec_perm_ok (tree vec_type, tree mask);
-
 
 /* Get a vector mode of the same size as the original but with elements
    twice as wide.  This is only guaranteed to apply to integral vectors.  */
@@ -34621,64 +34577,6 @@  ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
 }
 
 
-/* Implement targetm.vectorize.builtin_vec_perm.  */
-
-static tree
-ix86_vectorize_builtin_vec_perm (tree vec_type, tree *mask_type)
-{
-  tree itype = TREE_TYPE (vec_type);
-  bool u = TYPE_UNSIGNED (itype);
-  enum machine_mode vmode = TYPE_MODE (vec_type);
-  enum ix86_builtins fcode;
-  bool ok = TARGET_SSE2;
-
-  switch (vmode)
-    {
-    case V4DFmode:
-      ok = TARGET_AVX;
-      fcode = IX86_BUILTIN_VEC_PERM_V4DF;
-      goto get_di;
-    case V2DFmode:
-      fcode = IX86_BUILTIN_VEC_PERM_V2DF;
-    get_di:
-      itype = ix86_get_builtin_type (IX86_BT_DI);
-      break;
-
-    case V8SFmode:
-      ok = TARGET_AVX;
-      fcode = IX86_BUILTIN_VEC_PERM_V8SF;
-      goto get_si;
-    case V4SFmode:
-      ok = TARGET_SSE;
-      fcode = IX86_BUILTIN_VEC_PERM_V4SF;
-    get_si:
-      itype = ix86_get_builtin_type (IX86_BT_SI);
-      break;
-
-    case V2DImode:
-      fcode = u ? IX86_BUILTIN_VEC_PERM_V2DI_U : IX86_BUILTIN_VEC_PERM_V2DI;
-      break;
-    case V4SImode:
-      fcode = u ? IX86_BUILTIN_VEC_PERM_V4SI_U : IX86_BUILTIN_VEC_PERM_V4SI;
-      break;
-    case V8HImode:
-      fcode = u ? IX86_BUILTIN_VEC_PERM_V8HI_U : IX86_BUILTIN_VEC_PERM_V8HI;
-      break;
-    case V16QImode:
-      fcode = u ? IX86_BUILTIN_VEC_PERM_V16QI_U : IX86_BUILTIN_VEC_PERM_V16QI;
-      break;
-    default:
-      ok = false;
-      break;
-    }
-
-  if (!ok)
-    return NULL_TREE;
-
-  *mask_type = itype;
-  return ix86_builtins[(int) fcode];
-}
-
 /* Return a vector mode with twice as many elements as VMODE.  */
 /* ??? Consider moving this to a table generated by genmodes.c.  */
 
@@ -36395,12 +36293,12 @@  expand_vec_perm_vpshufb4_vpermq2 (struct expand_vec_perm_d *d)
   return true;
 }
 
-/* The guts of ix86_expand_vec_perm_builtin, also used by the ok hook.
+/* The guts of ix86_expand_vec_perm_const, also used by the ok hook.
    With all of the interface bits taken care of, perform the expansion
    in D and return true on success.  */
 
 static bool
-ix86_expand_vec_perm_builtin_1 (struct expand_vec_perm_d *d)
+ix86_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
 {
   /* Try a single instruction expansion.  */
   if (expand_vec_perm_1 (d))
@@ -36459,179 +36357,6 @@  ix86_expand_vec_perm_builtin_1 (struct expand_vec_perm_d *d)
   return false;
 }
 
-/* Extract the values from the vector CST into the permutation array in D.
-   Return 0 on error, 1 if all values from the permutation come from the
-   first vector, 2 if all values from the second vector, and 3 otherwise.  */
-
-static int
-extract_vec_perm_cst (struct expand_vec_perm_d *d, tree cst)
-{
-  tree list = TREE_VECTOR_CST_ELTS (cst);
-  unsigned i, nelt = d->nelt;
-  int ret = 0;
-
-  for (i = 0; i < nelt; ++i, list = TREE_CHAIN (list))
-    {
-      unsigned HOST_WIDE_INT e;
-
-      if (!host_integerp (TREE_VALUE (list), 1))
-	return 0;
-      e = tree_low_cst (TREE_VALUE (list), 1);
-      if (e >= 2 * nelt)
-	return 0;
-
-      ret |= (e < nelt ? 1 : 2);
-      d->perm[i] = e;
-    }
-  gcc_assert (list == NULL);
-
-  /* For all elements from second vector, fold the elements to first.  */
-  if (ret == 2)
-    for (i = 0; i < nelt; ++i)
-      d->perm[i] -= nelt;
-
-  return ret;
-}
-
-static rtx
-ix86_expand_vec_perm_builtin (tree exp)
-{
-  struct expand_vec_perm_d d;
-  tree arg0, arg1, arg2;
-  bool maybe_retry = false;
-
-  arg0 = CALL_EXPR_ARG (exp, 0);
-  arg1 = CALL_EXPR_ARG (exp, 1);
-  arg2 = CALL_EXPR_ARG (exp, 2);
-
-  d.vmode = TYPE_MODE (TREE_TYPE (arg0));
-  d.nelt = GET_MODE_NUNITS (d.vmode);
-  d.testing_p = false;
-  gcc_assert (VECTOR_MODE_P (d.vmode));
-
-  if (TREE_CODE (arg2) != VECTOR_CST)
-    {
-      error_at (EXPR_LOCATION (exp),
-		"vector permutation requires vector constant");
-      goto exit_error;
-    }
-
-  switch (extract_vec_perm_cst (&d, arg2))
-    {
-    default:
-      gcc_unreachable();
-
-    case 0:
-      error_at (EXPR_LOCATION (exp), "invalid vector permutation constant");
-      goto exit_error;
-
-    case 3:
-      if (!operand_equal_p (arg0, arg1, 0))
-	{
-	  d.op0 = expand_expr (arg0, NULL_RTX, d.vmode, EXPAND_NORMAL);
-	  d.op0 = force_reg (d.vmode, d.op0);
-	  d.op1 = expand_expr (arg1, NULL_RTX, d.vmode, EXPAND_NORMAL);
-	  d.op1 = force_reg (d.vmode, d.op1);
-	  break;
-	}
-
-      /* The elements of PERM do not suggest that only the first operand
-	 is used, but both operands are identical.  Allow easier matching
-	 of the permutation by folding the permutation into the single
-	 input vector.  */
-      {
-	unsigned i, nelt = d.nelt;
-	for (i = 0; i < nelt; ++i)
-	  if (d.perm[i] >= nelt)
-	    d.perm[i] -= nelt;
-	maybe_retry = true;
-      }
-      /* FALLTHRU */
-
-    case 1:
-      d.op0 = expand_expr (arg0, NULL_RTX, d.vmode, EXPAND_NORMAL);
-      d.op0 = force_reg (d.vmode, d.op0);
-      d.op1 = d.op0;
-      break;
-
-    case 2:
-      d.op0 = expand_expr (arg1, NULL_RTX, d.vmode, EXPAND_NORMAL);
-      d.op0 = force_reg (d.vmode, d.op0);
-      d.op1 = d.op0;
-      break;
-    }
-
-  d.target = gen_reg_rtx (d.vmode);
-  if (ix86_expand_vec_perm_builtin_1 (&d))
-    return d.target;
-
-  /* If the mask says both arguments are needed, but they are the same,
-     the above tried to expand with d.op0 == d.op1.  If that didn't work,
-     retry with d.op0 != d.op1 as that is what testing has been done with.  */
-  if (maybe_retry)
-    {
-      rtx seq;
-      bool ok;
-
-      extract_vec_perm_cst (&d, arg2);
-      d.op1 = gen_reg_rtx (d.vmode);
-      start_sequence ();
-      ok = ix86_expand_vec_perm_builtin_1 (&d);
-      seq = get_insns ();
-      end_sequence ();
-      if (ok)
-	{
-	  emit_move_insn (d.op1, d.op0);
-	  emit_insn (seq);
-	  return d.target;
-	}
-    }
-
-  /* For compiler generated permutations, we should never got here, because
-     the compiler should also be checking the ok hook.  But since this is a
-     builtin the user has access too, so don't abort.  */
-  switch (d.nelt)
-    {
-    case 2:
-      sorry ("vector permutation (%d %d)", d.perm[0], d.perm[1]);
-      break;
-    case 4:
-      sorry ("vector permutation (%d %d %d %d)",
-	     d.perm[0], d.perm[1], d.perm[2], d.perm[3]);
-      break;
-    case 8:
-      sorry ("vector permutation (%d %d %d %d %d %d %d %d)",
-	     d.perm[0], d.perm[1], d.perm[2], d.perm[3],
-	     d.perm[4], d.perm[5], d.perm[6], d.perm[7]);
-      break;
-    case 16:
-      sorry ("vector permutation "
-	     "(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)",
-	     d.perm[0], d.perm[1], d.perm[2], d.perm[3],
-	     d.perm[4], d.perm[5], d.perm[6], d.perm[7],
-	     d.perm[8], d.perm[9], d.perm[10], d.perm[11],
-	     d.perm[12], d.perm[13], d.perm[14], d.perm[15]);
-      break;
-    case 32:
-      sorry ("vector permutation "
-	     "(%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d "
-	     "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d)",
-	     d.perm[0], d.perm[1], d.perm[2], d.perm[3],
-	     d.perm[4], d.perm[5], d.perm[6], d.perm[7],
-	     d.perm[8], d.perm[9], d.perm[10], d.perm[11],
-	     d.perm[12], d.perm[13], d.perm[14], d.perm[15],
-	     d.perm[16], d.perm[17], d.perm[18], d.perm[19],
-	     d.perm[20], d.perm[21], d.perm[22], d.perm[23],
-	     d.perm[24], d.perm[25], d.perm[26], d.perm[27],
-	     d.perm[28], d.perm[29], d.perm[30], d.perm[31]);
-      break;
-    default:
-      gcc_unreachable ();
-    }
- exit_error:
-  return CONST0_RTX (d.vmode);
-}
-
 bool
 ix86_expand_vec_perm_const (rtx operands[4])
 {
@@ -36693,7 +36418,7 @@  ix86_expand_vec_perm_const (rtx operands[4])
       break;
     }
 
-  if (ix86_expand_vec_perm_builtin_1 (&d))
+  if (ix86_expand_vec_perm_const_1 (&d))
     return true;
 
   /* If the mask says both arguments are needed, but they are the same,
@@ -36707,7 +36432,7 @@  ix86_expand_vec_perm_const (rtx operands[4])
       memcpy (d.perm, perm, sizeof (perm));
       d.op1 = gen_reg_rtx (d.vmode);
       start_sequence ();
-      ok = ix86_expand_vec_perm_builtin_1 (&d);
+      ok = ix86_expand_vec_perm_const_1 (&d);
       seq = get_insns ();
       end_sequence ();
       if (ok)
@@ -36724,14 +36449,15 @@  ix86_expand_vec_perm_const (rtx operands[4])
 /* Implement targetm.vectorize.builtin_vec_perm_ok.  */
 
 static bool
-ix86_vectorize_builtin_vec_perm_ok (tree vec_type, tree mask)
+ix86_vectorize_vec_perm_const_ok (tree vec_type, tree mask)
 {
   struct expand_vec_perm_d d;
-  int vec_mask;
+  unsigned int i, nelt, which;
   bool ret, one_vec;
+  tree list;
 
   d.vmode = TYPE_MODE (vec_type);
-  d.nelt = GET_MODE_NUNITS (d.vmode);
+  d.nelt = nelt = GET_MODE_NUNITS (d.vmode);
   d.testing_p = true;
 
   /* Given sufficient ISA support we can just return true here
@@ -36749,13 +36475,29 @@  ix86_vectorize_builtin_vec_perm_ok (tree vec_type, tree mask)
 	return true;
     }
 
-  vec_mask = extract_vec_perm_cst (&d, mask);
+  /* Extract the values from the vector CST into the permutation
+     array in D.  */
+  list = TREE_VECTOR_CST_ELTS (mask);
+  for (i = which = 0; i < nelt; ++i, list = TREE_CHAIN (list))
+    {
+      unsigned HOST_WIDE_INT e;
 
-  /* Check whether the mask can be applied to the vector type.  */
-  if (vec_mask < 0 || vec_mask > 3)
-    return false;
+      gcc_checking_assert (host_integerp (TREE_VALUE (list), 1));
+      e = tree_low_cst (TREE_VALUE (list), 1);
+      gcc_assert (e < 2 * nelt);
+
+      which |= (e < nelt ? 1 : 2);
+      d.perm[i] = e;
+    }
+  gcc_assert (list == NULL);
 
-  one_vec = (vec_mask != 3);
+  /* For all elements from second vector, fold the elements to first.  */
+  if (which == 2)
+    for (i = 0; i < nelt; ++i)
+      d.perm[i] -= nelt;
+
+  /* Check whether the mask can be applied to the vector type.  */
+  one_vec = (which != 3);
 
   /* Implementable with shufps or pshufd.  */
   if (one_vec && (d.vmode == V4SFmode || d.vmode == V4SImode))
@@ -36769,7 +36511,7 @@  ix86_vectorize_builtin_vec_perm_ok (tree vec_type, tree mask)
     d.op1 = gen_raw_REG (d.vmode, LAST_VIRTUAL_REGISTER + 3);
 
   start_sequence ();
-  ret = ix86_expand_vec_perm_builtin_1 (&d);
+  ret = ix86_expand_vec_perm_const_1 (&d);
   end_sequence ();
 
   return ret;
@@ -38137,12 +37879,9 @@  ix86_autovectorize_vector_sizes (void)
 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST
 #define TARGET_VECTORIZE_BUILTIN_VECTORIZATION_COST \
   ix86_builtin_vectorization_cost
-#undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
-#define TARGET_VECTORIZE_BUILTIN_VEC_PERM \
-  ix86_vectorize_builtin_vec_perm
 #undef TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK
 #define TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK \
-  ix86_vectorize_builtin_vec_perm_ok
+  ix86_vectorize_vec_perm_const_ok
 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE \
   ix86_preferred_simd_mode
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d97ddd3..80833c4 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -988,7 +988,6 @@  static tree rs6000_builtin_mask_for_load (void);
 static tree rs6000_builtin_mul_widen_even (tree);
 static tree rs6000_builtin_mul_widen_odd (tree);
 static tree rs6000_builtin_conversion (unsigned int, tree, tree);
-static tree rs6000_builtin_vec_perm (tree, tree *);
 static bool rs6000_builtin_support_vector_misalignment (enum
 							machine_mode,
 							const_tree,
@@ -1407,8 +1406,6 @@  static const struct attribute_spec rs6000_attribute_table[] =
 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
-#undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
-#define TARGET_VECTORIZE_BUILTIN_VEC_PERM rs6000_builtin_vec_perm
 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
 #define TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT		\
   rs6000_builtin_support_vector_misalignment
@@ -3475,65 +3472,6 @@  rs6000_builtin_support_vector_misalignment (enum machine_mode mode,
   return false;
 }
 
-/* Implement targetm.vectorize.builtin_vec_perm.  */
-tree
-rs6000_builtin_vec_perm (tree type, tree *mask_element_type)
-{
-  tree inner_type = TREE_TYPE (type);
-  bool uns_p = TYPE_UNSIGNED (inner_type);
-  tree d;
-
-  *mask_element_type = unsigned_char_type_node;
-
-  switch (TYPE_MODE (type))
-    {
-    case V16QImode:
-      d = (uns_p
-	   ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI_UNS]
-	   : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_16QI]);
-      break;
-
-    case V8HImode:
-      d = (uns_p
-	   ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI_UNS]
-	   : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_8HI]);
-      break;
-
-    case V4SImode:
-      d = (uns_p
-	   ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI_UNS]
-	   : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SI]);
-      break;
-
-    case V4SFmode:
-      d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_4SF];
-      break;
-
-    case V2DFmode:
-      if (!TARGET_ALLOW_DF_PERMUTE)
-	return NULL_TREE;
-
-      d = rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DF];
-      break;
-
-    case V2DImode:
-      if (!TARGET_ALLOW_DF_PERMUTE)
-	return NULL_TREE;
-
-      d = (uns_p
-	   ? rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI_UNS]
-	   : rs6000_builtin_decls[ALTIVEC_BUILTIN_VPERM_2DI]);
-      break;
-
-    default:
-      return NULL_TREE;
-    }
-
-  gcc_assert (d);
-  return d;
-}
-
-
 /* Implement targetm.vectorize.builtin_vectorization_cost.  */
 static int
 rs6000_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 734c2be..0bab5cf 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -218,7 +218,6 @@  static tree spu_builtin_mul_widen_odd (tree);
 static tree spu_builtin_mask_for_load (void);
 static int spu_builtin_vectorization_cost (enum vect_cost_for_stmt, tree, int);
 static bool spu_vector_alignment_reachable (const_tree, bool);
-static tree spu_builtin_vec_perm (tree, tree *);
 static enum machine_mode spu_addr_space_pointer_mode (addr_space_t);
 static enum machine_mode spu_addr_space_address_mode (addr_space_t);
 static bool spu_addr_space_subset_p (addr_space_t, addr_space_t);
@@ -449,9 +448,6 @@  static void spu_setup_incoming_varargs (cumulative_args_t cum,
 #undef TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE
 #define TARGET_VECTORIZE_VECTOR_ALIGNMENT_REACHABLE spu_vector_alignment_reachable
 
-#undef TARGET_VECTORIZE_BUILTIN_VEC_PERM
-#define TARGET_VECTORIZE_BUILTIN_VEC_PERM spu_builtin_vec_perm
-
 #undef TARGET_LIBGCC_CMP_RETURN_MODE
 #define TARGET_LIBGCC_CMP_RETURN_MODE spu_libgcc_cmp_return_mode
 
@@ -6958,49 +6954,6 @@  spu_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed
   return true;
 }
 
-/* Implement targetm.vectorize.builtin_vec_perm.  */
-tree
-spu_builtin_vec_perm (tree type, tree *mask_element_type)
-{
-  *mask_element_type = unsigned_char_type_node;
-
-  switch (TYPE_MODE (type))
-    {
-    case V16QImode:
-      if (TYPE_UNSIGNED (type))
-        return spu_builtin_decls[SPU_SHUFFLE_0];
-      else
-        return spu_builtin_decls[SPU_SHUFFLE_1];
-
-    case V8HImode:
-      if (TYPE_UNSIGNED (type))
-        return spu_builtin_decls[SPU_SHUFFLE_2];
-      else
-        return spu_builtin_decls[SPU_SHUFFLE_3];
-
-    case V4SImode:
-      if (TYPE_UNSIGNED (type))
-        return spu_builtin_decls[SPU_SHUFFLE_4];
-      else
-        return spu_builtin_decls[SPU_SHUFFLE_5];
-
-    case V2DImode:
-      if (TYPE_UNSIGNED (type))
-        return spu_builtin_decls[SPU_SHUFFLE_6];
-      else
-        return spu_builtin_decls[SPU_SHUFFLE_7];
-
-    case V4SFmode:
-      return spu_builtin_decls[SPU_SHUFFLE_8];
-
-    case V2DFmode:
-      return spu_builtin_decls[SPU_SHUFFLE_9];
-
-    default:
-      return NULL_TREE;
-    }
-}
-
 /* Return the appropriate mode for a named address pointer.  */
 static enum machine_mode
 spu_addr_space_pointer_mode (addr_space_t addrspace)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index f9e4260..c52753a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5711,12 +5711,8 @@  misalignment value (@var{misalign}).
 Return true if vector alignment is reachable (by peeling N iterations) for the given type.
 @end deftypefn
 
-@deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_VEC_PERM (tree @var{type}, tree *@var{mask_element_type})
-Target builtin that implements vector permute.
-@end deftypefn
-
 @deftypefn {Target Hook} bool TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK (tree @var{vec_type}, tree @var{mask})
-Return true if a vector created for @code{builtin_vec_perm} is valid.
+Return true if a vector created for @code{vec_perm_const} is valid.
 @end deftypefn
 
 @deftypefn {Target Hook} tree TARGET_VECTORIZE_BUILTIN_CONVERSION (unsigned @var{code}, tree @var{dest_type}, tree @var{src_type})
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index e7e2588..22e82ee 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -5649,12 +5649,8 @@  misalignment value (@var{misalign}).
 Return true if vector alignment is reachable (by peeling N iterations) for the given type.
 @end deftypefn
 
-@hook TARGET_VECTORIZE_BUILTIN_VEC_PERM
-Target builtin that implements vector permute.
-@end deftypefn
-
 @hook TARGET_VECTORIZE_BUILTIN_VEC_PERM_OK
-Return true if a vector created for @code{builtin_vec_perm} is valid.
+Return true if a vector created for @code{vec_perm_const} is valid.
 @end deftypefn
 
 @hook TARGET_VECTORIZE_BUILTIN_CONVERSION
diff --git a/gcc/target.def b/gcc/target.def
index c3bec0e..c9d6067 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -985,12 +985,6 @@  DEFHOOK
  bool, (const_tree type, bool is_packed),
  default_builtin_vector_alignment_reachable)
 
-/* Target builtin that implements vector permute.  */
-DEFHOOK
-(builtin_vec_perm,
- "",
- tree, (tree type, tree *mask_element_type), NULL)
-
 /* Return true if a vector created for builtin_vec_perm is valid.  */
 DEFHOOK
 (builtin_vec_perm_ok,
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v2df.c b/gcc/testsuite/gcc.target/i386/vperm-v2df.c
index 40a5130..5aefc05 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v2df.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v2df.c
@@ -16,7 +16,7 @@  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
 #define assert(T) ((T) || (__builtin_trap (), 0))
 
 #define TEST(E0, E1) \
-  b.v = __builtin_ia32_vec_perm_v2df (i[0].v, i[1].v, (IV){E0, E1}); \
+  b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1}); \
   c.s[0] = i[0].s[E0]; \
   c.s[1] = i[0].s[E1]; \
   __asm__("" : : : "memory"); \
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v2di.c b/gcc/testsuite/gcc.target/i386/vperm-v2di.c
index 8e30083..282cce6 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v2di.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v2di.c
@@ -16,7 +16,7 @@  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
 #define assert(T) ((T) || (__builtin_trap (), 0))
 
 #define TEST(E0, E1) \
-  b.v = __builtin_ia32_vec_perm_v2di (i[0].v, i[1].v, (IV){E0, E1}); \
+  b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1}); \
   c.s[0] = i[0].s[E0]; \
   c.s[1] = i[0].s[E1]; \
   __asm__("" : : : "memory"); \
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c b/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
index 23608b3..f16c34b 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4sf-1.c
@@ -16,7 +16,7 @@  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
 #define assert(T) ((T) || (__builtin_trap (), 0))
 
 #define TEST(E0, E1, E2, E3) \
-  b.v = __builtin_ia32_vec_perm_v4sf (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
+  b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
   c.s[0] = i[0].s[E0]; \
   c.s[1] = i[0].s[E1]; \
   c.s[2] = i[0].s[E2]; \
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v4sf-2.c b/gcc/testsuite/gcc.target/i386/vperm-v4sf-2.c
index a0d4987..12a4623 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v4sf-2.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4sf-2.c
@@ -15,7 +15,7 @@  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
 #define assert(T) ((T) || (__builtin_trap (), 0))
 
 #define TEST(E0, E1, E2, E3) \
-  b.v = __builtin_ia32_vec_perm_v4sf (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
+  b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
   c.s[0] = i[0].s[E0]; \
   c.s[1] = i[0].s[E1]; \
   c.s[2] = i[0].s[E2]; \
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v4si-1.c b/gcc/testsuite/gcc.target/i386/vperm-v4si-1.c
index 01b7c6f..4667f95 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v4si-1.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4si-1.c
@@ -16,7 +16,7 @@  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
 #define assert(T) ((T) || (__builtin_trap (), 0))
 
 #define TEST(E0, E1, E2, E3) \
-  b.v = __builtin_ia32_vec_perm_v4si (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
+  b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
   c.s[0] = i[0].s[E0]; \
   c.s[1] = i[0].s[E1]; \
   c.s[2] = i[0].s[E2]; \
diff --git a/gcc/testsuite/gcc.target/i386/vperm-v4si-2.c b/gcc/testsuite/gcc.target/i386/vperm-v4si-2.c
index 43f88ee..9304345 100644
--- a/gcc/testsuite/gcc.target/i386/vperm-v4si-2.c
+++ b/gcc/testsuite/gcc.target/i386/vperm-v4si-2.c
@@ -15,7 +15,7 @@  extern int memcmp (const void *, const void *, __SIZE_TYPE__);
 #define assert(T) ((T) || (__builtin_trap (), 0))
 
 #define TEST(E0, E1, E2, E3) \
-  b.v = __builtin_ia32_vec_perm_v4si (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
+  b.v = __builtin_shuffle (i[0].v, i[1].v, (IV){E0, E1, E2, E3}); \
   c.s[0] = i[0].s[E0]; \
   c.s[1] = i[0].s[E1]; \
   c.s[2] = i[0].s[E2]; \