[rs6000] PR89765: Multiple problems with vec-insert implementation on PowerPC

Message ID 7768bfc2-a945-a7a6-57d8-007f6674969d@linux.ibm.com
State New
Headers show
Series
  • [rs6000] PR89765: Multiple problems with vec-insert implementation on PowerPC
Related show

Commit Message

Kelvin Nilsen April 30, 2019, 4:04 p.m.
In combination with a related recently committed patch (https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00989.html), the attached patch resolves the issues described in this problem report.  This patch also includes tests to exercise the previously committed patch.

This patch includes redundant content from patch PR89424 (https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00994.html), which has been already been approved by Segher for trunk and backports to GCC 7 and 8 but is awaiting GCC 9 release.

The patch has been bootstrapped and tested without regressions on powerpc64le-unknown-linux-gnu (both P8 and P9) and on powerpc64-unknown-linux-gnu (P7 and P8, both -m32 and -m64).

Segher: After GCC9 release, is this ok for trunk and backports to GCC 7 and GCC8?

Jakub or Richi: Is this patch and the redundant PR89424 patch ok for backports to GCC9?

gcc/ChangeLog:

2019-04-30  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/89765
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
	In handling of ALTIVEC_BUILTIN_VEC_INSERT, use modular arithmetic
	to compute vector element selector for both constant and variable
	operands.
	* config/rs6000/rs6000.c (rs6000_expand_vector_extract): Add case
	to handle V1TImode vectors.

gcc/testsuite/ChangeLog:

2019-04-30  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/89765
	* gcc.target/powerpc/pr89765-mc.c: New test.
	* gcc.target/powerpc/vsx-builtin-10c.c: New test.
	* gcc.target/powerpc/vsx-builtin-10d.c: New test.
	* gcc.target/powerpc/vsx-builtin-11c.c: New test.
	* gcc.target/powerpc/vsx-builtin-11d.c: New test.
	* gcc.target/powerpc/vsx-builtin-12c.c: New test.
	* gcc.target/powerpc/vsx-builtin-12d.c: New test.
	* gcc.target/powerpc/vsx-builtin-13c.c: New test.
	* gcc.target/powerpc/vsx-builtin-13d.c: New test.
	* gcc.target/powerpc/vsx-builtin-14c.c: New test.
	* gcc.target/powerpc/vsx-builtin-14d.c: New test.
	* gcc.target/powerpc/vsx-builtin-15c.c: New test.
	* gcc.target/powerpc/vsx-builtin-15d.c: New test.
	* gcc.target/powerpc/vsx-builtin-16c.c: New test.
	* gcc.target/powerpc/vsx-builtin-16d.c: New test.
	* gcc.target/powerpc/vsx-builtin-17c.c: New test.
	* gcc.target/powerpc/vsx-builtin-17d.c: New test.
	* gcc.target/powerpc/vsx-builtin-18c.c: New test.
	* gcc.target/powerpc/vsx-builtin-18d.c: New test.
	* gcc.target/powerpc/vsx-builtin-19c.c: New test.
	* gcc.target/powerpc/vsx-builtin-19d.c: New test.
	* gcc.target/powerpc/vsx-builtin-20c.c: New test.
	* gcc.target/powerpc/vsx-builtin-20d.c: New test.
	* gcc.target/powerpc/vsx-builtin-9c.c: New test.
	* gcc.target/powerpc/vsx-builtin-9d.c: New test.
	* gcc.target/powerpc/vsx-builtin-13a.c (PR89424): Define this
	macro to increase coverage of test.
	* gcc.target/powerpc/vsx-builtin-13b.c (PR89424): Likewise.
	* gcc.target/powerpc/vsx-builtin-20a.c (PR89424): Likewise.
	* gcc.target/powerpc/vsx-builtin-20b.c (PR89424): Likewise.

Comments

Jakub Jelinek April 30, 2019, 5:09 p.m. | #1
On Tue, Apr 30, 2019 at 11:04:10AM -0500, Kelvin Nilsen wrote:
> 

> In combination with a related recently committed patch (https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00989.html), the attached patch resolves the issues described in this problem report.  This patch also includes tests to exercise the previously committed patch.

> 

> This patch includes redundant content from patch PR89424 (https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00994.html), which has been already been approved by Segher for trunk and backports to GCC 7 and 8 but is awaiting GCC 9 release.

> 

> The patch has been bootstrapped and tested without regressions on powerpc64le-unknown-linux-gnu (both P8 and P9) and on powerpc64-unknown-linux-gnu (P7 and P8, both -m32 and -m64).

> 

> Segher: After GCC9 release, is this ok for trunk and backports to GCC 7 and GCC8?

> 

> Jakub or Richi: Is this patch and the redundant PR89424 patch ok for backports to GCC9?


I'm not against backporting it for GCC 9.2, but would strongly prefer not to
backport before GCC 9.1 is released.  At least from what I've seen, you get
many wrong-code issues with the V1TImode on powerpc since many years ago,
so I don't see why it couldn't wait another week.

The only changes to GCC 9.1 now should be severe blockers.

> 2019-04-30  Kelvin Nilsen  <kelvin@gcc.gnu.org>

> 

> 	PR target/89765

> 	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):

> 	In handling of ALTIVEC_BUILTIN_VEC_INSERT, use modular arithmetic

> 	to compute vector element selector for both constant and variable

> 	operands.

> 	* config/rs6000/rs6000.c (rs6000_expand_vector_extract): Add case

> 	to handle V1TImode vectors.


	Jakub
Segher Boessenkool May 1, 2019, 3:14 p.m. | #2
On Tue, Apr 30, 2019 at 11:04:10AM -0500, Kelvin Nilsen wrote:
> 

> In combination with a related recently committed patch (https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00989.html), the attached patch resolves the issues described in this problem report.  This patch also includes tests to exercise the previously committed patch.

> 

> This patch includes redundant content from patch PR89424 (https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00994.html), which has been already been approved by Segher for trunk and backports to GCC 7 and 8 but is awaiting GCC 9 release.

> 

> The patch has been bootstrapped and tested without regressions on powerpc64le-unknown-linux-gnu (both P8 and P9) and on powerpc64-unknown-linux-gnu (P7 and P8, both -m32 and -m64).

> 

> Segher: After GCC9 release, is this ok for trunk and backports to GCC 7 and GCC8?


Okay for trunk.  If it tests fine everywhere, and GCC 9.1 has been released,
okay for 9, and after that, okay for 8 and 7, too.

Thanks!


Segher

Patch

Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 270584)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -6736,11 +6736,13 @@  altivec_resolve_overloaded_builtin (location_t loc
       /* If we can use the VSX xxpermdi instruction, use that for insert.  */
       mode = TYPE_MODE (arg1_type);
       if ((mode == V2DFmode || mode == V2DImode) && VECTOR_UNIT_VSX_P (mode)
-	  && TREE_CODE (arg2) == INTEGER_CST
-	  && wi::ltu_p (wi::to_wide (arg2), 2))
+	  && TREE_CODE (arg2) == INTEGER_CST)
 	{
+	  wide_int selector = wi::to_wide (arg2);
+	  selector = wi::umod_trunc (selector, 2);
 	  tree call = NULL_TREE;
 
+	  arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
 	  if (mode == V2DFmode)
 	    call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V2DF];
 	  else if (mode == V2DImode)
@@ -6752,11 +6754,12 @@  altivec_resolve_overloaded_builtin (location_t loc
 	    return build_call_expr (call, 3, arg1, arg0, arg2);
 	}
       else if (mode == V1TImode && VECTOR_UNIT_VSX_P (mode)
-	       && TREE_CODE (arg2) == INTEGER_CST
-	       && wi::eq_p (wi::to_wide (arg2), 0))
+	       && TREE_CODE (arg2) == INTEGER_CST)
 	{
 	  tree call = rs6000_builtin_decls[VSX_BUILTIN_VEC_SET_V1TI];
+	  wide_int selector = wi::zero(32);
 
+	  arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
 	  /* Note, __builtin_vec_insert_<xxx> has vector and scalar types
 	     reversed.  */
 	  return build_call_expr (call, 3, arg1, arg0, arg2);
@@ -6764,10 +6767,13 @@  altivec_resolve_overloaded_builtin (location_t loc
 
       /* Build *(((arg1_inner_type*)&(vector type){arg1})+arg2) = arg0. */
       arg1_inner_type = TREE_TYPE (arg1_type);
-      arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2,
-			      build_int_cst (TREE_TYPE (arg2),
-					     TYPE_VECTOR_SUBPARTS (arg1_type)
-					     - 1), 0);
+      if (TYPE_VECTOR_SUBPARTS (arg1_type) == 1)
+	arg2 = build_int_cst (TREE_TYPE (arg2), 0);
+      else
+	arg2 = build_binary_op (loc, BIT_AND_EXPR, arg2,
+				build_int_cst (TREE_TYPE (arg2),
+					       TYPE_VECTOR_SUBPARTS (arg1_type)
+					       - 1), 0);
       decl = build_decl (loc, VAR_DECL, NULL_TREE, arg1_type);
       DECL_EXTERNAL (decl) = 0;
       TREE_PUBLIC (decl) = 0;
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 270584)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -6944,6 +6944,10 @@  rs6000_expand_vector_extract (rtx target, rtx vec,
 
       switch (mode)
 	{
+	case E_V1TImode:
+	  emit_move_insn (target, gen_lowpart (TImode, vec));
+	  return;
+
 	case E_V2DFmode:
 	  emit_insn (gen_vsx_extract_v2df_var (target, vec, elt));
 	  return;
Index: gcc/testsuite/gcc.target/powerpc/pr89765-mc.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr89765-mc.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr89765-mc.c	(working copy)
@@ -0,0 +1,400 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O2" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#include <stdio.h>
+
+static vector unsigned __int128
+deoptimize_uint128 (vector unsigned __int128  a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+static vector unsigned long long int
+deoptimize_ulong (vector unsigned long long int a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+static vector unsigned int
+deoptimize_uint (vector unsigned int a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+static vector unsigned char
+deoptimize_uchar (vector unsigned char a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+static vector unsigned short
+deoptimize_ushort (vector unsigned short a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+__attribute ((noinline))
+vector unsigned __int128
+set_auto_n_uint128 (vector unsigned __int128 a, int n, unsigned __int128 x)
+{
+  return vec_insert (x, a, n);
+}
+
+__attribute ((noinline))
+vector unsigned long long int
+set_auto_n_ulong (vector unsigned long long int a, int n,
+		  unsigned long long int x)
+{
+  return vec_insert (x, a, n);
+}
+
+__attribute ((noinline))
+vector unsigned int
+set_auto_n_uint (vector unsigned int a, int n, unsigned int x)
+{
+  return vec_insert (x, a, n);
+}
+
+__attribute ((noinline))
+vector unsigned char
+set_auto_n_uchar (vector unsigned char a, int n, unsigned char x)
+{
+  return vec_insert (x, a, n);
+}
+
+__attribute ((noinline))
+vector unsigned short
+set_auto_n_ushort (vector unsigned short a, int n, unsigned short x)
+{
+  return vec_insert (x, a, n);
+}
+
+__attribute ((noinline))
+unsigned __int128
+get_auto_n_uint128 (vector unsigned __int128 a, int n)
+{
+  return vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned long long int
+get_auto_n_ulong (vector unsigned long long int a, int n)
+{
+  return vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned int
+get_auto_n_uint (vector unsigned int a, int n)
+{
+  return vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned char
+get_auto_n_uchar (vector unsigned char a, int n)
+{
+  return vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned short
+get_auto_n_ushort (vector unsigned short a, int n)
+{
+  return vec_extract (a, n);
+}
+
+int check_uint128_element (int i, unsigned __int128 entry)
+{
+  printf ("checking uint128 entry at index %d\n", i);
+
+  return (entry == ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
+		    | 0x0706050403020100ULL));
+}
+
+unsigned __int128 get_uint128_element (int i)
+{
+  return ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
+	  | 0x0706050403020100ULL);
+}
+
+int check_ulong_element (int i, unsigned long long int entry)
+{
+  printf ("checking ulong entry 0x%llx at index %d\n", entry, i);
+
+  switch (i % 2)
+    {
+      case 0: return (entry == 0x9999901010ULL);
+      case 1: return (entry == 0x7777733333ULL);
+      default:
+	return 0;
+    }
+}
+
+unsigned long long int get_ulong_element (int i)
+{
+  switch (i % 2)
+    {
+    case 0: return 0x9999901010ULL;
+    case 1: return 0x7777733333ULL;
+    }
+}
+
+int check_uint_element (int i, unsigned int entry)
+{
+  printf ("checking uint entry 0x%x at index %d\n", entry, i);
+
+  switch (i % 4)
+    {
+    case 0: return (entry == 0x99999);
+    case 1: return (entry == 0x01010);
+    case 2: return (entry == 0x77777);
+    case 3: return (entry == 0x33333);
+    default:
+      return 0;
+    }
+}
+
+unsigned int get_uint_element (int i)
+{
+  switch (i % 4)
+    {
+    case 0: return 0x99999;
+    case 1: return 0x01010;
+    case 2: return 0x77777;
+    case 3: return 0x33333;
+    }
+}
+
+int check_uchar_element (int i, unsigned char entry)
+{
+  printf ("checking uchar entry 0x%x at index %d\n", entry, i);
+  switch (i % 16)
+    {
+    case 0: return (entry == 0x90);
+    case 1: return (entry == 0x80);
+    case 2: return (entry == 0x70);
+    case 3: return (entry == 0x60);
+    case 4: return (entry == 0x50);
+    case 5: return (entry == 0x40);
+    case 6: return (entry == 0x30);
+    case 7: return (entry == 0x20);
+    case 8: return (entry == 0x10);
+    case 9: return (entry == 0xf0);
+    case 10: return (entry == 0xe0);
+    case 11: return (entry == 0xd0);
+    case 12: return (entry == 0xc0);
+    case 13: return (entry == 0xb0);
+    case 14: return (entry == 0xa0);
+    case 15: return (entry == 0xff);
+    default:
+      return 0;
+    }
+}
+
+unsigned char get_uchar_element (int i)
+{
+  switch (i % 16)
+    {
+    case 0: return 0x90;
+    case 1: return 0x80;
+    case 2: return 0x70;
+    case 3: return 0x60;
+    case 4: return 0x50;
+    case 5: return 0x40;
+    case 6: return 0x30;
+    case 7: return 0x20;
+    case 8: return 0x10;
+    case 9: return 0xf0;
+    case 10: return 0xe0;
+    case 11: return 0xd0;
+    case 12: return 0xc0;
+    case 13: return 0xb0;
+    case 14: return 0xa0;
+    case 15: return 0xff;
+    }
+}
+
+int check_ushort_element (int i, unsigned short entry)
+{
+  printf ("checking ushort entry 0x%x at index %d\n", entry, i);
+  switch (i % 8)
+    {
+    case 0: return (entry == 0x9988);
+    case 1: return (entry == 0x8877);
+    case 2: return (entry == 0x7766);
+    case 3: return (entry == 0x6655);
+    case 4: return (entry == 0x5544);
+    case 5: return (entry == 0x4433);
+    case 6: return (entry == 0x3322);
+    case 7: return (entry == 0x2211);
+    default:
+      return 0;
+    }
+}
+
+unsigned short get_ushort_element (int i)
+{
+  switch (i % 8)
+    {
+    case 0: return 0x9988;
+    case 1: return 0x8877;
+    case 2: return 0x7766;
+    case 3: return 0x6655;
+    case 4: return 0x5544;
+    case 5: return 0x4433;
+    case 6: return 0x3322;
+    case 7: return 0x2211;
+    }
+}
+
+vector unsigned __int128
+init_auto_uint128 (vector unsigned __int128 a)
+{
+  int i;
+  for (i = 0; i < 32; i += 3)
+    a = set_auto_n_uint128 (a, i, get_uint128_element (i));
+  return a;
+}
+
+void do_auto_uint128 (vector unsigned __int128 a)
+{
+  int i;
+  unsigned __int128 c;
+  for (i = 0; i < 32; i += 3)
+    {
+      c = get_auto_n_uint128 (a, i);
+      if (!check_uint128_element (i, c)) abort ();
+    }
+}
+
+vector unsigned long long int
+init_auto_ulong (vector unsigned long long int a)
+{
+  int i;
+  for (i = 0; i < 32; i += 3)
+    a = set_auto_n_ulong (a, i, get_ulong_element (i));
+  return a;
+}
+
+void do_auto_ulong (vector unsigned long long int a)
+{
+  int i;
+  unsigned long long int c;
+  for (i = 0; i < 32; i += 3)
+    {
+      c = get_auto_n_ulong (a, i);
+      if (!check_ulong_element (i, c)) abort ();
+    }
+ }
+
+vector unsigned int init_auto_uint (vector unsigned int a)
+{
+  int i;
+  for (i = 0; i < 32; i += 3)
+    a = set_auto_n_uint (a, i, get_uint_element (i));
+  return a;
+}
+
+void do_auto_uint (vector unsigned int a)
+{
+  int i;
+  unsigned int c;
+  for (i = 0; i < 32; i += 3)
+    {
+      c = get_auto_n_uint (a, i);
+      if (!check_uint_element (i, c)) abort ();
+    }
+ }
+
+vector unsigned short init_auto_ushort ( vector unsigned short a )
+{
+  int i;
+  for (i = 0; i < 32; i += 3)
+    a = set_auto_n_ushort (a, i, get_ushort_element (i));
+  return a;
+}
+
+void do_auto_ushort (vector unsigned short a)
+{
+  int i;
+  unsigned short c;
+  for (i = 0; i < 32; i += 3)
+    {
+      c = get_auto_n_ushort (a, i);
+      if (!check_ushort_element (i, c)) abort ();
+    }
+}
+
+vector unsigned char init_auto_uchar (vector unsigned char a)
+{
+  int i;
+  for (i = 0; i < 32; i += 3)
+    a = set_auto_n_uchar (a, i, get_uchar_element (i));
+  return a;
+}
+
+void do_auto_uchar (vector unsigned char a)
+{
+  int i;
+  unsigned char c;
+  for (i = 0; i < 32; i += 3)
+    {
+      c = get_auto_n_uchar (a, i);
+      if (!check_uchar_element (i, c)) abort ();
+    }
+}
+
+int
+main (void)
+{
+  size_t i;
+
+  vector unsigned __int128 u = { 0 };
+  vector unsigned __int128 du;
+
+  vector unsigned long long int v = { 0, 0 };
+  vector unsigned long long int dv;
+
+  vector unsigned int x = { 0, 0, 0, 0 };
+  vector unsigned int dx;
+
+  vector unsigned char y = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  vector unsigned char dy;
+
+  vector unsigned short z = { 0, 0, 0, 0, 0, 0, 0, 0 };
+  vector unsigned short dz;
+
+  du = init_auto_uint128 (u);
+  dv = init_auto_ulong (v);
+  dx = init_auto_uint (x);
+  dy = init_auto_uchar (y);
+  dz = init_auto_ushort (z);
+
+  du = deoptimize_uint128 (du);
+  dv = deoptimize_ulong (dv);
+  dx = deoptimize_uint (dx);
+  dy = deoptimize_uchar (dy);
+  dz = deoptimize_ushort (dz);
+
+  do_auto_uint128 (du);
+  do_auto_ulong (dv);
+  do_auto_uint (dx);
+  do_auto_uchar (dy);
+  do_auto_ushort (dz);
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-10c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-10c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-10c.c	(working copy)
@@ -0,0 +1,155 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector short s3 (vector short v, short x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector short s7 (vector short v, short x)
+{
+  return vec_insert (x, v, 7);
+}
+
+vector short s21 (vector short v, short x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector short s30 (vector short v, short x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector short ms3 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector short ms7 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 7);
+}
+
+vector short ms21 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector short ms30 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector short ci (vector short v, int i, short x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector short mci (vector short *vp, int i, short x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, short *argv[]) {
+  vector short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+  short s;
+
+  sv = s3 (sv, CONST6);
+  if (sv [3] != CONST6)
+    abort ();
+
+  sv = s7 (sv, CONST4);
+  if (sv [7] != CONST4)
+    abort ();
+
+  sv = s21 (sv, CONST3);
+  if (sv [5] != CONST3)
+    abort ();
+
+  sv = s30 (sv, CONST2);
+  if (sv [6] != CONST2)
+    abort ();
+
+  sv = ms3 (&sv, CONST5);
+  if (sv [3] != CONST5)
+    abort ();
+
+  sv = ms7 (&sv, CONST1);
+  if (sv [7] != CONST1)
+    abort ();
+
+  sv = ms21 (&sv, CONST2);
+  if (sv [5] != CONST2)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [6] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST6);
+  if (sv [5] != CONST6)
+    abort ();
+
+  sv = ci (sv, 2, CONST4);
+  if (sv [2] != CONST4)
+    abort ();
+
+  sv = ci (sv, 15, CONST3);
+  if (sv [7] != CONST3)
+    abort ();
+
+  sv = ci (sv, 28, CONST3);
+  if (sv [4] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 5, CONST3);
+  if (sv [5] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 12, CONST7);
+  if (sv [4] != CONST7)
+    abort ();
+
+  sv = mci (&sv, 25, CONST6);
+  if (sv [1] != CONST6)
+    abort ();
+
+  sv = mci (&sv, 16, CONST5);
+  if (sv [0] != CONST5)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-10d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-10d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-10d.c	(working copy)
@@ -0,0 +1,155 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O3" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector short s3 (vector short v, short x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector short s7 (vector short v, short x)
+{
+  return vec_insert (x, v, 7);
+}
+
+vector short s21 (vector short v, short x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector short s30 (vector short v, short x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector short ms3 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector short ms7 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 7);
+}
+
+vector short ms21 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector short ms30 (vector short *vp, short x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector short ci (vector short v, int i, short x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector short mci (vector short *vp, int i, short x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, short *argv[]) {
+  vector short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+  short s;
+
+  sv = s3 (sv, CONST6);
+  if (sv [3] != CONST6)
+    abort ();
+
+  sv = s7 (sv, CONST4);
+  if (sv [7] != CONST4)
+    abort ();
+
+  sv = s21 (sv, CONST3);
+  if (sv [5] != CONST3)
+    abort ();
+
+  sv = s30 (sv, CONST2);
+  if (sv [6] != CONST2)
+    abort ();
+
+  sv = ms3 (&sv, CONST5);
+  if (sv [3] != CONST5)
+    abort ();
+
+  sv = ms7 (&sv, CONST1);
+  if (sv [7] != CONST1)
+    abort ();
+
+  sv = ms21 (&sv, CONST2);
+  if (sv [5] != CONST2)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [6] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST6);
+  if (sv [5] != CONST6)
+    abort ();
+
+  sv = ci (sv, 2, CONST4);
+  if (sv [2] != CONST4)
+    abort ();
+
+  sv = ci (sv, 15, CONST3);
+  if (sv [7] != CONST3)
+    abort ();
+
+  sv = ci (sv, 28, CONST3);
+  if (sv [4] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 5, CONST3);
+  if (sv [5] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 12, CONST7);
+  if (sv [4] != CONST7)
+    abort ();
+
+  sv = mci (&sv, 25, CONST6);
+  if (sv [1] != CONST6)
+    abort ();
+
+  sv = mci (&sv, 16, CONST5);
+  if (sv [0] != CONST5)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-11c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-11c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-11c.c	(working copy)
@@ -0,0 +1,149 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector int s3 (vector int v, int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector int s1 (vector int v, int x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector int s21 (vector int v, int x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector int s30 (vector int v, int x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector int ms3  (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector int ms1 (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector int ms21 (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector int ms30 (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector int ci (vector int v, int i, int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector int mci(vector int *vp, int i, int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, int *argv[]) {
+  vector int sv = { CONST0, CONST1, CONST2, CONST3 };
+  int s;
+
+  sv = s3 (sv, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = s1 (sv, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = s21 (sv, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = s30 (sv, CONST1);
+  if (sv [2] != CONST1)
+    abort ();
+
+  sv = ms3 (&sv, CONST2);
+  if (sv [3] != CONST2)
+    abort ();
+
+  sv = ms1 (&sv, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = ms21 (&sv, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [2] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = ci (sv, 2, CONST3);
+  if (sv [2] != CONST3)
+    abort ();
+
+  sv = ci (sv, 15, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = ci (sv, 28, CONST3);
+  if (sv [0] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 5, CONST2);
+  if (sv [1] != CONST2)
+    abort ();
+
+  sv = mci (&sv, 12, CONST1);
+  if (sv [0] != CONST1)
+    abort ();
+
+  sv = mci (&sv, 25, CONST2);
+  if (sv [1] != CONST2)
+    abort ();
+
+  sv = mci (&sv, 16, CONST3);
+  if (sv [0] != CONST3)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-11d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-11d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-11d.c	(working copy)
@@ -0,0 +1,149 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O3" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector int s3 (vector int v, int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector int s1 (vector int v, int x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector int s21 (vector int v, int x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector int s30 (vector int v, int x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector int ms3  (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector int ms1 (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector int ms21 (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector int ms30 (vector int *vp, int x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector int ci (vector int v, int i, int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector int mci(vector int *vp, int i, int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, int *argv[]) {
+  vector int sv = { CONST0, CONST1, CONST2, CONST3 };
+  int s;
+
+  sv = s3 (sv, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = s1 (sv, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = s21 (sv, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = s30 (sv, CONST1);
+  if (sv [2] != CONST1)
+    abort ();
+
+  sv = ms3 (&sv, CONST2);
+  if (sv [3] != CONST2)
+    abort ();
+
+  sv = ms1 (&sv, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = ms21 (&sv, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [2] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = ci (sv, 2, CONST3);
+  if (sv [2] != CONST3)
+    abort ();
+
+  sv = ci (sv, 15, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = ci (sv, 28, CONST3);
+  if (sv [0] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 5, CONST2);
+  if (sv [1] != CONST2)
+    abort ();
+
+  sv = mci (&sv, 12, CONST1);
+  if (sv [0] != CONST1)
+    abort ();
+
+  sv = mci (&sv, 25, CONST2);
+  if (sv [1] != CONST2)
+    abort ();
+
+  sv = mci (&sv, 16, CONST3);
+  if (sv [0] != CONST3)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-12c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-12c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-12c.c	(working copy)
@@ -0,0 +1,112 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(31415926539LL)
+#define CONST1		(2 * 31415926539LL)
+#define CONST2		(3 * 31415926539LL)
+#define CONST3		(4 * 31415926539LL)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector long long int e0 (vector long long int v, long long int x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector long long int e3 (vector long long int v, long long int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector long long int me0 (vector long long int *vp, long long int x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector long long int me3 (vector long long int *vp, long long int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector long long int ei (vector long long int v, int i, long long int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector long long int mei (vector long long int *vp, int i, long long int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector long long int dv = { CONST0, CONST1 };
+  long long int d;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e3 (dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = me0 (&dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me3 (&dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = ei (dv, 0, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 1, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = ei (dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 3, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 3, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-12d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-12d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-12d.c	(working copy)
@@ -0,0 +1,112 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O3" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(31415926539LL)
+#define CONST1		(2 * 31415926539LL)
+#define CONST2		(3 * 31415926539LL)
+#define CONST3		(4 * 31415926539LL)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector long long int e0 (vector long long int v, long long int x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector long long int e3 (vector long long int v, long long int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector long long int me0 (vector long long int *vp, long long int x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector long long int me3 (vector long long int *vp, long long int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector long long int ei (vector long long int v, int i, long long int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector long long int mei (vector long long int *vp, int i, long long int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector long long int dv = { CONST0, CONST1 };
+  long long int d;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e3 (dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = me0 (&dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me3 (&dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = ei (dv, 0, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 1, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = ei (dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 3, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 3, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c	(revision 270584)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c	(working copy)
@@ -9,7 +9,7 @@ 
 #include <altivec.h>
 
 /* Define this after PR89424 is addressed.  */
-#undef PR89424
+#define PR89424
 
 /* Define this after PR89626 is addressed.  */
 #undef PR89626
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c	(revision 270584)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c	(working copy)
@@ -9,7 +9,7 @@ 
 #include <altivec.h>
 
 /* Define this after PR89424 is addressed.  */
-#undef PR89424
+#define PR89424
 
 /* Define this after PR89626 is addressed.  */
 #undef PR89626
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-13c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-13c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-13c.c	(working copy)
@@ -0,0 +1,115 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+#define SIGNED signed
+
+extern void abort (void);
+
+#define CONST0		(((SIGNED __int128) 31415926539) << 60)
+#define CONST1		(((SIGNED __int128) 31415926539) << 55)
+#define CONST2		(((SIGNED __int128) 31415926539) << 50)
+#define CONST3		(((SIGNED __int128) 31415926539) << 45)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector SIGNED __int128 e0 (vector SIGNED __int128 v, SIGNED __int128 x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector SIGNED __int128 e3 (vector SIGNED __int128 v, SIGNED __int128 x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector SIGNED __int128 me0 (vector SIGNED __int128 *vp, SIGNED __int128 x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector SIGNED __int128 me3 (vector SIGNED __int128 *vp, SIGNED __int128 x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector SIGNED __int128
+ei (vector SIGNED __int128 v, int i, SIGNED __int128 x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector SIGNED __int128
+mei (vector SIGNED __int128 *vp, int i, SIGNED __int128 x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector SIGNED __int128 dv = { CONST0 };
+  SIGNED __int128 d;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e3 (dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me0 (&dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me3 (&dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 1, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = ei (dv, 2, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 3, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 0, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 1, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 3, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-13d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-13d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-13d.c	(working copy)
@@ -0,0 +1,115 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O3" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+#define SIGNED signed
+
+extern void abort (void);
+
+#define CONST0		(((SIGNED __int128) 31415926539) << 60)
+#define CONST1		(((SIGNED __int128) 31415926539) << 55)
+#define CONST2		(((SIGNED __int128) 31415926539) << 50)
+#define CONST3		(((SIGNED __int128) 31415926539) << 45)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector SIGNED __int128 e0 (vector SIGNED __int128 v, SIGNED __int128 x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector SIGNED __int128 e3 (vector SIGNED __int128 v, SIGNED __int128 x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector SIGNED __int128 me0 (vector SIGNED __int128 *vp, SIGNED __int128 x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector SIGNED __int128 me3 (vector SIGNED __int128 *vp, SIGNED __int128 x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector SIGNED __int128
+ei (vector SIGNED __int128 v, int i, SIGNED __int128 x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector SIGNED __int128
+mei (vector SIGNED __int128 *vp, int i, SIGNED __int128 x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector SIGNED __int128 dv = { CONST0 };
+  SIGNED __int128 d;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e3 (dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me0 (&dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me3 (&dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 1, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = ei (dv, 2, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 3, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 0, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 1, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 3, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-14c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-14c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-14c.c	(working copy)
@@ -0,0 +1,149 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		((float) (3.1415926539))
+#define CONST1		((float) (3.1415926539 * 2))
+#define CONST2		((float) (3.1415926539 * 3))
+#define CONST3		((float) (3.1415926539 * 4))
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector float e0(vector float v, float x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector float e1(vector float v, float x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector float e7(vector float v, float x)
+{
+  return vec_insert (x, v, 7);
+}
+
+vector float e8(vector float v, float x)
+{
+  return vec_insert (x, v, 8);
+}
+
+/* Test for vector residing in memory.  */
+vector float me0(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector float me1(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector float me13(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 13);
+}
+
+vector float me15(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 15);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector float ei(vector float v, int i, float x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector float mei(vector float *vp, int i, float x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector float dv = { CONST0, CONST1, CONST2, CONST3 };
+  float d;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e1 (dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = e7 (dv, CONST2);
+  if (dv [3] != CONST2)
+    abort ();
+
+  dv = e8 (dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me0 (&dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me1 (&dv, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = me13 (&dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = me15 (&dv, CONST1);
+  if (dv [3] != CONST1)
+    abort ();
+
+  dv = ei (dv, 0, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 2, CONST1);
+  if (dv [2] != CONST1)
+    abort ();
+
+  dv = ei (dv, 11, CONST0);
+  if (dv [3] != CONST0)
+    abort ();
+
+  dv = ei (dv, 17, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 15, CONST1);
+  if (dv [3] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 6, CONST0);
+  if (dv [2] != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-14d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-14d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-14d.c	(working copy)
@@ -0,0 +1,149 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O3" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		((float) (3.1415926539))
+#define CONST1		((float) (3.1415926539 * 2))
+#define CONST2		((float) (3.1415926539 * 3))
+#define CONST3		((float) (3.1415926539 * 4))
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector float e0(vector float v, float x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector float e1(vector float v, float x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector float e7(vector float v, float x)
+{
+  return vec_insert (x, v, 7);
+}
+
+vector float e8(vector float v, float x)
+{
+  return vec_insert (x, v, 8);
+}
+
+/* Test for vector residing in memory.  */
+vector float me0(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector float me1(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector float me13(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 13);
+}
+
+vector float me15(vector float *vp, float x)
+{
+  return vec_insert (x, *vp, 15);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector float ei(vector float v, int i, float x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector float mei(vector float *vp, int i, float x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector float dv = { CONST0, CONST1, CONST2, CONST3 };
+  float d;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e1 (dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = e7 (dv, CONST2);
+  if (dv [3] != CONST2)
+    abort ();
+
+  dv = e8 (dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me0 (&dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me1 (&dv, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = me13 (&dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = me15 (&dv, CONST1);
+  if (dv [3] != CONST1)
+    abort ();
+
+  dv = ei (dv, 0, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 2, CONST1);
+  if (dv [2] != CONST1)
+    abort ();
+
+  dv = ei (dv, 11, CONST0);
+  if (dv [3] != CONST0)
+    abort ();
+
+  dv = ei (dv, 17, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 15, CONST1);
+  if (dv [3] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 6, CONST0);
+  if (dv [2] != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-15c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-15c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-15c.c	(working copy)
@@ -0,0 +1,151 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(3.1415926539)
+#define CONST1		(3.1415926539 * 2)
+#define CONST2		(3.1415926539 * 3)
+#define CONST3		(3.1415926539 * 4)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector double e0(vector double v, double x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector double e1(vector double v, double x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector double e2(vector double v, double x)
+{
+  return vec_insert (x, v, 2);
+}
+
+vector double e3(vector double v, double x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector double me0(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector double me1(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector double me2(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 2);
+}
+
+vector double me3(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector double ei(vector double v, int i, double x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector double mei(vector double *vp, int i, double x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector double dv;
+  double d;
+  dv[0] = CONST0;
+  dv[1] = CONST1;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e1 (dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = e2 (dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = e3 (dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = me0 (&dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me1 (&dv, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = me2 (&dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me3 (&dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = ei (dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = ei (dv, 2, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 3, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 2, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 3, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-15d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-15d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-15d.c	(working copy)
@@ -0,0 +1,151 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O3" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(3.1415926539)
+#define CONST1		(3.1415926539 * 2)
+#define CONST2		(3.1415926539 * 3)
+#define CONST3		(3.1415926539 * 4)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector double e0(vector double v, double x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector double e1(vector double v, double x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector double e2(vector double v, double x)
+{
+  return vec_insert (x, v, 2);
+}
+
+vector double e3(vector double v, double x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector double me0(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector double me1(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector double me2(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 2);
+}
+
+vector double me3(vector double *vp, double x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector double ei(vector double v, int i, double x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector double mei(vector double *vp, int i, double x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector double dv;
+  double d;
+  dv[0] = CONST0;
+  dv[1] = CONST1;
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e1 (dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = e2 (dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = e3 (dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = me0 (&dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me1 (&dv, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = me2 (&dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me3 (&dv, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = ei (dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = ei (dv, 2, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 3, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST0);
+  if (dv [1] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 2, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 3, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-16c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-16c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-16c.c	(working copy)
@@ -0,0 +1,180 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <stdio.h>
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+#define CONST8		(8)
+#define CONST9		(9)
+#define CONSTA		(10)
+#define CONSTB		(11)
+#define CONSTC		(12)
+#define CONSTD		(13)
+#define CONSTE		(14)
+#define CONSTF		(15)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned char c0 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector unsigned char c9 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 9);
+}
+
+vector unsigned char c21 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector unsigned char c30 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned char mc0 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector unsigned char mc9 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 9);
+}
+
+vector unsigned char mc21 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector unsigned char mc30 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned char ci (vector unsigned char v, int i, unsigned char x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned char mci (vector unsigned char *vp, int i, unsigned char x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector unsigned char cv = { CONST0, CONST1, CONST2, CONST3,
+			      CONST4, CONST5, CONST6, CONST7,
+			      CONST8, CONST9, CONSTA, CONSTB,
+			      CONSTC, CONSTD, CONSTE, CONSTF };
+  printf ("A\n");
+  cv = c0 (cv, CONST3);
+  if (cv [0] != CONST3)
+    abort ();
+
+  printf ("B\n");
+  cv = c9 (cv, CONST2);
+  if (cv [9] != CONST2)
+    abort ();
+
+  printf ("C\n");
+  cv = c21 (cv, CONSTF);
+  if (cv [5] != CONSTF)
+    abort ();
+
+  printf ("D\n");
+  cv = c30 (cv, CONST3);
+  if (cv [14] != CONST3)
+    abort ();
+
+  printf ("E\n");
+  cv = mc0 (&cv, CONST4);
+  if (cv [0] != CONST4)
+    abort ();
+
+  printf ("F\n");
+  cv = mc9 (&cv, CONST3);
+  if (cv [9] != CONST3)
+    abort ();
+
+  printf ("G\n");
+  cv = mc21 (&cv, CONST1);
+  if (cv [5] != CONST1)
+    abort ();
+
+  printf ("H\n");
+  cv = mc30 (&cv, CONSTC);
+  if (cv [14] != CONSTC)
+    abort ();
+
+  printf ("I\n");
+  cv = ci (cv, 8, CONSTD);
+  if (cv [8] != CONSTD)
+    abort ();
+
+  printf ("J\n");
+  cv = ci (cv, 13, CONST5);
+  if (cv [13] != CONST5)
+    abort ();
+
+  printf ("K\n");
+  cv = ci (cv, 23, CONST6);
+  if (cv [7] != CONST6)
+    abort ();
+
+  printf ("L\n");
+  cv = ci (cv, 31, CONST7);
+  if (cv [15] != CONST7)
+    abort ();
+
+  printf ("M\n");
+  cv = mci (&cv, 5, CONST8);
+  if (cv [5] != CONST8)
+    abort ();
+
+  printf ("N\n");
+  cv = mci (&cv, 12, CONST9);
+  if (cv [12] != CONST9)
+    abort ();
+
+  printf ("O\n");
+  cv = mci (&cv, 25, CONSTA);
+  if (cv [9] != CONSTA)
+    abort ();
+
+  printf ("P\n");
+  cv = mci (&cv, 16, CONSTB);
+  if (cv [0] != CONSTB)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-16d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-16d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-16d.c	(working copy)
@@ -0,0 +1,163 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O3" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+#define CONST8		(8)
+#define CONST9		(9)
+#define CONSTA		(10)
+#define CONSTB		(11)
+#define CONSTC		(12)
+#define CONSTD		(13)
+#define CONSTE		(14)
+#define CONSTF		(15)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned char c0 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector unsigned char c9 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 9);
+}
+
+vector unsigned char c21 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector unsigned char c30 (vector unsigned char v, unsigned char x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned char mc0 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector unsigned char mc9 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 9);
+}
+
+vector unsigned char mc21 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector unsigned char mc30 (vector unsigned char *vp, unsigned char x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned char ci (vector unsigned char v, int i, unsigned char x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned char mci (vector unsigned char *vp, int i, unsigned char x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector unsigned char cv = { CONST0, CONST1, CONST2, CONST3,
+			      CONST4, CONST5, CONST6, CONST7,
+			      CONST8, CONST9, CONSTA, CONSTB,
+			      CONSTC, CONSTD, CONSTE, CONSTF };
+  cv = c0 (cv, CONST3);
+  if (cv [0] != CONST3)
+    abort ();
+
+  cv = c9 (cv, CONST2);
+  if (cv [9] != CONST2)
+    abort ();
+
+  cv = c21 (cv, CONSTF);
+  if (cv [5] != CONSTF)
+    abort ();
+
+  cv = c30 (cv, CONST3);
+  if (cv [14] != CONST3)
+    abort ();
+
+  cv = mc0 (&cv, CONST4);
+  if (cv [0] != CONST4)
+    abort ();
+
+  cv = mc9 (&cv, CONST3);
+  if (cv [9] != CONST3)
+    abort ();
+
+  cv = mc21 (&cv, CONST1);
+  if (cv [5] != CONST1)
+    abort ();
+
+  cv = mc30 (&cv, CONSTC);
+  if (cv [14] != CONSTC)
+    abort ();
+
+  cv = ci (cv, 8, CONSTD);
+  if (cv [8] != CONSTD)
+    abort ();
+
+  cv = ci (cv, 13, CONST5);
+  if (cv [13] != CONST5)
+    abort ();
+
+  cv = ci (cv, 23, CONST6);
+  if (cv [7] != CONST6)
+    abort ();
+
+  cv = ci (cv, 31, CONST7);
+  if (cv [15] != CONST7)
+    abort ();
+
+  cv = mci (&cv, 5, CONST8);
+  if (cv [5] != CONST8)
+    abort ();
+
+  cv = mci (&cv, 12, CONST9);
+  if (cv [12] != CONST9)
+    abort ();
+
+  cv = mci (&cv, 25, CONSTA);
+  if (cv [9] != CONSTA)
+    abort ();
+
+  cv = mci (&cv, 16, CONSTB);
+  if (cv [0] != CONSTB)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-17c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-17c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-17c.c	(working copy)
@@ -0,0 +1,154 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned short s3 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector unsigned short s7 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 7);
+}
+
+vector unsigned short s21 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector unsigned short s30 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned short ms3 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector unsigned short ms7 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 7);
+}
+
+vector unsigned short ms21 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector unsigned short ms30 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned short ci (vector unsigned short v, int i, unsigned short x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned short mci (vector unsigned short *vp, int i, unsigned short x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, unsigned short *argv[]) {
+  vector unsigned short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+
+  sv = s3 (sv, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = s7 (sv, CONST2);
+  if (sv [7] != CONST2)
+    abort ();
+
+  sv = s21 (sv, CONST3);
+  if (sv [5] != CONST3)
+    abort ();
+
+  sv = s30 (sv, CONST4);
+  if (sv [6] != CONST4)
+    abort ();
+
+  sv = ms3 (&sv, CONST5);
+  if (sv [3] != CONST5)
+    abort ();
+
+  sv = ms7 (&sv, CONST6);
+  if (sv [7] != CONST6)
+    abort ();
+
+  sv = ms21 (&sv, CONST7);
+  if (sv [5] != CONST7)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [6] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST1);
+  if (sv [5] != CONST1)
+    abort ();
+
+  sv = ci (sv, 2, CONST3);
+  if (sv [2] != CONST3)
+    abort ();
+
+  sv = ci (sv, 15, CONST2);
+  if (sv [7] != CONST2)
+    abort ();
+
+  sv = ci (sv, 28, CONST5);
+  if (sv [4] != CONST5)
+    abort ();
+
+  sv = mci (&sv, 5, CONST4);
+  if (sv [5] != CONST4)
+    abort ();
+
+  sv = mci (&sv, 12, CONST6);
+  if (sv [4] != CONST6)
+    abort ();
+
+  sv = mci (&sv, 25, CONST7);
+  if (sv [1] != CONST7)
+    abort ();
+
+  sv = mci (&sv, 16, CONST4);
+  if (sv [0] != CONST4)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-17d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-17d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-17d.c	(working copy)
@@ -0,0 +1,154 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned short s3 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector unsigned short s7 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 7);
+}
+
+vector unsigned short s21 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector unsigned short s30 (vector unsigned short v, unsigned short x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned short ms3 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector unsigned short ms7 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 7);
+}
+
+vector unsigned short ms21 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector unsigned short ms30 (vector unsigned short *vp, unsigned short x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned short ci (vector unsigned short v, int i, unsigned short x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned short mci (vector unsigned short *vp, int i, unsigned short x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, unsigned short *argv[]) {
+  vector unsigned short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+
+  sv = s3 (sv, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = s7 (sv, CONST2);
+  if (sv [7] != CONST2)
+    abort ();
+
+  sv = s21 (sv, CONST3);
+  if (sv [5] != CONST3)
+    abort ();
+
+  sv = s30 (sv, CONST4);
+  if (sv [6] != CONST4)
+    abort ();
+
+  sv = ms3 (&sv, CONST5);
+  if (sv [3] != CONST5)
+    abort ();
+
+  sv = ms7 (&sv, CONST6);
+  if (sv [7] != CONST6)
+    abort ();
+
+  sv = ms21 (&sv, CONST7);
+  if (sv [5] != CONST7)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [6] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST1);
+  if (sv [5] != CONST1)
+    abort ();
+
+  sv = ci (sv, 2, CONST3);
+  if (sv [2] != CONST3)
+    abort ();
+
+  sv = ci (sv, 15, CONST2);
+  if (sv [7] != CONST2)
+    abort ();
+
+  sv = ci (sv, 28, CONST5);
+  if (sv [4] != CONST5)
+    abort ();
+
+  sv = mci (&sv, 5, CONST4);
+  if (sv [5] != CONST4)
+    abort ();
+
+  sv = mci (&sv, 12, CONST6);
+  if (sv [4] != CONST6)
+    abort ();
+
+  sv = mci (&sv, 25, CONST7);
+  if (sv [1] != CONST7)
+    abort ();
+
+  sv = mci (&sv, 16, CONST4);
+  if (sv [0] != CONST4)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-18c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-18c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-18c.c	(working copy)
@@ -0,0 +1,148 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Unsigned Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned int s3 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector unsigned int s1 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector unsigned int s21 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector unsigned int s30 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned int ms3 (vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector unsigned int ms1(vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector unsigned int ms21(vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector unsigned int ms30(vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned int ci (vector unsigned int v, int i, unsigned int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned int mci(vector unsigned int *vp, int i, unsigned int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, unsigned char *argv[]) {
+  vector unsigned int sv = { CONST0, CONST1, CONST2, CONST3 };
+
+  sv = s3 (sv, CONST2);
+  if (sv [3] != CONST2)
+    abort ();
+
+  sv = s1 (sv, CONST2);
+  if (sv [1] != CONST2)
+    abort ();
+
+  sv = s21 (sv, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = s30 (sv, CONST1);
+  if (sv [2] != CONST1)
+    abort ();
+
+  sv = ms3 (&sv, CONST0);
+  if (sv [3] != CONST0)
+    abort ();
+
+  sv = ms1 (&sv, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = ms21 (&sv, CONST1);
+  if (sv [1] != CONST1)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [2] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = ci (sv, 2, CONST0);
+  if (sv [2] != CONST0)
+    abort ();
+
+  sv = ci (sv, 15, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = ci (sv, 28, CONST3);
+  if (sv [0] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 5, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = mci (&sv, 12, CONST2);
+  if (sv [0] != CONST2)
+    abort ();
+
+  sv = mci (&sv, 25, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 16, CONST1);
+  if (sv [0] != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-18d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-18d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-18d.c	(working copy)
@@ -0,0 +1,148 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O3" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Unsigned Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned int s3 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+vector unsigned int s1 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 1);
+}
+
+vector unsigned int s21 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector unsigned int s30 (vector unsigned int v, unsigned int x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned int ms3 (vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+vector unsigned int ms1(vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 1);
+}
+
+vector unsigned int ms21(vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector unsigned int ms30(vector unsigned int *vp, unsigned int x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned int ci (vector unsigned int v, int i, unsigned int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned int mci(vector unsigned int *vp, int i, unsigned int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, unsigned char *argv[]) {
+  vector unsigned int sv = { CONST0, CONST1, CONST2, CONST3 };
+
+  sv = s3 (sv, CONST2);
+  if (sv [3] != CONST2)
+    abort ();
+
+  sv = s1 (sv, CONST2);
+  if (sv [1] != CONST2)
+    abort ();
+
+  sv = s21 (sv, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = s30 (sv, CONST1);
+  if (sv [2] != CONST1)
+    abort ();
+
+  sv = ms3 (&sv, CONST0);
+  if (sv [3] != CONST0)
+    abort ();
+
+  sv = ms1 (&sv, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = ms21 (&sv, CONST1);
+  if (sv [1] != CONST1)
+    abort ();
+
+  sv = ms30 (&sv, CONST0);
+  if (sv [2] != CONST0)
+    abort ();
+
+  sv = ci (sv, 5, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = ci (sv, 2, CONST0);
+  if (sv [2] != CONST0)
+    abort ();
+
+  sv = ci (sv, 15, CONST1);
+  if (sv [3] != CONST1)
+    abort ();
+
+  sv = ci (sv, 28, CONST3);
+  if (sv [0] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 5, CONST0);
+  if (sv [1] != CONST0)
+    abort ();
+
+  sv = mci (&sv, 12, CONST2);
+  if (sv [0] != CONST2)
+    abort ();
+
+  sv = mci (&sv, 25, CONST3);
+  if (sv [1] != CONST3)
+    abort ();
+
+  sv = mci (&sv, 16, CONST1);
+  if (sv [0] != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-19c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-19c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-19c.c	(working copy)
@@ -0,0 +1,122 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(31415926539LL)
+#define CONST1		(2 * 31415926539LL)
+#define CONST2		(3 * 31415926539LL)
+#define CONST3		(4 * 31415926539LL)
+#define CONST4		(5 * 31415926539LL)
+#define CONST5		(6 * 31415926539LL)
+#define CONST6		(7 * 31415926539LL)
+#define CONST7		(8 * 31415926539LL)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned long long int
+e0 (vector unsigned long long int v, unsigned long long int x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector unsigned long long int
+e3 (vector unsigned long long int v, unsigned long long int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned long long int
+me0 (vector unsigned long long int *vp, unsigned long long int x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector unsigned long long int
+me3 (vector unsigned long long int *vp, unsigned long long int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned long long int
+ei (vector unsigned long long int v, int i, unsigned long long int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned long long int
+mei (vector unsigned long long int *vp, int i, unsigned long long int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector unsigned long long int dv = { CONST0, CONST1 };
+  unsigned long long int d;
+
+  dv = e0 (dv, CONST7);
+  if (dv [0] != CONST7)
+    abort ();
+
+  dv = e3 (dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = me0 (&dv, CONST4);
+  if (dv [0] != CONST4)
+    abort ();
+
+  dv = me3 (&dv, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = ei (dv, 0, CONST5);
+  if (dv [0] != CONST5)
+    abort ();
+
+  dv = ei (dv, 1, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = ei (dv, 2, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 3, CONST6);
+  if (dv [1] != CONST6)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 3, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-19d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-19d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-19d.c	(working copy)
@@ -0,0 +1,122 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O3" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(31415926539LL)
+#define CONST1		(2 * 31415926539LL)
+#define CONST2		(3 * 31415926539LL)
+#define CONST3		(4 * 31415926539LL)
+#define CONST4		(5 * 31415926539LL)
+#define CONST5		(6 * 31415926539LL)
+#define CONST6		(7 * 31415926539LL)
+#define CONST7		(8 * 31415926539LL)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned long long int
+e0 (vector unsigned long long int v, unsigned long long int x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector unsigned long long int
+e3 (vector unsigned long long int v, unsigned long long int x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned long long int
+me0 (vector unsigned long long int *vp, unsigned long long int x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector unsigned long long int
+me3 (vector unsigned long long int *vp, unsigned long long int x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned long long int
+ei (vector unsigned long long int v, int i, unsigned long long int x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned long long int
+mei (vector unsigned long long int *vp, int i, unsigned long long int x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector unsigned long long int dv = { CONST0, CONST1 };
+  unsigned long long int d;
+
+  dv = e0 (dv, CONST7);
+  if (dv [0] != CONST7)
+    abort ();
+
+  dv = e3 (dv, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = me0 (&dv, CONST4);
+  if (dv [0] != CONST4)
+    abort ();
+
+  dv = me3 (&dv, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = ei (dv, 0, CONST5);
+  if (dv [0] != CONST5)
+    abort ();
+
+  dv = ei (dv, 1, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  dv = ei (dv, 2, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 3, CONST6);
+  if (dv [1] != CONST6)
+    abort ();
+
+  dv = mei (&dv, 0, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 1, CONST3);
+  if (dv [1] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 2, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 3, CONST2);
+  if (dv [1] != CONST2)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c	(revision 270584)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c	(working copy)
@@ -9,7 +9,7 @@ 
 #include <altivec.h>
 
 /* Define this after PR89424 is addressed.  */
-#undef PR89424
+#define PR89424
 
 extern void abort (void);
 
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c	(revision 270584)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c	(working copy)
@@ -9,7 +9,7 @@ 
 #include <altivec.h>
 
 /* Define this after PR89424 is addressed.  */
-#undef PR89424
+#define PR89424
 
 extern void abort (void);
 
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-20c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-20c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-20c.c	(working copy)
@@ -0,0 +1,115 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(((unsigned __int128) 31415926539) << 60)
+#define CONST1		(((unsigned __int128) 31415926539) << 54)
+#define CONST2		(((unsigned __int128) 31415926539) << 48)
+#define CONST3		(((unsigned __int128) 31415926539) << 32)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned __int128 e0 (vector unsigned __int128 v, unsigned __int128 x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector unsigned __int128 e3 (vector unsigned __int128 v, unsigned __int128 x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned __int128
+me0 (vector unsigned __int128 *vp, unsigned __int128 x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector unsigned __int128
+me3 (vector unsigned __int128 *vp, unsigned __int128 x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned __int128
+ei (vector unsigned __int128 v, int i, unsigned __int128 x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned __int128
+mei (vector unsigned __int128 *vp, int i, unsigned __int128 x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector unsigned __int128 dv = { CONST0 };
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e3 (dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me0 (&dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me3 (&dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 0, CONST0);
+  if (dv [0] != CONST0)
+    abort ();
+
+  dv = ei (dv, 1, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 2, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = ei (dv, 3, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 0, CONST0);
+  if (dv [0] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 1, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 2, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 3, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-20d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-20d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-20d.c	(working copy)
@@ -0,0 +1,115 @@ 
+/* { dg-do run { target int128 } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O3" } */
+
+/* This test should run the same on any target that supports vsx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(((unsigned __int128) 31415926539) << 60)
+#define CONST1		(((unsigned __int128) 31415926539) << 54)
+#define CONST2		(((unsigned __int128) 31415926539) << 48)
+#define CONST3		(((unsigned __int128) 31415926539) << 32)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector unsigned __int128 e0 (vector unsigned __int128 v, unsigned __int128 x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector unsigned __int128 e3 (vector unsigned __int128 v, unsigned __int128 x)
+{
+  return vec_insert (x, v, 3);
+}
+
+/* Test for vector residing in memory.  */
+vector unsigned __int128
+me0 (vector unsigned __int128 *vp, unsigned __int128 x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector unsigned __int128
+me3 (vector unsigned __int128 *vp, unsigned __int128 x)
+{
+  return vec_insert (x, *vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector unsigned __int128
+ei (vector unsigned __int128 v, int i, unsigned __int128 x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector unsigned __int128
+mei (vector unsigned __int128 *vp, int i, unsigned __int128 x)
+{
+  return vec_insert (x, *vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector unsigned __int128 dv = { CONST0 };
+
+  dv = e0 (dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = e3 (dv, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = me0 (&dv, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = me3 (&dv, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = ei (dv, 0, CONST0);
+  if (dv [0] != CONST0)
+    abort ();
+
+  dv = ei (dv, 1, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = ei (dv, 2, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = ei (dv, 3, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  dv = mei (&dv, 0, CONST0);
+  if (dv [0] != CONST0)
+    abort ();
+
+  dv = mei (&dv, 1, CONST1);
+  if (dv [0] != CONST1)
+    abort ();
+
+  dv = mei (&dv, 2, CONST2);
+  if (dv [0] != CONST2)
+    abort ();
+
+  dv = mei (&dv, 3, CONST3);
+  if (dv [0] != CONST3)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-9c.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-9c.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-9c.c	(working copy)
@@ -0,0 +1,164 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+#define CONST8		(8)
+#define CONST9		(9)
+#define CONSTA		(10)
+#define CONSTB		(11)
+#define CONSTC		(12)
+#define CONSTD		(13)
+#define CONSTE		(14)
+#define CONSTF		(15)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector signed char c0 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector signed char c9 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 9);
+}
+
+vector signed char c21 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector signed char c30 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector signed char mc0 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector signed char mc9 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 9);
+}
+
+vector signed char mc21 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector signed char mc30 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector signed char ci (vector signed char v, int i, signed char x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector signed char mci(vector signed char *vp, int i, signed char x) {
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector signed char cv = { CONST0, CONST1, CONST2, CONST3,
+			    CONST4, CONST5, CONST6, CONST7,
+			    CONST8, CONST9, CONSTA, CONSTB,
+			    CONSTC, CONSTD, CONSTE, CONSTF };
+  signed char c;
+
+  cv = c0 (cv, CONSTF);
+  if (cv [0] != CONSTF)
+    abort ();
+
+  cv = c9 (cv, CONST7);
+  if (cv [9] != CONST7)
+    abort ();
+
+  cv = c21 (cv, CONSTA);
+  if (cv [5] != CONSTA)
+    abort ();
+
+  cv = c30 (cv, CONSTC);
+  if (cv [14] != CONSTC)
+    abort ();
+
+  cv = mc0 (&cv, CONSTB);
+  if (cv [0] != CONSTB)
+    abort ();
+
+  cv = mc9 (&cv, CONST1);
+  if (cv [9] != CONST1)
+    abort ();
+
+  cv = mc21 (&cv, CONST7);
+  if (cv [5] != CONST7)
+    abort ();
+
+  cv = mc30 (&cv, CONST2);
+  if (cv [14] != CONST2)
+    abort ();
+
+  cv = ci (cv, 8, CONST4);
+  if (cv [8] != CONST4)
+    abort ();
+
+  cv = ci (cv, 13, CONSTB);
+  if (cv [13] != CONSTB)
+    abort ();
+
+  cv = ci (cv, 23, CONST3);
+  if (cv [7] != CONST3)
+    abort ();
+
+  cv = ci (cv, 31, CONST2);
+  if (cv [15] != CONST2)
+    abort ();
+
+  cv = mci (&cv, 5, CONST1);
+  if (cv [5] != CONST1)
+    abort ();
+
+  cv = mci (&cv, 12, CONST3);
+  if (cv [12] != CONST3)
+    abort ();
+
+  cv = mci (&cv, 25, CONST5);
+  if (cv [9] != CONST5)
+    abort ();
+
+  cv = mci (&cv, 16, CONSTD);
+  if (cv [0] != CONSTD)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-9d.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-9d.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-9d.c	(working copy)
@@ -0,0 +1,164 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O3" } */
+
+/* This test should run the same on any target that supports altivec/vmx
+   instructions.  Intentionally not specifying cpu in order to test
+   all code generation paths.  */
+
+#include <altivec.h>
+
+extern void abort (void);
+
+#define CONST0		(0)
+#define CONST1		(1)
+#define CONST2		(2)
+#define CONST3		(3)
+#define CONST4		(4)
+#define CONST5		(5)
+#define CONST6		(6)
+#define CONST7		(7)
+#define CONST8		(8)
+#define CONST9		(9)
+#define CONSTA		(10)
+#define CONSTB		(11)
+#define CONSTC		(12)
+#define CONSTD		(13)
+#define CONSTE		(14)
+#define CONSTF		(15)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+vector signed char c0 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 0);
+}
+
+vector signed char c9 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 9);
+}
+
+vector signed char c21 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 21);
+}
+
+vector signed char c30 (vector signed char v, signed char x)
+{
+  return vec_insert (x, v, 30);
+}
+
+/* Test for vector residing in memory.  */
+vector signed char mc0 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 0);
+}
+
+vector signed char mc9 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 9);
+}
+
+vector signed char mc21 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 21);
+}
+
+vector signed char mc30 (vector signed char *vp, signed char x)
+{
+  return vec_insert (x, *vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+vector signed char ci (vector signed char v, int i, signed char x)
+{
+  return vec_insert (x, v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+vector signed char mci(vector signed char *vp, int i, signed char x) {
+  return vec_insert (x, *vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector signed char cv = { CONST0, CONST1, CONST2, CONST3,
+			    CONST4, CONST5, CONST6, CONST7,
+			    CONST8, CONST9, CONSTA, CONSTB,
+			    CONSTC, CONSTD, CONSTE, CONSTF };
+  signed char c;
+
+  cv = c0 (cv, CONSTF);
+  if (cv [0] != CONSTF)
+    abort ();
+
+  cv = c9 (cv, CONST7);
+  if (cv [9] != CONST7)
+    abort ();
+
+  cv = c21 (cv, CONSTA);
+  if (cv [5] != CONSTA)
+    abort ();
+
+  cv = c30 (cv, CONSTC);
+  if (cv [14] != CONSTC)
+    abort ();
+
+  cv = mc0 (&cv, CONSTB);
+  if (cv [0] != CONSTB)
+    abort ();
+
+  cv = mc9 (&cv, CONST1);
+  if (cv [9] != CONST1)
+    abort ();
+
+  cv = mc21 (&cv, CONST7);
+  if (cv [5] != CONST7)
+    abort ();
+
+  cv = mc30 (&cv, CONST2);
+  if (cv [14] != CONST2)
+    abort ();
+
+  cv = ci (cv, 8, CONST4);
+  if (cv [8] != CONST4)
+    abort ();
+
+  cv = ci (cv, 13, CONSTB);
+  if (cv [13] != CONSTB)
+    abort ();
+
+  cv = ci (cv, 23, CONST3);
+  if (cv [7] != CONST3)
+    abort ();
+
+  cv = ci (cv, 31, CONST2);
+  if (cv [15] != CONST2)
+    abort ();
+
+  cv = mci (&cv, 5, CONST1);
+  if (cv [5] != CONST1)
+    abort ();
+
+  cv = mci (&cv, 12, CONST3);
+  if (cv [12] != CONST3)
+    abort ();
+
+  cv = mci (&cv, 25, CONST5);
+  if (cv [9] != CONST5)
+    abort ();
+
+  cv = mci (&cv, 16, CONSTD);
+  if (cv [0] != CONSTD)
+    abort ();
+
+  return 0;
+}