===================================================================
@@ -6565,12 +6565,14 @@ altivec_resolve_overloaded_builtin (location_t loc
arg2 = fold_for_warn (arg2);
- /* If the second argument is an integer constant, if the value is in
- the expected range, generate the built-in code if we can. We need
- 64-bit and direct move to extract the small integer vectors. */
- if (TREE_CODE (arg2) == INTEGER_CST
- && wi::ltu_p (wi::to_wide (arg2), nunits))
+ /* If the second argument is an integer constant, generate
+ the built-in code if we can. We need 64-bit and direct
+ move to extract the small integer vectors. */
+ if (TREE_CODE (arg2) == INTEGER_CST)
{
+ wide_int selector = wi::to_wide (arg2);
+ selector = wi::umod_trunc (selector, nunits);
+ arg2 = wide_int_to_tree (TREE_TYPE (arg2), selector);
switch (mode)
{
default:
===================================================================
@@ -6894,7 +6894,6 @@ rs6000_expand_vector_extract (rtx target, rtx vec,
default:
break;
case E_V1TImode:
- gcc_assert (INTVAL (elt) == 0 && inner_mode == TImode);
emit_move_insn (target, gen_lowpart (TImode, vec));
break;
case E_V2DFmode:
@@ -6974,18 +6973,32 @@ rs6000_expand_vector_extract (rtx target, rtx vec,
}
}
- gcc_assert (CONST_INT_P (elt));
-
/* Allocate mode-sized buffer. */
mem = assign_stack_temp (mode, GET_MODE_SIZE (mode));
emit_move_insn (mem, vec);
+ if (CONST_INT_P (elt))
+ {
+ int modulo_elt = INTVAL (elt) % GET_MODE_NUNITS (mode);
- /* Add offset to field within buffer matching vector element. */
- mem = adjust_address_nv (mem, inner_mode,
- INTVAL (elt) * GET_MODE_SIZE (inner_mode));
+ /* Add offset to field within buffer matching vector element. */
+ mem = adjust_address_nv (mem, inner_mode,
+ modulo_elt * GET_MODE_SIZE (inner_mode));
+ emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
+ }
+ else
+ {
+ unsigned int ele_size = GET_MODE_SIZE (inner_mode);
+ rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
+ rtx new_addr = gen_reg_rtx (Pmode);
- emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
+ elt = gen_rtx_AND (Pmode, elt, num_ele_m1);
+ if (ele_size > 1)
+ elt = gen_rtx_MULT (Pmode, elt, GEN_INT (ele_size));
+ new_addr = gen_rtx_PLUS (Pmode, XEXP (mem, 0), elt);
+ new_addr = change_address (mem, inner_mode, new_addr);
+ emit_move_insn (target, new_addr);
+ }
}
/* Adjust a memory address (MEM) of a vector type to point to a scalar field
@@ -7165,6 +7178,10 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, r
systems. */
if (MEM_P (src))
{
+ int num_elements = GET_MODE_NUNITS (mode);
+ rtx num_ele_m1 = GEN_INT (num_elements - 1);
+
+ emit_insn (gen_anddi3 (element, element, num_ele_m1));
gcc_assert (REG_P (tmp_gpr));
emit_move_insn (dest, rs6000_adjust_vec_address (dest, src, element,
tmp_gpr, scalar_mode));
@@ -7173,7 +7190,9 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, r
else if (REG_P (src) || SUBREG_P (src))
{
- int bit_shift = byte_shift + 3;
+ int num_elements = GET_MODE_NUNITS (mode);
+ int bits_in_element = mode_to_bits (GET_MODE_INNER (mode));
+ int bit_shift = 7 - exact_log2 (num_elements);
rtx element2;
unsigned int dest_regno = reg_or_subregno (dest);
unsigned int src_regno = reg_or_subregno (src);
@@ -7249,7 +7268,7 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, r
{
if (!BYTES_BIG_ENDIAN)
{
- rtx num_ele_m1 = GEN_INT (GET_MODE_NUNITS (mode) - 1);
+ rtx num_ele_m1 = GEN_INT (num_elements - 1);
emit_insn (gen_anddi3 (tmp_gpr, element, num_ele_m1));
emit_insn (gen_subdi3 (tmp_gpr, num_ele_m1, tmp_gpr));
@@ -7307,8 +7326,8 @@ rs6000_split_vec_extract_var (rtx dest, rtx src, r
emit_insn (gen_vsx_vslo_v2di (tmp_altivec_di, src_v2di,
tmp_altivec));
emit_move_insn (tmp_gpr_di, tmp_altivec_di);
- emit_insn (gen_ashrdi3 (tmp_gpr_di, tmp_gpr_di,
- GEN_INT (64 - (8 * scalar_size))));
+ emit_insn (gen_lshrdi3 (tmp_gpr_di, tmp_gpr_di,
+ GEN_INT (64 - bits_in_element)));
return;
}
@@ -14723,9 +14742,17 @@ altivec_expand_vec_ext_builtin (tree exp, rtx targ
op0 = expand_normal (arg0);
op1 = expand_normal (arg1);
- /* Call get_element_number to validate arg1 if it is a constant. */
if (TREE_CODE (arg1) == INTEGER_CST)
- (void) get_element_number (TREE_TYPE (arg0), arg1);
+ {
+ unsigned HOST_WIDE_INT elt;
+ unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+ unsigned int truncated_selector;
+ if (!tree_fits_uhwi_p (arg1))
+ error ("selector expression is out of range");
+ elt = tree_to_uhwi (arg1);
+ truncated_selector = elt % size;
+ op1 = GEN_INT (truncated_selector);
+ }
tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
mode0 = TYPE_MODE (TREE_TYPE (arg0));
===================================================================
@@ -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} } } */
===================================================================
@@ -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 } } } */
===================================================================
@@ -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 } } } */
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -0,0 +1,253 @@
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#ifndef RTYPE
+#define RTYPE TYPE
+#endif
+
+#ifdef DO_TRACE
+#include <stdio.h>
+
+#define TRACE(STRING, NUM) \
+do \
+ { \
+ fprintf (stderr, "%s: %2d\n", STRING, (int) NUM); \
+ fflush (stderr); \
+ } \
+while (0)
+
+#ifndef FAIL_FORMAT
+#define FAIL_FORMAT "%ld"
+#define FAIL_CAST(X) ((long)(X))
+#endif
+
+#define FAIL(EXP, GOT) \
+do \
+ { \
+ fprintf (stderr, "Expected: " FAIL_FORMAT ", got " FAIL_FORMAT "\n", \
+ FAIL_CAST (EXP), FAIL_CAST (GOT)); \
+ fflush (stderr); \
+ abort (); \
+ } \
+while (0)
+
+#else
+#define TRACE(STRING, NUM)
+#define FAIL(EXP, GOT) abort ()
+#endif
+
+static void
+check (RTYPE, RTYPE) __attribute__((__noinline__));
+
+static vector TYPE
+deoptimize (vector TYPE) __attribute__((__noinline__));
+
+static vector TYPE
+*deoptimize_ptr (vector TYPE *) __attribute__((__noinline__));
+
+static void
+check (RTYPE expected, RTYPE got)
+{
+ if (expected != got)
+ FAIL (expected, got);
+}
+
+static vector TYPE
+deoptimize (vector TYPE a)
+{
+ __asm__ (" # %x0" : "+v" (a));
+ return a;
+}
+
+static vector TYPE *
+deoptimize_ptr (vector TYPE *p)
+{
+ __asm__ (" # %0" : "+r" (p));
+ return p;
+}
+
+
+RTYPE
+get_auto_0 (vector TYPE a)
+{
+ TRACE ("get_auto_", 0);
+ return (RTYPE) vec_extract (a, 0);
+}
+
+RTYPE
+get_auto_1 (vector TYPE a)
+{
+ TRACE ("get_auto_", 1);
+ return (RTYPE) vec_extract (a, 1);
+}
+
+#if ELEMENTS >= 4
+RTYPE
+get_auto_2 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 2);
+}
+
+RTYPE
+get_auto_3 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 3);
+}
+
+#if ELEMENTS >= 8
+RTYPE
+get_auto_4 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 4);
+}
+
+RTYPE
+get_auto_5 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 5);
+}
+
+RTYPE
+get_auto_6 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 6);
+}
+
+RTYPE
+get_auto_7 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 7);
+}
+
+#if ELEMENTS >= 16
+RTYPE
+get_auto_8 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 8);
+}
+
+RTYPE
+get_auto_9 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 9);
+}
+
+RTYPE
+get_auto_10 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 10);
+}
+
+RTYPE
+get_auto_11 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 11);
+}
+
+RTYPE
+get_auto_12 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 12);
+}
+
+RTYPE
+get_auto_13 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 13);
+}
+
+RTYPE
+get_auto_14 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 14);
+}
+
+RTYPE
+get_auto_15 (vector TYPE a)
+{
+ return (RTYPE) vec_extract (a, 15);
+}
+
+#endif
+#endif
+#endif
+
+
+/* Tests for the normal case of vec_extract where the vector is in a register
+ and returning the result in a register as a return value. */
+#ifdef DISABLE_INLINE_OF_GET_AUTO_N
+__attribute__ ((__noinline__))
+#else
+/* gcc issues warning: always_inline function might not be inlinable
+
+ __attribute__ ((__always_inline__))
+*/
+#endif
+RTYPE
+get_auto_n (vector TYPE a, ssize_t n)
+{
+ return (RTYPE) vec_extract (a, n);
+}
+
+typedef RTYPE (*auto_func_type) (vector TYPE);
+
+static auto_func_type get_auto_const[] = {
+ get_auto_0,
+ get_auto_1,
+#if ELEMENTS >= 4
+ get_auto_2,
+ get_auto_3,
+#if ELEMENTS >= 8
+ get_auto_4,
+ get_auto_5,
+ get_auto_6,
+ get_auto_7,
+#if ELEMENTS >= 16
+ get_auto_8,
+ get_auto_9,
+ get_auto_10,
+ get_auto_11,
+ get_auto_12,
+ get_auto_13,
+ get_auto_14,
+ get_auto_15,
+#endif
+#endif
+#endif
+};
+
+extern void do_auto (vector TYPE a) __attribute__((__noinline__));
+
+void
+do_auto (vector TYPE a)
+{
+ size_t i;
+
+ for (i = 1; i < 40; i += 3)
+ {
+ TRACE ("do_auto, i: ", i);
+ TRACE (" get_auto_const[i] returns: ",
+ (*get_auto_const [i % ELEMENTS]) (a));
+ TRACE (" get_auto_n returns", get_auto_n (a, i));
+ check (get_auto_n (a, i), (*get_auto_const [i % ELEMENTS]) (a));
+ }
+}
+
+
+
+/* Main program to test all of the possibilities. */
+int
+main (void)
+{
+ size_t i;
+ vector TYPE x = INITIAL;
+ vector TYPE *p, *p2, a, y;
+ vector TYPE z[2];
+
+ a = deoptimize (x);
+
+ do_auto (a);
+
+ return 0;
+}
===================================================================
@@ -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"
===================================================================
@@ -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"
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}
===================================================================
@@ -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;
+}