re PR target/87532 (bad results from vec_extract(unsigned char, foo) dependent upon...
authorKelvin Nilsen <kelvin@gcc.gnu.org>
Fri, 15 Mar 2019 19:52:43 +0000 (19:52 +0000)
committerKelvin Nilsen <kelvin@gcc.gnu.org>
Fri, 15 Mar 2019 19:52:43 +0000 (19:52 +0000)
gcc/ChangeLog:

2019-03-15  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
compute index.

gcc/testsuite/ChangeLog:

2019-03-15  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.

From-SVN: r269715

36 files changed:
gcc/ChangeLog
gcc/config/rs6000/rs6000-c.c
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c
gcc/testsuite/gcc.target/powerpc/fold-vec-extract-int.p8.c
gcc/testsuite/gcc.target/powerpc/fold-vec-extract-short.p8.c
gcc/testsuite/gcc.target/powerpc/pr87532-mc.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pr87532.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2.h [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-10a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-10b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-11a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-11b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-12a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-12b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-14a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-14b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-15a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-15b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-16a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-16b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-17a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-17b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-18a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-18b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-19a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-19b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-9a.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-9b.c [new file with mode: 0644]

index dfec5891a93835d79ed65439d20032df8a6c5f55..55d80e563678e75e88bd7971c4eb35c5d92d15ab 100644 (file)
@@ -1,3 +1,18 @@
+2019-03-15  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
+       compute index.
+
 2019-03-15  Alexandre Oliva <aoliva@redhat.com>
 
        PR c++/88534
index ae39eb77ea1d6245bf98942517839ab2a0a708c5..063d4acfafb98aa8dd551834920000d4cc0639e5 100644 (file)
@@ -6565,12 +6565,14 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
 
          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 14d39ba84209e920a522b5841204093b447c3850..734c3860ffe04cf4aefb9004c2d1332d88949bc4 100644 (file)
@@ -6894,7 +6894,6 @@ rs6000_expand_vector_extract (rtx target, rtx vec, rtx elt)
        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, rtx elt)
        }
     }
 
-  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, rtx element, rtx tmp_gpr,
      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, rtx element, rtx tmp_gpr,
 
   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, rtx element, rtx tmp_gpr,
        {
          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, rtx element, rtx tmp_gpr,
            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;
          }
 
@@ -14725,9 +14744,17 @@ altivec_expand_vec_ext_builtin (tree exp, rtx target)
   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;
+      /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
+        returns low-order bits of INTEGER_CST for modulo indexing.  */
+      elt = TREE_INT_CST_LOW (arg1);
+      truncated_selector = elt % size;
+      op1 = GEN_INT (truncated_selector);
+    }
 
   tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
   mode0 = TYPE_MODE (TREE_TYPE (arg0));
index 139e45a68029691cb87bde91b2829ae9c379e5a5..7acb52b1ffdeda7546e3b72c1f44c2ad8e4251ae 100644 (file)
@@ -1,3 +1,40 @@
+2019-03-15  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.
+
 2019-03-15  Alexandre Oliva <aoliva@redhat.com>
 
        PR c++/88534
index 234740c307afe06570160fb0283705c29dff97f6..81a7a0239f1796ecb91579aedd521e1503b6d421 100644 (file)
@@ -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 b23476e37462c2034a47b53ceccb84e43a227104..637cdce318a3c17902108c15646be50fb8434b76 100644 (file)
@@ -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 7ab0fc459a40f10346629f7c676da1d400b05321..e9dd1131691709b6bf8cc6b07f98705af04660c8 100644 (file)
@@ -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 } } } */
 
diff --git a/gcc/testsuite/gcc.target/powerpc/pr87532-mc.c b/gcc/testsuite/gcc.target/powerpc/pr87532-mc.c
new file mode 100644 (file)
index 0000000..400df7f
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr87532.c b/gcc/testsuite/gcc.target/powerpc/pr87532.c
new file mode 100644 (file)
index 0000000..4b07f07
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2.h b/gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2.h
new file mode 100644 (file)
index 0000000..d115759
--- /dev/null
@@ -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;
+}
+
+\f
+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
+
+\f
+/* 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));
+    }
+}
+
+
+\f
+/* 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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2a.c b/gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2a.c
new file mode 100644 (file)
index 0000000..05082b7
--- /dev/null
@@ -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"
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2b.c b/gcc/testsuite/gcc.target/powerpc/vec-extract-v16qiu-v2b.c
new file mode 100644 (file)
index 0000000..87a3aa4
--- /dev/null
@@ -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"
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-10a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-10a.c
new file mode 100644 (file)
index 0000000..e8516de
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-10b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-10b.c
new file mode 100644 (file)
index 0000000..6300b0e
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-11a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-11a.c
new file mode 100644 (file)
index 0000000..e962e12
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-11b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-11b.c
new file mode 100644 (file)
index 0000000..fafdd10
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-12a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-12a.c
new file mode 100644 (file)
index 0000000..a79bc7f
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-12b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-12b.c
new file mode 100644 (file)
index 0000000..2b63624
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-13a.c
new file mode 100644 (file)
index 0000000..907bcce
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-13b.c
new file mode 100644 (file)
index 0000000..e1d791d
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-14a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-14a.c
new file mode 100644 (file)
index 0000000..8eb8eb6
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-14b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-14b.c
new file mode 100644 (file)
index 0000000..84bc8a2
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-15a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-15a.c
new file mode 100644 (file)
index 0000000..b8bff5c
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-15b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-15b.c
new file mode 100644 (file)
index 0000000..402cde7
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-16a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-16a.c
new file mode 100644 (file)
index 0000000..465296a
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-16b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-16b.c
new file mode 100644 (file)
index 0000000..b646fb1
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-17a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-17a.c
new file mode 100644 (file)
index 0000000..afb6934
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-17b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-17b.c
new file mode 100644 (file)
index 0000000..63814ee
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-18a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-18a.c
new file mode 100644 (file)
index 0000000..3681ad9
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-18b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-18b.c
new file mode 100644 (file)
index 0000000..57b5c43
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-19a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-19a.c
new file mode 100644 (file)
index 0000000..dee8319
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-19b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-19b.c
new file mode 100644 (file)
index 0000000..c39923e
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-20a.c
new file mode 100644 (file)
index 0000000..638f5a1
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-20b.c
new file mode 100644 (file)
index 0000000..7b127a0
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-9a.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-9a.c
new file mode 100644 (file)
index 0000000..7b35434
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-9b.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-9b.c
new file mode 100644 (file)
index 0000000..ff081b3
--- /dev/null
@@ -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;
+}