diff mbox series

[v2,rs6000] PR87532: Bad Results from vec_extract(unsigned char, foo) dependent upon function inline

Message ID 486a2d36-cd18-ced2-2064-ed0be52a87b2@linux.ibm.com
State New
Headers show
Series [v2,rs6000] PR87532: Bad Results from vec_extract(unsigned char, foo) dependent upon function inline | expand

Commit Message

Kelvin Nilsen March 13, 2019, 9:43 p.m. UTC
An initial draft patch was distributed on 3/8/19.  Thanks Segher for careful review and detailed feedback.  This second draft patch differs from the first in the following regards:

  1. Simplified dg directives in the new tests cases:
     a) Removed { target { powerpc*-*-* } } from dg-do run directives because this is redundant with powerpc.exp
     b) Removed { dg-skip-if "" { powerpc*-*-darwin* } } directives because this is redundant with requiring vsx or altivec
     c) Changed effective target requirement from dfp_hw to vmx_hw
     d) Required { target { int128 } } instead of lp64 for tests that require int128 support
     e) Removed dg-skip-if for -mcpu= overrides, because these tests are not setting cpu
     f) Removed "-save-temps -dp -g" from the dg-options directive on certain tests
  2. Corrected certain __asm__ statements to require the "v" output constraint rather than the "wa" output constraint (when compiling with -maltivec)
  3. In rs6000-c.c, made modular computation of constant selector expression unconditional
  4. In rs6000.c:
     a) Changed computation of bits_in_element to use GET_MODE_INNER macro.
     b) Changed error message in case of selector expression overflow to not make reference to HOST_WIDE_INT


This problem report, though initially motivated by differences in behavior between constant and non-constant selector arguments, uncovered a number of inconsistencies in the implementation of vec_extract.

This patch provides several fixes to make handling of constant selector expressions the same as the handling of non-constant selector expressions.  In the process of testing, it was observed that certain existing regression tests were looking for the wrong instructions to be emitted and those tests have been updated.

This has bootstrapped and tested without regressions on powerpc64le-unknown-linux (both P8 and P9) and on powerpc-linux (P7 big-endian, with both -m32 and -m64 target options).

Is this ok for trunk?

gcc/ChangeLog:

2019-03-13  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/87532
	* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
	When handling vec_extract, use modular arithmetic to allow
	constant selectors greater than vector length.
	* config/rs6000/rs6000.c (rs6000_expand_vector_extract): Allow
	V1TImode vectors to have constant selector values greater than 0.
	Use modular arithmetic to compute vector index.
	(rs6000_split_vec_extract_var): Use modular arithmetic to compute
	index for in-memory vectors.  Correct code generation for
	in-register vectors.
	(altivec_expand_vec_ext_builtin): Use modular arithmetic to
	computer index.

gcc/testsuite/ChangeLog:

2019-03-13  Kelvin Nilsen  <kelvin@gcc.gnu.org>

	PR target/87532
	* gcc.target/powerpc/fold-vec-extract-char.p8.c: Modify expected
	instruction selection.
	* gcc.target/powerpc/fold-vec-extract-int.p8.c: Likewise.
	* gcc.target/powerpc/fold-vec-extract-short.p8.c: Likewise.
	* gcc.target/powerpc/pr87532-mc.c: New test.
	* gcc.target/powerpc/pr87532.c: New test.
	* gcc.target/powerpc/vec-extract-v16qiu-v2.h: New test.
	* gcc.target/powerpc/vec-extract-v16qiu-v2a.c: New test.
	* gcc.target/powerpc/vec-extract-v16qiu-v2b.c: New test.
	* gcc.target/powerpc/vsx-builtin-10a.c: New test.
	* gcc.target/powerpc/vsx-builtin-10b.c: New test.
	* gcc.target/powerpc/vsx-builtin-11a.c: New test.
	* gcc.target/powerpc/vsx-builtin-11b.c: New test.
	* gcc.target/powerpc/vsx-builtin-12a.c: New test.
	* gcc.target/powerpc/vsx-builtin-12b.c: New test.
	* gcc.target/powerpc/vsx-builtin-13a.c: New test.
	* gcc.target/powerpc/vsx-builtin-13b.c: New test.
	* gcc.target/powerpc/vsx-builtin-14a.c: New test.
	* gcc.target/powerpc/vsx-builtin-14b.c: New test.
	* gcc.target/powerpc/vsx-builtin-15a.c: New test.
	* gcc.target/powerpc/vsx-builtin-15b.c: New test.
	* gcc.target/powerpc/vsx-builtin-16a.c: New test.
	* gcc.target/powerpc/vsx-builtin-16b.c: New test.
	* gcc.target/powerpc/vsx-builtin-17a.c: New test.
	* gcc.target/powerpc/vsx-builtin-17b.c: New test.
	* gcc.target/powerpc/vsx-builtin-18a.c: New test.
	* gcc.target/powerpc/vsx-builtin-18b.c: New test.
	* gcc.target/powerpc/vsx-builtin-19a.c: New test.
	* gcc.target/powerpc/vsx-builtin-19b.c: New test.
	* gcc.target/powerpc/vsx-builtin-20a.c: New test.
	* gcc.target/powerpc/vsx-builtin-20b.c: New test.
	* gcc.target/powerpc/vsx-builtin-9a.c: New test.
	* gcc.target/powerpc/vsx-builtin-9b.c: New test.

Comments

Segher Boessenkool March 13, 2019, 11:50 p.m. UTC | #1
Hi Kelvin,

On Wed, Mar 13, 2019 at 04:43:35PM -0500, Kelvin Nilsen wrote:
[ snip ]

This looks great, thanks!  Okay for trunk.  A few more comments, do
with it as you like:

> 	(altivec_expand_vec_ext_builtin): Use modular arithmetic to
> 	computer index.

s/computer/compute/

> @@ -14723,9 +14742,17 @@ altivec_expand_vec_ext_builtin (tree exp, rtx targ
>    op0 = expand_normal (arg0);
>    op1 = expand_normal (arg1);
>  
> -  /* Call get_element_number to validate arg1 if it is a constant.  */
>    if (TREE_CODE (arg1) == INTEGER_CST)
> -    (void) get_element_number (TREE_TYPE (arg0), arg1);
> +    {
> +      unsigned HOST_WIDE_INT elt;
> +      unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
> +      unsigned int truncated_selector;
> +      if (!tree_fits_uhwi_p (arg1))
> +	error ("selector expression is out of range");
> +      elt = tree_to_uhwi (arg1);
> +      truncated_selector = elt % size;
> +      op1 = GEN_INT (truncated_selector);
> +    }

This error really should never happen, but maybe there is a better way to
report it (error_at maybe), or we can avoid it completely?  It shouldn't
be too hard to extract the low few bits from any precision number.

Have you tested this?  Is the error reasonable?  Can you provoke it at all,
even with negative indices?

> +/* { dg-do run { target { int128 } } } */

You can write this simpler as

/* { dg-do run { target int128 } } */


Segher
diff mbox series

Patch

Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c	(revision 269492)
+++ gcc/config/rs6000/rs6000-c.c	(working copy)
@@ -6565,12 +6565,14 @@  altivec_resolve_overloaded_builtin (location_t loc
 
 	  arg2 = fold_for_warn (arg2);
 
-	  /* If the second argument is an integer constant, if the value is in
-	     the expected range, generate the built-in code if we can.  We need
-	     64-bit and direct move to extract the small integer vectors.  */
-	  if (TREE_CODE (arg2) == INTEGER_CST
-	      && wi::ltu_p (wi::to_wide (arg2), nunits))
+	  /* If the second argument is an integer constant, generate
+	     the built-in code if we can.  We need 64-bit and direct
+	     move to extract the small integer vectors.  */
+	  if (TREE_CODE (arg2) == INTEGER_CST)
 	    {
+	      wide_int selector = wi::to_wide (arg2);
+	      selector = wi::umod_trunc (selector, nunits);
+	      arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
 	      switch (mode)
 		{
 		default:
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 269492)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -6894,7 +6894,6 @@  rs6000_expand_vector_extract (rtx target, rtx vec,
 	default:
 	  break;
 	case E_V1TImode:
-	  gcc_assert (INTVAL (elt) == 0 && inner_mode == TImode);
 	  emit_move_insn (target, gen_lowpart (TImode, vec));
 	  break;
 	case E_V2DFmode:
@@ -6974,18 +6973,32 @@  rs6000_expand_vector_extract (rtx target, rtx vec,
 	}
     }
 
-  gcc_assert (CONST_INT_P (elt));
-
   /* Allocate mode-sized buffer.  */
   mem = assign_stack_temp (mode, GET_MODE_SIZE (mode));
 
   emit_move_insn (mem, vec);
+  if (CONST_INT_P (elt))
+    {
+      int modulo_elt = INTVAL (elt) % GET_MODE_NUNITS (mode);
 
-  /* Add offset to field within buffer matching vector element.  */
-  mem = adjust_address_nv (mem, inner_mode,
-			   INTVAL (elt) * GET_MODE_SIZE (inner_mode));
+      /* Add offset to field within buffer matching vector element.  */
+      mem = adjust_address_nv (mem, inner_mode,
+			       modulo_elt * GET_MODE_SIZE (inner_mode));
+      emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
+    }
+  else
+    {
+      unsigned int ele_size = GET_MODE_SIZE (inner_mode);
+      rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
+      rtx new_addr = gen_reg_rtx (Pmode);
 
-  emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
+      elt = gen_rtx_AND (Pmode, elt, num_ele_m1);
+      if (ele_size > 1)
+	elt = gen_rtx_MULT (Pmode, elt, GEN_INT (ele_size));
+      new_addr = gen_rtx_PLUS (Pmode, XEXP (mem, 0), elt);
+      new_addr = change_address (mem, inner_mode, new_addr);
+      emit_move_insn (target, new_addr);
+    }
 }
 
 /* Adjust a memory address (MEM) of a vector type to point to a scalar field
@@ -7165,6 +7178,10 @@  rs6000_split_vec_extract_var (rtx dest, rtx src, r
      systems.  */
   if (MEM_P (src))
     {
+      int num_elements = GET_MODE_NUNITS (mode);
+      rtx num_ele_m1 = GEN_INT (num_elements - 1);
+
+      emit_insn (gen_anddi3 (element, element, num_ele_m1));
       gcc_assert (REG_P (tmp_gpr));
       emit_move_insn (dest, rs6000_adjust_vec_address (dest, src, element,
 						       tmp_gpr, scalar_mode));
@@ -7173,7 +7190,9 @@  rs6000_split_vec_extract_var (rtx dest, rtx src, r
 
   else if (REG_P (src) || SUBREG_P (src))
     {
-      int bit_shift = byte_shift + 3;
+      int num_elements = GET_MODE_NUNITS (mode);
+      int bits_in_element = mode_to_bits (GET_MODE_INNER (mode));
+      int bit_shift = 7 - exact_log2 (num_elements);
       rtx element2;
       unsigned int dest_regno = reg_or_subregno (dest);
       unsigned int src_regno = reg_or_subregno (src);
@@ -7249,7 +7268,7 @@  rs6000_split_vec_extract_var (rtx dest, rtx src, r
 	{
 	  if (!BYTES_BIG_ENDIAN)
 	    {
-	      rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
+	      rtx num_ele_m1 = GEN_INT (num_elements - 1);
 
 	      emit_insn (gen_anddi3 (tmp_gpr, element, num_ele_m1));
 	      emit_insn (gen_subdi3 (tmp_gpr, num_ele_m1, tmp_gpr));
@@ -7307,8 +7326,8 @@  rs6000_split_vec_extract_var (rtx dest, rtx src, r
 	    emit_insn (gen_vsx_vslo_v2di (tmp_altivec_di, src_v2di,
 					  tmp_altivec));
 	    emit_move_insn (tmp_gpr_di, tmp_altivec_di);
-	    emit_insn (gen_ashrdi3 (tmp_gpr_di, tmp_gpr_di,
-				    GEN_INT (64 - (8 * scalar_size))));
+	    emit_insn (gen_lshrdi3 (tmp_gpr_di, tmp_gpr_di,
+				    GEN_INT (64 - bits_in_element)));
 	    return;
 	  }
 
@@ -14723,9 +14742,17 @@  altivec_expand_vec_ext_builtin (tree exp, rtx targ
   op0 = expand_normal (arg0);
   op1 = expand_normal (arg1);
 
-  /* Call get_element_number to validate arg1 if it is a constant.  */
   if (TREE_CODE (arg1) == INTEGER_CST)
-    (void) get_element_number (TREE_TYPE (arg0), arg1);
+    {
+      unsigned HOST_WIDE_INT elt;
+      unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+      unsigned int truncated_selector;
+      if (!tree_fits_uhwi_p (arg1))
+	error ("selector expression is out of range");
+      elt = tree_to_uhwi (arg1);
+      truncated_selector = elt % size;
+      op1 = GEN_INT (truncated_selector);
+    }
 
   tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
   mode0 = TYPE_MODE (TREE_TYPE (arg0));
Index: gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c	(revision 269492)
+++ gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c	(working copy)
@@ -18,7 +18,7 @@ 
 /* { dg-final { scan-assembler-times {\mxxpermdi\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times {\mvslo\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times {\mmfvsrd\M} 6 { target lp64 } } } */
-/* { dg-final { scan-assembler-times {\msradi\M} 3 { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\msrdi\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times "extsb" 2 } } */
 /* { dg-final { scan-assembler-times {\mvspltb\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times {\mrlwinm\M} 2 { target lp64} } } */
Index: gcc/testsuite/gcc.target/powerpc/fold-vec-extract-int.p8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/fold-vec-extract-int.p8.c	(revision 269492)
+++ gcc/testsuite/gcc.target/powerpc/fold-vec-extract-int.p8.c	(working copy)
@@ -21,7 +21,7 @@ 
 /* { dg-final { scan-assembler-times {\mxxpermdi\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times {\mvslo\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times {\mmfvsrd\M} 3 { target lp64 } } } */
-/* { dg-final { scan-assembler-times {\msradi\M} 3 { target lp64 } } } */
+/* { dg-final { scan-assembler-times {\msrdi\M} 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times {\mextsw\M} 2 { target lp64 } } } */
 
 
Index: gcc/testsuite/gcc.target/powerpc/fold-vec-extract-short.p8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/fold-vec-extract-short.p8.c	(revision 269492)
+++ gcc/testsuite/gcc.target/powerpc/fold-vec-extract-short.p8.c	(working copy)
@@ -6,9 +6,9 @@ 
 /* { dg-options "-mdejagnu-cpu=power8 -O2" } */
 
 // six tests total. Targeting P8, both LE and BE.
-// p8 (le) variable offset: rldicl, subfic, sldi, mtvsrd, xxpermdi, vslo, mfvsrd, sradi, *extsh
+// p8 (le) variable offset: rldicl, subfic, sldi, mtvsrd, xxpermdi, vslo, mfvsrd, srdi, *extsh
 // p8 (le) const offset:                          mtvsrd,                                *extsh/rlwinm
-// p8 (be) var offset:                      sldi, mtvsrd, xxpermdi, vslo, mfvsrd, sradi, *extsh
+// p8 (be) var offset:                      sldi, mtvsrd, xxpermdi, vslo, mfvsrd, srdi, *extsh
 // p8 (be) const offset:    vsplth,               mfvsrd,                                *extsh/rlwinm
 
 // * - each of the above will have an extsh if the argument is signed.
@@ -22,7 +22,7 @@ 
 /* { dg-final { scan-assembler-times "xxpermdi" 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times "vslo" 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times "mfvsrd" 6 { target lp64 } } } */
-/* { dg-final { scan-assembler-times "sradi" 3 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "srdi" 3 { target lp64 } } } */
 /* { dg-final { scan-assembler-times "extsh" 2 { target lp64 } } } */
 /* { dg-final { scan-assembler-times "rlwinm" 2 { target lp64 } } } */
 
Index: gcc/testsuite/gcc.target/powerpc/pr87532-mc.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr87532-mc.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr87532-mc.c	(working copy)
@@ -0,0 +1,258 @@ 
+/* { dg-do run { target { int128 } } } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec -O2" } */
+
+/* This test should run the same on any target that supports altivec/dfp
+   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)) unsigned __int128
+get_auto_n_uint128 (vector unsigned __int128 a, int n)
+{
+  return __builtin_vec_extract (a, n);
+}
+
+__attribute ((noinline)) unsigned long long int
+get_auto_n_ulong (vector unsigned long long int a, int n)
+{
+  return __builtin_vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned int get_auto_n_uint (vector unsigned int a, int n)
+{
+  return __builtin_vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned char get_auto_n_uchar (vector unsigned char a, int n)
+{
+  return __builtin_vec_extract (a, n);
+}
+
+__attribute ((noinline))
+unsigned short get_auto_n_ushort (vector unsigned short a, int n)
+{
+  return __builtin_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));
+}
+
+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;
+    }
+}
+
+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;
+    }
+}
+
+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;
+    }
+}
+
+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;
+    }
+}
+
+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 ();
+    }
+ }
+
+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 ();
+    }
+ }
+
+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 ();
+    }
+ }
+
+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 ();
+    }
+}
+
+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 = {
+    ((((unsigned __int128) 0xffeeddccbbaa9988ULL) << 64)
+     | 0x0706050403020100ULL) };
+  vector unsigned __int128 du;
+
+  vector unsigned long long int v = { 0x9999901010ULL, 0x7777733333ULL };
+  vector unsigned long long int dv;
+
+  vector unsigned int x = { 0x99999, 0x01010, 0x77777, 0x33333 };
+  vector unsigned int dx;
+
+  vector unsigned char y = { 0x90, 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20,
+			     0x10, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, 0xff };
+  vector unsigned char dy;
+
+  vector unsigned short z = { 0x9988, 0x8877, 0x7766, 0x6655,
+			      0x5544, 0x4433, 0x3322, 0x2211 };
+  vector unsigned short dz;
+
+  do_auto_uint128 (u);
+  do_auto_ulong (v);
+  do_auto_uint (x);
+  do_auto_uchar (y);
+  do_auto_ushort (z);
+
+  du = deoptimize_uint128 (u);
+  dv = deoptimize_ulong (v);
+  dx = deoptimize_uint (x);
+  dy = deoptimize_uchar (y);
+  dz = deoptimize_ushort (z);
+
+  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/pr87532.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr87532.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr87532.c	(working copy)
@@ -0,0 +1,72 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/dfp
+   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 void
+check (unsigned char, unsigned char) __attribute__((__noinline__));
+
+static __attribute__((altivec(vector__))) unsigned char
+deoptimize (__attribute__((altivec(vector__))) unsigned char)
+__attribute__((__noinline__));
+
+static __attribute__((altivec(vector__))) unsigned char
+deoptimize (__attribute__((altivec(vector__))) unsigned char a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+// Toggle this attribute inline/noinline to see pass/fail.
+// fails with the noinline attribute applied.
+__attribute__ ((__noinline__))
+unsigned char
+get_auto_n (__attribute__((altivec(vector__))) unsigned char a, size_t n)
+{
+  return (unsigned char) __builtin_vec_extract (a, n);
+}
+
+void
+do_auto (__attribute__((altivec(vector__))) unsigned char a)
+{
+  size_t i;
+  for (i = 1; i < 3 ; i++)
+  {
+    do
+      {
+	printf ("get_auto_n (a, %d) produces 0x0%x\n",
+		i, (int) get_auto_n (a, i));
+
+	if ((int) get_auto_n (a,i) > 250) abort();
+      } while (0);
+  }
+}
+
+int
+main (void)
+{
+  size_t i;
+  __attribute__((altivec(vector__))) unsigned char x =
+    { 3, 2, 3, 8, 5, 6, 7, 8, 240, 241, 242, 243, 244, 245, 246, 247 };
+  __attribute__((altivec(vector__))) unsigned char a;
+
+  printf (" first elements of x are: %d %d %d %d %d\n",
+	  x[0], x[1], x[2], x[3], x[4]);
+
+  a = deoptimize (x);
+
+  printf (" after deoptimization, first elements of a are: %d %d %d %d %d\n",
+	  a[0], a[1], a[2], a[3], a[4]);
+
+  do_auto (a);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2.h
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2.h	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2.h	(working copy)
@@ -0,0 +1,253 @@ 
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#ifndef RTYPE
+#define RTYPE TYPE
+#endif
+
+#ifdef DO_TRACE
+#include <stdio.h>
+
+#define TRACE(STRING, NUM)						\
+do									\
+  {									\
+    fprintf (stderr, "%s: %2d\n", STRING, (int) NUM);			\
+    fflush (stderr);							\
+  }									\
+while (0)
+
+#ifndef FAIL_FORMAT
+#define FAIL_FORMAT "%ld"
+#define FAIL_CAST(X) ((long)(X))
+#endif
+
+#define FAIL(EXP, GOT)							 \
+do									 \
+  {									 \
+    fprintf (stderr, "Expected: " FAIL_FORMAT ", got " FAIL_FORMAT "\n", \
+	     FAIL_CAST (EXP), FAIL_CAST (GOT));				 \
+    fflush (stderr);							 \
+    abort ();								 \
+  }									 \
+while (0)
+
+#else
+#define TRACE(STRING, NUM)
+#define FAIL(EXP, GOT) abort ()
+#endif
+
+static void
+check (RTYPE, RTYPE) __attribute__((__noinline__));
+
+static vector TYPE
+deoptimize (vector TYPE) __attribute__((__noinline__));
+
+static vector TYPE
+*deoptimize_ptr (vector TYPE *)	__attribute__((__noinline__));
+
+static void
+check (RTYPE expected, RTYPE got)
+{
+  if (expected != got)
+    FAIL (expected, got);
+}
+
+static vector TYPE
+deoptimize (vector TYPE a)
+{
+  __asm__ (" # %x0" : "+v" (a));
+  return a;
+}
+
+static vector TYPE *
+deoptimize_ptr (vector TYPE *p)
+{
+  __asm__ (" # %0" : "+r" (p));
+  return p;
+}
+
+
+RTYPE
+get_auto_0 (vector TYPE a)
+{
+  TRACE ("get_auto_", 0);
+  return (RTYPE) vec_extract (a, 0);
+}
+
+RTYPE
+get_auto_1 (vector TYPE a)
+{
+  TRACE ("get_auto_", 1);
+  return (RTYPE) vec_extract (a, 1);
+}
+
+#if ELEMENTS >= 4
+RTYPE
+get_auto_2 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 2);
+}
+
+RTYPE
+get_auto_3 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 3);
+}
+
+#if ELEMENTS >= 8
+RTYPE
+get_auto_4 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 4);
+}
+
+RTYPE
+get_auto_5 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 5);
+}
+
+RTYPE
+get_auto_6 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 6);
+}
+
+RTYPE
+get_auto_7 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 7);
+}
+
+#if ELEMENTS >= 16
+RTYPE
+get_auto_8 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 8);
+}
+
+RTYPE
+get_auto_9 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 9);
+}
+
+RTYPE
+get_auto_10 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 10);
+}
+
+RTYPE
+get_auto_11 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 11);
+}
+
+RTYPE
+get_auto_12 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 12);
+}
+
+RTYPE
+get_auto_13 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 13);
+}
+
+RTYPE
+get_auto_14 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 14);
+}
+
+RTYPE
+get_auto_15 (vector TYPE a)
+{
+  return (RTYPE) vec_extract (a, 15);
+}
+
+#endif
+#endif
+#endif
+
+
+/* Tests for the normal case of vec_extract where the vector is in a register
+   and returning the result in a register as a return value.  */
+#ifdef DISABLE_INLINE_OF_GET_AUTO_N
+__attribute__ ((__noinline__))
+#else
+/* gcc issues warning: always_inline function might not be inlinable
+
+   __attribute__ ((__always_inline__))
+*/
+#endif
+RTYPE
+get_auto_n (vector TYPE a, ssize_t n)
+{
+  return (RTYPE) vec_extract (a, n);
+}
+
+typedef RTYPE (*auto_func_type) (vector TYPE);
+
+static auto_func_type get_auto_const[] = {
+  get_auto_0,
+  get_auto_1,
+#if ELEMENTS >= 4
+  get_auto_2,
+  get_auto_3,
+#if ELEMENTS >= 8
+  get_auto_4,
+  get_auto_5,
+  get_auto_6,
+  get_auto_7,
+#if ELEMENTS >= 16
+  get_auto_8,
+  get_auto_9,
+  get_auto_10,
+  get_auto_11,
+  get_auto_12,
+  get_auto_13,
+  get_auto_14,
+  get_auto_15,
+#endif
+#endif
+#endif
+};
+
+extern void do_auto (vector TYPE a) __attribute__((__noinline__));
+
+void
+do_auto (vector TYPE a)
+{
+  size_t i;
+
+  for (i = 1; i < 40; i += 3)
+    {
+      TRACE ("do_auto, i: ", i);
+      TRACE ("  get_auto_const[i] returns: ",
+	     (*get_auto_const [i % ELEMENTS]) (a));
+      TRACE ("  get_auto_n returns", get_auto_n (a, i));
+      check (get_auto_n (a, i), (*get_auto_const [i % ELEMENTS]) (a));
+    }
+}
+
+
+
+/* Main program to test all of the possibilities.  */
+int
+main (void)
+{
+  size_t i;
+  vector TYPE x = INITIAL;
+  vector TYPE *p, *p2, a, y;
+  vector TYPE z[2];
+
+  a = deoptimize (x);
+
+  do_auto (a);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2a.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2 -mvsx" } */
+
+#define TYPE unsigned char
+/* ELEMENTS is number of elements in a vector of TYPE.  */
+#define ELEMENTS 16
+#define INITIAL \
+  {  3, 2, 3, 4, 5, 6, 7, 8, 240, 241, 242, 243, 244, 245, 246, 247 }
+
+#define DO_TRACE
+#define DISABLE_INLINE_OF_GET_AUTO_N
+
+#include "vec-extract-v16qiu-v2.h"
Index: gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2b.c	(working copy)
@@ -0,0 +1,14 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2 -mvsx" } */
+
+#define TYPE unsigned char
+/* ELEMENTS is number of elements in a vector of TYPE.  */
+#define ELEMENTS 16
+#define INITIAL \
+  {  3, 2, 3, 4, 5, 6, 7, 8, 240, 241, 242, 243, 244, 245, 246, 247 }
+
+#define DO_TRACE
+#undef DISABLE_INLINE_OF_GET_AUTO_N
+
+#include "vec-extract-v16qiu-v2.h"
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-10a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-10a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-10a.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/dfp
+   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.  */
+short s3 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 3);
+}
+
+short s7 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 7);
+}
+
+short s21 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 21);
+}
+
+short s30 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+short ms3 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 3);
+}
+
+short ms7 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 7);
+}
+
+short ms21 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 21);
+}
+
+short ms30 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+short ci (vector short v, int i)
+{
+  return __builtin_vec_ext_v8hi (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+short mci (vector short *vp, int i)
+{
+  return __builtin_vec_ext_v8hi (*vp, i);
+}
+
+
+int main (int argc, short *argv[]) {
+  vector short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+  short s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s7 (sv);
+  if (s != CONST7)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST5)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms7 (&sv);
+  if (s != CONST7)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST5)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST7)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-10b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-10b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-10b.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/dfp
+   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.  */
+short s3 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 3);
+}
+
+short s7 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 7);
+}
+
+short s21 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 21);
+}
+
+short s30 (vector short v)
+{
+  return __builtin_vec_ext_v8hi (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+short ms3 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 3);
+}
+
+short ms7 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 7);
+}
+
+short ms21 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 21);
+}
+
+short ms30 (vector short *vp)
+{
+  return __builtin_vec_ext_v8hi (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+short ci (vector short v, int i)
+{
+  return __builtin_vec_ext_v8hi (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+short mci (vector short *vp, int i)
+{
+  return __builtin_vec_ext_v8hi (*vp, i);
+}
+
+
+int main (int argc, short *argv[]) {
+  vector short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+  short s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s7 (sv);
+  if (s != CONST7)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST5)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms7 (&sv);
+  if (s != CONST7)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST5)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST7)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-11a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-11a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-11a.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/dfp
+   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.  */
+int s3 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 3);
+}
+
+int s1 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 1);
+}
+
+int s21 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 21);
+}
+
+int s30 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+int ms3 (vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 3);
+}
+
+int ms1(vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 1);
+}
+
+int ms21(vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 21);
+}
+
+int ms30(vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+int ci (vector int v, int i)
+{
+  return __builtin_vec_ext_v4si (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+int mci(vector int *vp, int i)
+{
+  return __builtin_vec_ext_v4si (*vp, i);
+}
+
+
+int main (int argc, int *argv[]) {
+  vector int sv = { CONST0, CONST1, CONST2, CONST3 };
+  int s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s1 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms1 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST3)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-11b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-11b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-11b.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/dfp
+   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.  */
+int s3 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 3);
+}
+
+int s1 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 1);
+}
+
+int s21 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 21);
+}
+
+int s30 (vector int v)
+{
+  return __builtin_vec_ext_v4si (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+int ms3 (vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 3);
+}
+
+int ms1(vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 1);
+}
+
+int ms21(vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 21);
+}
+
+int ms30(vector int *vp)
+{
+  return __builtin_vec_ext_v4si (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+int ci (vector int v, int i)
+{
+  return __builtin_vec_ext_v4si (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+int mci(vector int *vp, int i)
+{
+  return __builtin_vec_ext_v4si (*vp, i);
+}
+
+
+int main (int argc, int *argv[]) {
+  vector int sv = { CONST0, CONST1, CONST2, CONST3 };
+  int s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s1 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms1 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST3)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-12a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-12a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-12a.c	(working copy)
@@ -0,0 +1,109 @@ 
+/* { 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)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+long long int e0 (vector long long int v)
+{
+  return __builtin_vec_ext_v2di (v, 0);
+}
+
+long long int e3 (vector long long int v)
+{
+  return __builtin_vec_ext_v2di (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+long long int me0 (vector long long int *vp)
+{
+  return __builtin_vec_ext_v2di (*vp, 0);
+}
+
+long long int me3 (vector long long int *vp)
+{
+  return __builtin_vec_ext_v2di (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+long long int ei (vector long long int v, int i)
+{
+  return __builtin_vec_ext_v2di (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+long long int mei (vector long long int *vp, int i)
+{
+  return __builtin_vec_ext_v2di (*vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector long long int dv = { CONST0, CONST1 };
+  long long int d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-12b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-12b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-12b.c	(working copy)
@@ -0,0 +1,109 @@ 
+/* { 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)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+long long int e0 (vector long long int v)
+{
+  return __builtin_vec_ext_v2di (v, 0);
+}
+
+long long int e3 (vector long long int v)
+{
+  return __builtin_vec_ext_v2di (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+long long int me0 (vector long long int *vp)
+{
+  return __builtin_vec_ext_v2di (*vp, 0);
+}
+
+long long int me3 (vector long long int *vp)
+{
+  return __builtin_vec_ext_v2di (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+long long int ei (vector long long int v, int i)
+{
+  return __builtin_vec_ext_v2di (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+long long int mei (vector long long int *vp, int i)
+{
+  return __builtin_vec_ext_v2di (*vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector long long int dv = { CONST0, CONST1 };
+  long long int d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c	(working copy)
@@ -0,0 +1,124 @@ 
+/* { 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 this after PR89424 is addressed.  */
+#undef PR89424
+
+/* Define this after PR89626 is addressed.  */
+#undef PR89626
+
+#ifdef PR89626
+#define SIGNED
+#else
+#define SIGNED signed
+#endif
+
+extern void abort (void);
+
+#define CONST0		(((SIGNED __int128) 31415926539) << 60)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+SIGNED __int128 e0 (vector SIGNED __int128 v)
+{
+  return __builtin_vec_ext_v1ti (v, 0);
+}
+
+SIGNED __int128 e3 (vector SIGNED __int128 v)
+{
+  return __builtin_vec_ext_v1ti (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+SIGNED __int128 me0 (vector SIGNED __int128 *vp)
+{
+  return __builtin_vec_ext_v1ti (*vp, 0);
+}
+
+SIGNED __int128 me3 (vector SIGNED __int128 *vp)
+{
+  return __builtin_vec_ext_v1ti (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+#ifdef PR89424
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+SIGNED __int128 ei (vector SIGNED __int128 v, int i)
+{
+  return __builtin_vec_ext_v1ti (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+SIGNED __int128 mei (vector SIGNED __int128 *vp, int i)
+{
+  return __builtin_vec_ext_v1ti (*vp, i);
+}
+#endif
+
+int main (int argc, char *argv[]) {
+  vector SIGNED __int128 dv = { CONST0 };
+  SIGNED __int128 d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST0)
+    abort ();
+
+#ifdef PR89424
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST0)
+    abort ();
+#endif
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c	(working copy)
@@ -0,0 +1,124 @@ 
+/* { 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 this after PR89424 is addressed.  */
+#undef PR89424
+
+/* Define this after PR89626 is addressed.  */
+#undef PR89626
+
+#ifdef PR89626
+#define SIGNED
+#else
+#define SIGNED signed
+#endif
+
+extern void abort (void);
+
+#define CONST0		(((SIGNED __int128) 31415926539) << 60)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+SIGNED __int128 e0 (vector SIGNED __int128 v)
+{
+  return __builtin_vec_ext_v1ti (v, 0);
+}
+
+SIGNED __int128 e3 (vector SIGNED __int128 v)
+{
+  return __builtin_vec_ext_v1ti (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+SIGNED __int128 me0 (vector SIGNED __int128 *vp)
+{
+  return __builtin_vec_ext_v1ti (*vp, 0);
+}
+
+SIGNED __int128 me3 (vector SIGNED __int128 *vp)
+{
+  return __builtin_vec_ext_v1ti (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+#ifdef PR89424
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+SIGNED __int128 ei (vector SIGNED __int128 v, int i)
+{
+  return __builtin_vec_ext_v1ti (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+SIGNED __int128 mei (vector SIGNED __int128 *vp, int i)
+{
+  return __builtin_vec_ext_v1ti (*vp, i);
+}
+#endif
+
+int main (int argc, char *argv[]) {
+  vector SIGNED __int128 dv = { CONST0 };
+  SIGNED __int128 d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST0)
+    abort ();
+
+#ifdef PR89424
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST0)
+    abort ();
+#endif
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-14a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-14a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-14a.c	(working copy)
@@ -0,0 +1,126 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/dfp
+   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.  */
+float e0(vector float v){ return __builtin_vec_ext_v4sf (v, 0); }
+float e1(vector float v){ return __builtin_vec_ext_v4sf (v, 1); }
+float e7(vector float v){ return __builtin_vec_ext_v4sf (v, 7); }
+float e8(vector float v){ return __builtin_vec_ext_v4sf (v, 8); }
+
+/* Test for vector residing in memory.  */
+float me0(vector float *vp){ return __builtin_vec_ext_v4sf (*vp, 0); }
+float me1(vector float *vp){ return __builtin_vec_ext_v4sf (*vp, 1); }
+
+float me13(vector float *vp)
+{
+  return __builtin_vec_ext_v4sf (*vp, 13);
+}
+
+float me15(vector float *vp)
+{
+  return __builtin_vec_ext_v4sf (*vp, 15);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+float ei(vector float v, int i)
+{
+  return __builtin_vec_ext_v4sf (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+float mei(vector float *vp, int i)
+{
+  return __builtin_vec_ext_v4sf (*vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector float dv = { CONST0, CONST1, CONST2, CONST3 };
+  float d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e1 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = e7 (dv);
+  if (d != CONST3)
+    abort ();
+
+  d = e8 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me1 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me13 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me15 (&dv);
+  if (d != CONST3)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST2)
+    abort ();
+
+  d = ei (dv, 11);
+  if (d != CONST3)
+    abort ();
+
+  d = ei (dv, 17);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 15);
+  if (d != CONST3)
+    abort ();
+
+  d = mei (&dv, 6);
+  if (d != CONST2)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-14b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-14b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-14b.c	(working copy)
@@ -0,0 +1,126 @@ 
+/* { 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/dfp
+   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.  */
+float e0(vector float v){ return __builtin_vec_ext_v4sf (v, 0); }
+float e1(vector float v){ return __builtin_vec_ext_v4sf (v, 1); }
+float e7(vector float v){ return __builtin_vec_ext_v4sf (v, 7); }
+float e8(vector float v){ return __builtin_vec_ext_v4sf (v, 8); }
+
+/* Test for vector residing in memory.  */
+float me0(vector float *vp){ return __builtin_vec_ext_v4sf (*vp, 0); }
+float me1(vector float *vp){ return __builtin_vec_ext_v4sf (*vp, 1); }
+
+float me13(vector float *vp)
+{
+  return __builtin_vec_ext_v4sf (*vp, 13);
+}
+
+float me15(vector float *vp)
+{
+  return __builtin_vec_ext_v4sf (*vp, 15);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+float ei(vector float v, int i)
+{
+  return __builtin_vec_ext_v4sf (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+float mei(vector float *vp, int i)
+{
+  return __builtin_vec_ext_v4sf (*vp, i);
+}
+
+
+int main (int argc, char *argv[]) {
+  vector float dv = { CONST0, CONST1, CONST2, CONST3 };
+  float d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e1 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = e7 (dv);
+  if (d != CONST3)
+    abort ();
+
+  d = e8 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me1 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me13 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me15 (&dv);
+  if (d != CONST3)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST2)
+    abort ();
+
+  d = ei (dv, 11);
+  if (d != CONST3)
+    abort ();
+
+  d = ei (dv, 17);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 15);
+  if (d != CONST3)
+    abort ();
+
+  d = mei (&dv, 6);
+  if (d != CONST2)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-15a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-15a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-15a.c	(working copy)
@@ -0,0 +1,113 @@ 
+/* { 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)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+double e0(vector double v){ return __builtin_vec_ext_v2df (v, 0); }
+double e1(vector double v){ return __builtin_vec_ext_v2df (v, 1); }
+double e2(vector double v){ return __builtin_vec_ext_v2df (v, 2); }
+double e3(vector double v){ return __builtin_vec_ext_v2df (v, 3); }
+
+/* Test for vector residing in memory.  */
+double me0(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 0); }
+double me1(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 1); }
+double me2(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 2); }
+double me3(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 3); }
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+double ei(vector double v, int i){ return __builtin_vec_ext_v2df (v, i); }
+
+/* Test for variable selector and vector residing in memory.  */
+double mei(vector double *vp, int i){ return __builtin_vec_ext_v2df (*vp, i); }
+
+
+int main (int argc, char *argv[]) {
+  vector double dv;
+  double d;
+  dv[0] = CONST0;
+  dv[1] = CONST1;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e1 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = e2 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me1 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me2 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-15b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-15b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-15b.c	(working copy)
@@ -0,0 +1,113 @@ 
+/* { 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)
+
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+double e0(vector double v){ return __builtin_vec_ext_v2df (v, 0); }
+double e1(vector double v){ return __builtin_vec_ext_v2df (v, 1); }
+double e2(vector double v){ return __builtin_vec_ext_v2df (v, 2); }
+double e3(vector double v){ return __builtin_vec_ext_v2df (v, 3); }
+
+/* Test for vector residing in memory.  */
+double me0(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 0); }
+double me1(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 1); }
+double me2(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 2); }
+double me3(vector double *vp){ return __builtin_vec_ext_v2df (*vp, 3); }
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+double ei(vector double v, int i){ return __builtin_vec_ext_v2df (v, i); }
+
+/* Test for variable selector and vector residing in memory.  */
+double mei(vector double *vp, int i){ return __builtin_vec_ext_v2df (*vp, i); }
+
+
+int main (int argc, char *argv[]) {
+  vector double dv;
+  double d;
+  dv[0] = CONST0;
+  dv[1] = CONST1;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e1 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = e2 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me1 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me2 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-16a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-16a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-16a.c	(working copy)
@@ -0,0 +1,165 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target vmx_hw } */
+/* { dg-options "-maltivec" } */
+
+/* This test should run the same on any target that supports altivec/dfp
+   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.  */
+unsigned char c0 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 0);
+}
+
+unsigned char c9 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 9);
+}
+
+unsigned char c21 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 21);
+}
+
+unsigned char c30 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+unsigned char mc0 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 0);
+}
+
+unsigned char mc9 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 9);
+}
+
+unsigned char mc21 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 21);
+}
+
+unsigned char mc30 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned char ci (vector unsigned char v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+unsigned char mci (vector unsigned char *vp, int i)
+{
+  return __builtin_vec_extract (*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 };
+  unsigned char c;
+
+  c = c0 (cv);
+  if (c != CONST0)
+    abort ();
+
+  c = c9 (cv);
+  if (c != CONST9)
+    abort ();
+
+  c = c21 (cv);
+  if (c != CONST5)
+    abort ();
+
+  c = c30 (cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = mc0 (&cv);
+  if (c != CONST0)
+    abort ();
+
+  c = mc9 (&cv);
+  if (c != CONST9)
+    abort ();
+
+  c = mc21 (&cv);
+  if (c != CONST5)
+    abort ();
+
+  c = mc30 (&cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = ci (cv, 8);
+  if (c != CONST8)
+    abort ();
+
+  c = ci (cv, 13);
+  if (c != CONSTD)
+    abort ();
+
+  c = ci (cv, 23);
+  if (c != CONST7)
+    abort ();
+
+  c = ci (cv, 31);
+  if (c != CONSTF)
+    abort ();
+
+  c = mci (&cv, 5);
+  if (c != CONST5)
+    abort ();
+
+  c = mci (&cv, 12);
+  if (c != CONSTC)
+    abort ();
+
+  c = mci (&cv, 25);
+  if (c != CONST9)
+    abort ();
+
+  c = mci (&cv, 16);
+  if (c != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-16b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-16b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-16b.c	(working copy)
@@ -0,0 +1,165 @@ 
+/* { 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/dfp
+   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.  */
+unsigned char c0 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 0);
+}
+
+unsigned char c9 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 9);
+}
+
+unsigned char c21 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 21);
+}
+
+unsigned char c30 (vector unsigned char v)
+{
+  return __builtin_vec_extract (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+unsigned char mc0 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 0);
+}
+
+unsigned char mc9 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 9);
+}
+
+unsigned char mc21 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 21);
+}
+
+unsigned char mc30 (vector unsigned char *vp)
+{
+  return __builtin_vec_extract (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned char ci (vector unsigned char v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+unsigned char mci (vector unsigned char *vp, int i)
+{
+  return __builtin_vec_extract (*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 };
+  unsigned char c;
+
+  c = c0 (cv);
+  if (c != CONST0)
+    abort ();
+
+  c = c9 (cv);
+  if (c != CONST9)
+    abort ();
+
+  c = c21 (cv);
+  if (c != CONST5)
+    abort ();
+
+  c = c30 (cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = mc0 (&cv);
+  if (c != CONST0)
+    abort ();
+
+  c = mc9 (&cv);
+  if (c != CONST9)
+    abort ();
+
+  c = mc21 (&cv);
+  if (c != CONST5)
+    abort ();
+
+  c = mc30 (&cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = ci (cv, 8);
+  if (c != CONST8)
+    abort ();
+
+  c = ci (cv, 13);
+  if (c != CONSTD)
+    abort ();
+
+  c = ci (cv, 23);
+  if (c != CONST7)
+    abort ();
+
+  c = ci (cv, 31);
+  if (c != CONSTF)
+    abort ();
+
+  c = mci (&cv, 5);
+  if (c != CONST5)
+    abort ();
+
+  c = mci (&cv, 12);
+  if (c != CONSTC)
+    abort ();
+
+  c = mci (&cv, 25);
+  if (c != CONST9)
+    abort ();
+
+  c = mci (&cv, 16);
+  if (c != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-17a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-17a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-17a.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/dfp
+   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.  */
+unsigned short s3 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+unsigned short s7 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 7);
+}
+
+unsigned short s21 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 21);
+}
+
+unsigned short s30 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+unsigned short ms3 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+unsigned short ms7 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 7);
+}
+
+unsigned short ms21 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 21);
+}
+
+unsigned short ms30 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned short ci (vector unsigned short v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+unsigned short mci (vector unsigned short *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+
+
+int main (int argc, unsigned short *argv[]) {
+  vector unsigned short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+  unsigned short s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s7 (sv);
+  if (s != CONST7)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST5)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms7 (&sv);
+  if (s != CONST7)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST5)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST7)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-17b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-17b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-17b.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/dfp
+   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.  */
+unsigned short s3 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+unsigned short s7 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 7);
+}
+
+unsigned short s21 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 21);
+}
+
+unsigned short s30 (vector unsigned short v)
+{
+  return __builtin_vec_extract (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+unsigned short ms3 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+unsigned short ms7 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 7);
+}
+
+unsigned short ms21 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 21);
+}
+
+unsigned short ms30 (vector unsigned short *vp)
+{
+  return __builtin_vec_extract (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned short ci (vector unsigned short v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+unsigned short mci (vector unsigned short *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+
+
+int main (int argc, unsigned short *argv[]) {
+  vector unsigned short sv = {
+    CONST0, CONST1, CONST2, CONST3, CONST4, CONST5, CONST6, CONST7 };
+  unsigned short s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s7 (sv);
+  if (s != CONST7)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST5)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms7 (&sv);
+  if (s != CONST7)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST5)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST6)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST7)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST5)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST4)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-18a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-18a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-18a.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/dfp
+   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.  */
+unsigned int s3 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+unsigned int s1 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 1);
+}
+
+unsigned int s21 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 21);
+}
+
+unsigned int s30 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+unsigned int ms3 (vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+unsigned int ms1(vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 1);
+}
+
+unsigned int ms21(vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 21);
+}
+
+unsigned int ms30(vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned int ci (vector unsigned int v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+unsigned int mci(vector unsigned int *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+
+
+unsigned int main (int argc, unsigned char *argv[]) {
+  vector unsigned int sv = { CONST0, CONST1, CONST2, CONST3 };
+  unsigned int s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s1 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms1 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST3)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-18b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-18b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-18b.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/dfp
+   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.  */
+unsigned int s3 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+unsigned int s1 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 1);
+}
+
+unsigned int s21 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 21);
+}
+
+unsigned int s30 (vector unsigned int v)
+{
+  return __builtin_vec_extract (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+unsigned int ms3 (vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+unsigned int ms1(vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 1);
+}
+
+unsigned int ms21(vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 21);
+}
+
+unsigned int ms30(vector unsigned int *vp)
+{
+  return __builtin_vec_extract (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned int ci (vector unsigned int v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+unsigned int mci(vector unsigned int *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+
+
+unsigned int main (int argc, unsigned char *argv[]) {
+  vector unsigned int sv = { CONST0, CONST1, CONST2, CONST3 };
+  unsigned int s;
+
+  s = s3 (sv);
+  if (s != CONST3)
+    abort ();
+
+  s = s1 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s21 (sv);
+  if (s != CONST1)
+    abort ();
+
+  s = s30 (sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ms3 (&sv);
+  if (s != CONST3)
+    abort ();
+
+  s = ms1 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms21 (&sv);
+  if (s != CONST1)
+    abort ();
+
+  s = ms30 (&sv);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = ci (sv, 2);
+  if (s != CONST2)
+    abort ();
+
+  s = ci (sv, 15);
+  if (s != CONST3)
+    abort ();
+
+  s = ci (sv, 28);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 5);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 12);
+  if (s != CONST0)
+    abort ();
+
+  s = mci (&sv, 25);
+  if (s != CONST1)
+    abort ();
+
+  s = mci (&sv, 16);
+  if (s != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-19a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-19a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-19a.c	(working copy)
@@ -0,0 +1,109 @@ 
+/* { 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)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+unsigned long long int e0 (vector unsigned long long int v)
+{
+  return __builtin_vec_extract (v, 0);
+}
+
+unsigned long long int e3 (vector unsigned long long int v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+unsigned long long int me0 (vector unsigned long long int *vp)
+{
+  return __builtin_vec_extract (*vp, 0);
+}
+
+unsigned long long int me3 (vector unsigned long long int *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned long long int ei (vector unsigned long long int v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+unsigned long long int mei (vector unsigned long long int *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector unsigned long long int dv = { CONST0, CONST1 };
+  unsigned long long int d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-19b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-19b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-19b.c	(working copy)
@@ -0,0 +1,109 @@ 
+/* { 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)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+unsigned long long int e0 (vector unsigned long long int v)
+{
+  return __builtin_vec_extract (v, 0);
+}
+
+unsigned long long int e3 (vector unsigned long long int v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+unsigned long long int me0 (vector unsigned long long int *vp)
+{
+  return __builtin_vec_extract (*vp, 0);
+}
+
+unsigned long long int me3 (vector unsigned long long int *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned long long int ei (vector unsigned long long int v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+unsigned long long int mei (vector unsigned long long int *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+
+int main (int argc, char *argv[]) {
+  vector unsigned long long int dv = { CONST0, CONST1 };
+  unsigned long long int d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST1)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST1)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST1)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.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 this after PR89424 is addressed.  */
+#undef PR89424
+
+extern void abort (void);
+
+#define CONST0		(((unsigned __int128) 31415926539) << 60)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+unsigned __int128 e0 (vector unsigned __int128 v)
+{
+  return __builtin_vec_extract (v, 0);
+}
+
+unsigned __int128 e3 (vector unsigned __int128 v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+unsigned __int128 me0 (vector unsigned __int128 *vp)
+{
+  return __builtin_vec_extract (*vp, 0);
+}
+
+unsigned __int128 me3 (vector unsigned __int128 *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+#ifdef PR89424
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned __int128 ei (vector unsigned __int128 v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+unsigned __int128 mei (vector unsigned __int128 *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+#endif
+
+int main (int argc, char *argv[]) {
+  vector unsigned __int128 dv = { CONST0 };
+  unsigned __int128 d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST0)
+    abort ();
+
+#ifdef PR89424
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST0)
+    abort ();
+#endif
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.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 this after PR89424 is addressed.  */
+#undef PR89424
+
+extern void abort (void);
+
+#define CONST0		(((unsigned __int128) 31415926539) << 60)
+
+/* Test that indices > length of vector are applied modulo the vector
+   length.  */
+
+/* Test for vector residing in register.  */
+unsigned __int128 e0 (vector unsigned __int128 v)
+{
+  return __builtin_vec_extract (v, 0);
+}
+
+unsigned __int128 e3 (vector unsigned __int128 v)
+{
+  return __builtin_vec_extract (v, 3);
+}
+
+/* Test for vector residing in memory.  */
+unsigned __int128 me0 (vector unsigned __int128 *vp)
+{
+  return __builtin_vec_extract (*vp, 0);
+}
+
+unsigned __int128 me3 (vector unsigned __int128 *vp)
+{
+  return __builtin_vec_extract (*vp, 3);
+}
+
+/* Test the same with variable indices.  */
+
+#ifdef PR89424
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+unsigned __int128 ei (vector unsigned __int128 v, int i)
+{
+  return __builtin_vec_extract (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+unsigned __int128 mei (vector unsigned __int128 *vp, int i)
+{
+  return __builtin_vec_extract (*vp, i);
+}
+#endif
+
+int main (int argc, char *argv[]) {
+  vector unsigned __int128 dv = { CONST0 };
+  unsigned __int128 d;
+
+  d = e0 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = e3 (dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me0 (&dv);
+  if (d != CONST0)
+    abort ();
+
+  d = me3 (&dv);
+  if (d != CONST0)
+    abort ();
+
+#ifdef PR89424
+  d = ei (dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = ei (dv, 3);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 0);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 1);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 2);
+  if (d != CONST0)
+    abort ();
+
+  d = mei (&dv, 3);
+  if (d != CONST0)
+    abort ();
+#endif
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-9a.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-9a.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-9a.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/dfp
+   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.  */
+signed char c0 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 0);
+}
+
+signed char c9 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 9);
+}
+
+signed char c21 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 21);
+}
+
+signed char c30 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+signed char mc0 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 0);
+}
+
+signed char mc9 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 9);
+}
+
+signed char mc21 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 21);
+}
+
+signed char mc30 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+signed char ci (vector signed char v, int i)
+{
+  return __builtin_vec_ext_v16qi (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+signed char mci(vector signed char *vp, int i) {
+  return __builtin_vec_ext_v16qi (*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;
+
+  c = c0 (cv);
+  if (c != CONST0)
+    abort ();
+
+  c = c9 (cv);
+  if (c != CONST9)
+    abort ();
+
+  c = c21 (cv);
+  if (c != CONST5)
+    abort ();
+
+  c = c30 (cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = mc0 (&cv);
+  if (c != CONST0)
+    abort ();
+
+  c = mc9 (&cv);
+  if (c != CONST9)
+    abort ();
+
+  c = mc21 (&cv);
+  if (c != CONST5)
+    abort ();
+
+  c = mc30 (&cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = ci (cv, 8);
+  if (c != CONST8)
+    abort ();
+
+  c = ci (cv, 13);
+  if (c != CONSTD)
+    abort ();
+
+  c = ci (cv, 23);
+  if (c != CONST7)
+    abort ();
+
+  c = ci (cv, 31);
+  if (c != CONSTF)
+    abort ();
+
+  c = mci (&cv, 5);
+  if (c != CONST5)
+    abort ();
+
+  c = mci (&cv, 12);
+  if (c != CONSTC)
+    abort ();
+
+  c = mci (&cv, 25);
+  if (c != CONST9)
+    abort ();
+
+  c = mci (&cv, 16);
+  if (c != CONST0)
+    abort ();
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vsx-builtin-9b.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsx-builtin-9b.c	(nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/vsx-builtin-9b.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/dfp
+   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.  */
+signed char c0 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 0);
+}
+
+signed char c9 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 9);
+}
+
+signed char c21 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 21);
+}
+
+signed char c30 (vector signed char v)
+{
+  return __builtin_vec_ext_v16qi (v, 30);
+}
+
+/* Test for vector residing in memory.  */
+signed char mc0 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 0);
+}
+
+signed char mc9 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 9);
+}
+
+signed char mc21 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 21);
+}
+
+signed char mc30 (vector signed char *vp)
+{
+  return __builtin_vec_ext_v16qi (*vp, 30);
+}
+
+/* Test the same with variable indices.  */
+
+/* Test for variable selector and vector residing in register.  */
+__attribute__((noinline))
+signed char ci (vector signed char v, int i)
+{
+  return __builtin_vec_ext_v16qi (v, i);
+}
+
+/* Test for variable selector and vector residing in memory.  */
+__attribute__((noinline))
+signed char mci(vector signed char *vp, int i) {
+  return __builtin_vec_ext_v16qi (*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;
+
+  c = c0 (cv);
+  if (c != CONST0)
+    abort ();
+
+  c = c9 (cv);
+  if (c != CONST9)
+    abort ();
+
+  c = c21 (cv);
+  if (c != CONST5)
+    abort ();
+
+  c = c30 (cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = mc0 (&cv);
+  if (c != CONST0)
+    abort ();
+
+  c = mc9 (&cv);
+  if (c != CONST9)
+    abort ();
+
+  c = mc21 (&cv);
+  if (c != CONST5)
+    abort ();
+
+  c = mc30 (&cv);
+  if (c != CONSTE)
+    abort ();
+
+  c = ci (cv, 8);
+  if (c != CONST8)
+    abort ();
+
+  c = ci (cv, 13);
+  if (c != CONSTD)
+    abort ();
+
+  c = ci (cv, 23);
+  if (c != CONST7)
+    abort ();
+
+  c = ci (cv, 31);
+  if (c != CONSTF)
+    abort ();
+
+  c = mci (&cv, 5);
+  if (c != CONST5)
+    abort ();
+
+  c = mci (&cv, 12);
+  if (c != CONSTC)
+    abort ();
+
+  c = mci (&cv, 25);
+  if (c != CONST9)
+    abort ();
+
+  c = mci (&cv, 16);
+  if (c != CONST0)
+    abort ();
+
+  return 0;
+}