+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
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:
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:
}
}
- 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
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));
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);
{
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));
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;
}
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));
+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
/* { 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} } } */
/* { 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 } } } */
/* { 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.
/* { 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 } } } */
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+#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;
+}
--- /dev/null
+/* { 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"
--- /dev/null
+/* { 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"
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}