diff mbox

, Patch #7, Add PowerPC vector initialization tests

Message ID 20160826192950.GA5763@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner Aug. 26, 2016, 7:29 p.m. UTC
These patches add more tests to the PowerPC vector initialization tests.  Four
of the tests added (#4, #5, #8, and #9) just try to do a bunch of vector
initializations for the different vector type (char, short, float, and double).

These other patches (#6, #7) test the code generated in paches #5 and #6.

I have run tese tests on a big endian power7 system (with both 32-bt and 64-bit
tests runs), a big endian power8 system (just 64-bit tests), and a little
endian power8 system.  There were no regressions.  As these tests ok to
install?

2016-08-25  Michael Meissner  <meissner@linux.vnet.ibm.com>

	* gcc.target/powerpc/vec-init-4.c: New runtime tests for various
	vector short/char initializations.
	* gcc.target/powerpc/vec-init-5.c: Likewise.
	* gcc.target/powerpc/vec-init-6.c: New compile time test for
	vector initialization optimizations.
	* gcc.target/powerpc/vec-init-7.c: Likewise.
	* gcc.target/powerpc/vec-init-8.c: New runtime tests for various
	vector float/double initializations.
	* gcc.target/powerpc/vec-init-9.c: Likewise.

Comments

Segher Boessenkool Aug. 27, 2016, 1:24 a.m. UTC | #1
On Fri, Aug 26, 2016 at 03:29:50PM -0400, Michael Meissner wrote:
> These patches add more tests to the PowerPC vector initialization tests.  Four
> of the tests added (#4, #5, #8, and #9) just try to do a bunch of vector
> initializations for the different vector type (char, short, float, and double).
> 
> These other patches (#6, #7) test the code generated in paches #5 and #6.
> 
> I have run tese tests on a big endian power7 system (with both 32-bt and 64-bit
> tests runs), a big endian power8 system (just 64-bit tests), and a little
> endian power8 system.  There were no regressions.  As these tests ok to
> install?

This is okay for trunk; one comment:

> +/* { dg-final { scan-assembler     "mtvsrd" } } */

This also matches mtvsrdd; if you don't want that, you can avoid it by
writing it as {\mmtvsrd\M} (the {} instead of "" to avoid toothpickeritus).

Thanks,


Segher
Michael Meissner Aug. 29, 2016, 7:35 p.m. UTC | #2
On Fri, Aug 26, 2016 at 08:24:40PM -0500, Segher Boessenkool wrote:
> On Fri, Aug 26, 2016 at 03:29:50PM -0400, Michael Meissner wrote:
> > These patches add more tests to the PowerPC vector initialization tests.  Four
> > of the tests added (#4, #5, #8, and #9) just try to do a bunch of vector
> > initializations for the different vector type (char, short, float, and double).
> > 
> > These other patches (#6, #7) test the code generated in paches #5 and #6.
> > 
> > I have run tese tests on a big endian power7 system (with both 32-bt and 64-bit
> > tests runs), a big endian power8 system (just 64-bit tests), and a little
> > endian power8 system.  There were no regressions.  As these tests ok to
> > install?
> 
> This is okay for trunk; one comment:
> 
> > +/* { dg-final { scan-assembler     "mtvsrd" } } */
> 
> This also matches mtvsrdd; if you don't want that, you can avoid it by
> writing it as {\mmtvsrd\M} (the {} instead of "" to avoid toothpickeritus).

In this case, mtvsrd and mtvsrdd are both fine.  However, given the test has an
explicit -mcpu=power8, it should never see mtvsrdd.
diff mbox

Patch

Index: gcc/testsuite/gcc.target/powerpc/vec-init-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-init-4.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-init-4.c	(working copy)
@@ -0,0 +1,212 @@ 
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2 -mvsx" } */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#define ELEMENTS -1, 2, 0, -32768, 32767, 53, 1, 16000
+#define SPLAT 0x0123
+
+vector short sv = (vector short) { ELEMENTS };
+vector short splat = (vector short) { SPLAT, SPLAT, SPLAT, SPLAT,
+				      SPLAT, SPLAT, SPLAT, SPLAT };
+vector short sv_global, sp_global;
+static vector short sv_static, sp_static;
+static short expected[] = { ELEMENTS };
+static short splat_expected = SPLAT;
+
+extern void check (vector short a)
+  __attribute__((__noinline__));
+
+extern void check_splat (vector short a)
+  __attribute__((__noinline__));
+
+extern vector short pack_reg (short a, short b, short c, short d,
+			      short e, short f, short g, short h)
+  __attribute__((__noinline__));
+
+extern vector short pack_from_ptr (short *p_a, short *p_b,
+				   short *p_c, short *p_d,
+				   short *p_e, short *p_f,
+				   short *p_g, short *p_h)
+  __attribute__((__noinline__));
+
+extern vector short pack_const (void)
+  __attribute__((__noinline__));
+
+extern void pack_ptr (vector short *p,
+		      short a, short b, short c, short d,
+		      short e, short f, short g, short h)
+  __attribute__((__noinline__));
+
+extern void pack_static (short a, short b, short c, short d,
+			 short e, short f, short g, short h)
+  __attribute__((__noinline__));
+
+extern void pack_global (short a, short b, short c, short d,
+			 short e, short f, short g, short h)
+  __attribute__((__noinline__));
+
+extern vector short splat_reg (short a)
+  __attribute__((__noinline__));
+
+extern vector short splat_from_ptr (short *p_a)
+  __attribute__((__noinline__));
+
+extern vector short splat_const (void)
+  __attribute__((__noinline__));
+
+extern void splat_ptr (vector short *p, short a)
+  __attribute__((__noinline__));
+
+extern void splat_static (short a)
+  __attribute__((__noinline__));
+
+extern void splat_global (short a)
+  __attribute__((__noinline__));
+
+void
+check (vector short a)
+{
+  size_t i;
+
+  for (i = 0; i < 8; i++)
+    if (vec_extract (a, i) != expected[i])
+      abort ();
+}
+
+void
+check_splat (vector short a)
+{
+  size_t i;
+
+  for (i = 0; i < 8; i++)
+    if (vec_extract (a, i) != SPLAT)
+      abort ();
+}
+
+vector short
+pack_reg (short a, short b, short c, short d,
+	  short e, short f, short g, short h)
+{
+  return (vector short) { a, b, c, d, e, f, g, h };
+}
+
+vector short
+pack_from_ptr (short *p_a, short *p_b, short *p_c, short *p_d,
+	       short *p_e, short *p_f, short *p_g, short *p_h)
+{
+  return (vector short) { *p_a, *p_b, *p_c, *p_d,
+			  *p_e, *p_f, *p_g, *p_h };
+}
+
+vector short
+pack_const (void)
+{
+  return (vector short) { ELEMENTS };
+}
+
+void
+pack_ptr (vector short *p,
+	  short a, short b, short c, short d,
+	  short e, short f, short g, short h)
+{
+  *p = (vector short) { a, b, c, d, e, f, g, h };
+}
+
+void
+pack_static (short a, short b, short c, short d,
+	     short e, short f, short g, short h)
+{
+  sv_static = (vector short) { a, b, c, d, e, f, g, h };
+}
+
+void
+pack_global (short a, short b, short c, short d,
+	     short e, short f, short g, short h)
+{
+  sv_global = (vector short) { a, b, c, d, e, f, g, h };
+}
+
+vector short
+splat_reg (short a)
+{
+  return (vector short) { a, a, a, a, a, a, a, a };
+}
+
+vector short
+splat_from_ptr (short *p_a)
+{
+  return (vector short) { *p_a, *p_a, *p_a, *p_a,
+			  *p_a, *p_a, *p_a, *p_a };
+}
+
+vector short
+splat_const (void)
+{
+  return (vector short) { SPLAT, SPLAT, SPLAT, SPLAT,
+			  SPLAT, SPLAT, SPLAT, SPLAT };
+}
+
+void
+splat_ptr (vector short *p, short a)
+{
+  *p = (vector short) { a, a, a, a, a, a, a, a };
+}
+
+void
+splat_static (short a)
+{
+  sp_static = (vector short) { a, a, a, a, a, a, a, a };
+}
+
+void
+splat_global (short a)
+{
+  sp_global = (vector short) { a, a, a, a, a, a, a, a };
+}
+
+int main (void)
+{
+  vector short sv2, sv3;
+
+  check (sv);
+
+  check (pack_reg (ELEMENTS));
+
+  check (pack_from_ptr (&expected[0], &expected[1], &expected[2],
+			&expected[3], &expected[4], &expected[5],
+			&expected[6], &expected[7]));
+
+  check (pack_const ());
+
+  pack_ptr (&sv2, ELEMENTS);
+  check (sv2);
+
+  pack_static (ELEMENTS);
+  check (sv_static);
+
+  pack_global (ELEMENTS);
+  check (sv_global);
+
+  check_splat (splat);
+
+  check_splat (splat_reg (SPLAT));
+
+  check_splat (splat_from_ptr (&splat_expected));
+
+  check_splat (splat_const ());
+
+  splat_ptr (&sv2, SPLAT);
+  check_splat (sv2);
+
+  splat_static (SPLAT);
+  check_splat (sp_static);
+
+  splat_global (SPLAT);
+  check_splat (sp_global);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vec-init-5.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-init-5.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-init-5.c	(working copy)
@@ -0,0 +1,258 @@ 
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2 -mvsx" } */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#define ELEMENTS 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 127, -1, -128
+#define SPLAT 0x12
+
+vector signed char sv = (vector signed char) { ELEMENTS };
+vector signed char splat = (vector signed char) { SPLAT, SPLAT, SPLAT, SPLAT,
+						  SPLAT, SPLAT, SPLAT, SPLAT,
+						  SPLAT, SPLAT, SPLAT, SPLAT,
+						  SPLAT, SPLAT, SPLAT, SPLAT };
+vector signed char sv_global, sp_global;
+static vector signed char sv_static, sp_static;
+static signed char expected[] = { ELEMENTS };
+static signed char splat_expected = SPLAT;
+
+extern void check (vector signed char a)
+  __attribute__((__noinline__));
+
+extern void check_splat (vector signed char a)
+  __attribute__((__noinline__));
+
+extern vector signed char pack_reg (signed char a, signed char b,
+				    signed char c, signed char d,
+				    signed char e, signed char f,
+				    signed char g, signed char h,
+				    signed char i, signed char j,
+				    signed char k, signed char l,
+				    signed char m, signed char n,
+				    signed char o, signed char p)
+  __attribute__((__noinline__));
+
+extern vector signed char pack_from_ptr (signed char *p_a, signed char *p_b,
+					 signed char *p_c, signed char *p_d,
+					 signed char *p_e, signed char *p_f,
+					 signed char *p_g, signed char *p_h,
+					 signed char *p_i, signed char *p_j,
+					 signed char *p_k, signed char *p_l,
+					 signed char *p_m, signed char *p_n,
+					 signed char *p_o, signed char *p_p)
+  __attribute__((__noinline__));
+
+extern vector signed char pack_const (void)
+  __attribute__((__noinline__));
+
+extern void pack_ptr (vector signed char *q,
+		      signed char a, signed char b, signed char c, signed char d,
+		      signed char e, signed char f, signed char g, signed char h,
+		      signed char i, signed char j, signed char k, signed char l,
+		      signed char m, signed char n, signed char o, signed char p)
+  __attribute__((__noinline__));
+
+extern void pack_static (signed char a, signed char b, signed char c, signed char d,
+			 signed char e, signed char f, signed char g, signed char h,
+			 signed char i, signed char j, signed char k, signed char l,
+			 signed char m, signed char n, signed char o, signed char p)
+  __attribute__((__noinline__));
+
+extern void pack_global (signed char a, signed char b, signed char c, signed char d,
+			 signed char e, signed char f, signed char g, signed char h,
+			 signed char i, signed char j, signed char k, signed char l,
+			 signed char m, signed char n, signed char o, signed char p)
+  __attribute__((__noinline__));
+
+extern vector signed char splat_reg (signed char a)
+  __attribute__((__noinline__));
+
+extern vector signed char splat_from_ptr (signed char *p_a)
+  __attribute__((__noinline__));
+
+extern vector signed char splat_const (void)
+  __attribute__((__noinline__));
+
+extern void splat_ptr (vector signed char *p, signed char a)
+  __attribute__((__noinline__));
+
+extern void splat_static (signed char a)
+  __attribute__((__noinline__));
+
+extern void splat_global (signed char a)
+  __attribute__((__noinline__));
+
+void
+check (vector signed char a)
+{
+  size_t i;
+
+  for (i = 0; i < 16; i++)
+    if (vec_extract (a, i) != expected[i])
+      abort ();
+}
+
+void
+check_splat (vector signed char a)
+{
+  size_t i;
+
+  for (i = 0; i < 16; i++)
+    if (vec_extract (a, i) != SPLAT)
+      abort ();
+}
+
+vector signed char
+pack_reg (signed char a, signed char b, signed char c, signed char d,
+	  signed char e, signed char f, signed char g, signed char h,
+	  signed char i, signed char j, signed char k, signed char l,
+	  signed char m, signed char n, signed char o, signed char p)
+{
+  return (vector signed char) { a, b, c, d, e, f, g, h,
+				i, j, k, l, m, n, o, p };
+}
+
+vector signed char
+pack_from_ptr (signed char *p_a, signed char *p_b, signed char *p_c, signed char *p_d,
+	       signed char *p_e, signed char *p_f, signed char *p_g, signed char *p_h,
+	       signed char *p_i, signed char *p_j, signed char *p_k, signed char *p_l,
+	       signed char *p_m, signed char *p_n, signed char *p_o, signed char *p_p)
+{
+  return (vector signed char) { *p_a, *p_b, *p_c, *p_d,
+				*p_e, *p_f, *p_g, *p_h,
+				*p_i, *p_j, *p_k, *p_l,
+				*p_m, *p_n, *p_o, *p_p };
+
+}
+
+vector signed char
+pack_const (void)
+{
+  return (vector signed char) { ELEMENTS };
+}
+
+void
+pack_ptr (vector signed char *q,
+	  signed char a, signed char b, signed char c, signed char d,
+	  signed char e, signed char f, signed char g, signed char h,
+	  signed char i, signed char j, signed char k, signed char l,
+	  signed char m, signed char n, signed char o, signed char p)
+{
+  *q = (vector signed char) { a, b, c, d, e, f, g, h,
+			      i, j, k, l, m, n, o, p };
+}
+
+void
+pack_static (signed char a, signed char b, signed char c, signed char d,
+	     signed char e, signed char f, signed char g, signed char h,
+	     signed char i, signed char j, signed char k, signed char l,
+	     signed char m, signed char n, signed char o, signed char p)
+{
+  sv_static = (vector signed char) { a, b, c, d, e, f, g, h,
+				     i, j, k, l, m, n, o, p };
+}
+
+void
+pack_global (signed char a, signed char b, signed char c, signed char d,
+	     signed char e, signed char f, signed char g, signed char h,
+	     signed char i, signed char j, signed char k, signed char l,
+	     signed char m, signed char n, signed char o, signed char p)
+{
+  sv_global = (vector signed char) { a, b, c, d, e, f, g, h,
+				     i, j, k, l, m, n, o, p };
+}
+
+vector signed char
+splat_reg (signed char a)
+{
+  return (vector signed char) { a, a, a, a, a, a, a, a,
+				a, a, a, a, a, a, a, a };
+}
+
+vector signed char
+splat_from_ptr (signed char *p_a)
+{
+  return (vector signed char) { *p_a, *p_a, *p_a, *p_a,
+				*p_a, *p_a, *p_a, *p_a,
+				*p_a, *p_a, *p_a, *p_a,
+				*p_a, *p_a, *p_a, *p_a };
+}
+
+vector signed char
+splat_const (void)
+{
+  return (vector signed char) { SPLAT, SPLAT, SPLAT, SPLAT,
+				SPLAT, SPLAT, SPLAT, SPLAT,
+				SPLAT, SPLAT, SPLAT, SPLAT,
+				SPLAT, SPLAT, SPLAT, SPLAT };
+}
+
+void
+splat_ptr (vector signed char *p, signed char a)
+{
+  *p = (vector signed char) { a, a, a, a, a, a, a, a,
+			      a, a, a, a, a, a, a, a };
+}
+
+void
+splat_static (signed char a)
+{
+  sp_static = (vector signed char) { a, a, a, a, a, a, a, a,
+				     a, a, a, a, a, a, a, a };
+}
+
+void
+splat_global (signed char a)
+{
+  sp_global = (vector signed char) { a, a, a, a, a, a, a, a,
+				     a, a, a, a, a, a, a, a };
+}
+
+int main (void)
+{
+  vector signed char sv2, sv3;
+
+  check (sv);
+
+  check (pack_reg (ELEMENTS));
+
+  check (pack_from_ptr (&expected[0],  &expected[1],  &expected[2],
+			&expected[3],  &expected[4],  &expected[5],
+			&expected[6],  &expected[7],  &expected[8],
+			&expected[9],  &expected[10], &expected[11],
+			&expected[12], &expected[13], &expected[14],
+			&expected[15]));
+
+  check (pack_const ());
+
+  pack_ptr (&sv2, ELEMENTS);
+  check (sv2);
+
+  pack_static (ELEMENTS);
+  check (sv_static);
+
+  pack_global (ELEMENTS);
+  check (sv_global);
+
+  check_splat (splat);
+
+  check_splat (splat_reg (SPLAT));
+
+  check_splat (splat_from_ptr (&splat_expected));
+
+  check_splat (splat_const ());
+
+  splat_ptr (&sv2, SPLAT);
+  check_splat (sv2);
+
+  splat_static (SPLAT);
+  check_splat (sp_static);
+
+  splat_global (SPLAT);
+  check_splat (sp_global);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vec-init-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-init-6.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-init-6.c	(working copy)
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -mupper-regs-di" } */
+
+vector int
+merge (int a, int b, int c, int d)
+{
+  return (vector int) { a, b, c, d };
+}
+
+/* { dg-final { scan-assembler     "rldicr" } } */
+/* { dg-final { scan-assembler     "rldicl" } } */
+/* { dg-final { scan-assembler     "mtvsrd" } } */
+/* { dg-final { scan-assembler-not "stw"    } } */
+/* { dg-final { scan-assembler-not "lxvw4x" } } */
Index: gcc/testsuite/gcc.target/powerpc/vec-init-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-init-7.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-init-7.c	(working copy)
@@ -0,0 +1,13 @@ 
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2 -mupper-regs-di" } */
+
+vector int
+splat (int a)
+{
+  return (vector int) { a, a, a, a };
+}
+
+/* { dg-final { scan-assembler "mtvsrwz" } } */
+/* { dg-final { scan-assembler "xxspltw" } } */
Index: gcc/testsuite/gcc.target/powerpc/vec-init-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-init-8.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-init-8.c	(working copy)
@@ -0,0 +1,194 @@ 
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2 -mvsx" } */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#define ELEMENTS -1.0f, 2.0f, 0.0f, -1234.0f
+#define SPLAT 2345.0f
+
+vector float sv = (vector float) { ELEMENTS };
+vector float splat = (vector float) { SPLAT, SPLAT, SPLAT, SPLAT };
+vector float sv_global, sp_global;
+static vector float sv_static, sp_static;
+static const float expected[] = { ELEMENTS };
+
+extern void check (vector float a)
+  __attribute__((__noinline__));
+
+extern void check_splat (vector float a)
+  __attribute__((__noinline__));
+
+extern vector float pack_reg (float a, float b, float c, float d)
+  __attribute__((__noinline__));
+
+extern vector float pack_from_ptr (float *p_a, float *p_b,
+				   float *p_c, float *p_d)
+  __attribute__((__noinline__));
+
+extern vector float pack_const (void)
+  __attribute__((__noinline__));
+
+extern void pack_ptr (vector float *p, float a, float b, float c, float d)
+  __attribute__((__noinline__));
+
+extern void pack_static (float a, float b, float c, float d)
+  __attribute__((__noinline__));
+
+extern void pack_global (float a, float b, float c, float d)
+  __attribute__((__noinline__));
+
+extern vector float splat_reg (float a)
+  __attribute__((__noinline__));
+
+extern vector float splat_from_ptr (float *p)
+  __attribute__((__noinline__));
+
+extern vector float splat_const (void)
+  __attribute__((__noinline__));
+
+extern void splat_ptr (vector float *p, float a)
+  __attribute__((__noinline__));
+
+extern void splat_static (float a)
+  __attribute__((__noinline__));
+
+extern void splat_global (float a)
+  __attribute__((__noinline__));
+
+void
+check (vector float a)
+{
+  size_t i;
+
+  for (i = 0; i < 4; i++)
+    if (vec_extract (a, i) != expected[i])
+      abort ();
+}
+
+void
+check_splat (vector float a)
+{
+  size_t i;
+
+  for (i = 0; i < 4; i++)
+    if (vec_extract (a, i) != SPLAT)
+      abort ();
+}
+
+vector float
+pack_reg (float a, float b, float c, float d)
+{
+  return (vector float) { a, b, c, d };
+}
+
+vector float
+pack_from_ptr (float *p_a, float *p_b, float *p_c, float *p_d)
+{
+  return (vector float) { *p_a, *p_b, *p_c, *p_d };
+}
+
+vector float
+pack_const (void)
+{
+  return (vector float) { ELEMENTS };
+}
+
+void
+pack_ptr (vector float *p, float a, float b, float c, float d)
+{
+  *p = (vector float) { a, b, c, d };
+}
+
+void
+pack_static (float a, float b, float c, float d)
+{
+  sv_static = (vector float) { a, b, c, d };
+}
+
+void
+pack_global (float a, float b, float c, float d)
+{
+  sv_global = (vector float) { a, b, c, d };
+}
+
+vector float
+splat_reg (float a)
+{
+  return (vector float) { a, a, a, a };
+}
+
+vector float
+splat_from_ptr (float *p)
+{
+  return (vector float) { *p, *p, *p, *p };
+}
+
+vector float
+splat_const (void)
+{
+  return (vector float) { SPLAT, SPLAT, SPLAT, SPLAT };
+}
+
+void
+splat_ptr (vector float *p, float a)
+{
+  *p = (vector float) { a, a, a, a };
+}
+
+void
+splat_static (float a)
+{
+  sp_static = (vector float) { a, a, a, a };
+}
+
+void
+splat_global (float a)
+{
+  sp_global = (vector float) { a, a, a, a };
+}
+
+int main (void)
+{
+  vector float sv2, sv3;
+  float mem = SPLAT;
+  float mem2[4] = { ELEMENTS };
+
+  check (sv);
+
+  check (pack_reg (ELEMENTS));
+
+  check (pack_from_ptr (&mem2[0], &mem2[1], &mem2[2], &mem2[3]));
+
+  check (pack_const ());
+
+  pack_ptr (&sv2, ELEMENTS);
+  check (sv2);
+
+  pack_static (ELEMENTS);
+  check (sv_static);
+
+  pack_global (ELEMENTS);
+  check (sv_global);
+
+  check_splat (splat);
+
+  check_splat (splat_reg (SPLAT));
+
+  check_splat (splat_from_ptr (&mem));
+
+  check_splat (splat_const ());
+
+  splat_ptr (&sv2, SPLAT);
+  check_splat (sv2);
+
+  splat_static (SPLAT);
+  check_splat (sp_static);
+
+  splat_global (SPLAT);
+  check_splat (sp_global);
+
+  return 0;
+}
Index: gcc/testsuite/gcc.target/powerpc/vec-init-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vec-init-9.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vec-init-9.c	(working copy)
@@ -0,0 +1,193 @@ 
+/* { dg-do run { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2 -mvsx" } */
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <altivec.h>
+
+#define ELEMENTS -12345.0, 23456.0
+#define SPLAT 34567.0
+
+vector double sv = (vector double) { ELEMENTS };
+vector double splat = (vector double) { SPLAT, SPLAT };
+vector double sv_global, sp_global;
+static vector double sv_static, sp_static;
+static const int expected[] = { ELEMENTS };
+
+extern void check (vector double a)
+  __attribute__((__noinline__));
+
+extern void check_splat (vector double a)
+  __attribute__((__noinline__));
+
+extern vector double pack_reg (double a, double b)
+  __attribute__((__noinline__));
+
+extern vector double pack_from_ptr (double *p_a, double *p_b)
+  __attribute__((__noinline__));
+
+extern vector double pack_const (void)
+  __attribute__((__noinline__));
+
+extern void pack_ptr (vector double *p, double a, double b)
+  __attribute__((__noinline__));
+
+extern void pack_static (double a, double b)
+  __attribute__((__noinline__));
+
+extern void pack_global (double a, double b)
+  __attribute__((__noinline__));
+
+extern vector double splat_reg (double a)
+  __attribute__((__noinline__));
+
+extern vector double splat_from_ptr (double *p)
+  __attribute__((__noinline__));
+
+extern vector double splat_const (void)
+  __attribute__((__noinline__));
+
+extern void splat_ptr (vector double *p, double a)
+  __attribute__((__noinline__));
+
+extern void splat_static (double a)
+  __attribute__((__noinline__));
+
+extern void splat_global (double a)
+  __attribute__((__noinline__));
+
+void
+check (vector double a)
+{
+  size_t i;
+
+  for (i = 0; i < 2; i++)
+    if (vec_extract (a, i) != expected[i])
+      abort ();
+}
+
+void
+check_splat (vector double a)
+{
+  size_t i;
+
+  for (i = 0; i < 2; i++)
+    if (vec_extract (a, i) != SPLAT)
+      abort ();
+}
+
+vector double
+pack_reg (double a, double b)
+{
+  return (vector double) { a, b };
+}
+
+vector double
+pack_from_ptr (double *p_a, double *p_b)
+{
+  return (vector double) { *p_a, *p_b };
+}
+
+vector double
+pack_const (void)
+{
+  return (vector double) { ELEMENTS };
+}
+
+void
+pack_ptr (vector double *p, double a, double b)
+{
+  *p = (vector double) { a, b };
+}
+
+void
+pack_static (double a, double b)
+{
+  sv_static = (vector double) { a, b };
+}
+
+void
+pack_global (double a, double b)
+{
+  sv_global = (vector double) { a, b };
+}
+
+vector double
+splat_reg (double a)
+{
+  return (vector double) { a, a };
+}
+
+vector double
+splat_from_ptr (double *p)
+{
+  return (vector double) { *p, *p };
+}
+
+vector double
+splat_const (void)
+{
+  return (vector double) { SPLAT, SPLAT };
+}
+
+void
+splat_ptr (vector double *p, double a)
+{
+  *p = (vector double) { a, a };
+}
+
+void
+splat_static (double a)
+{
+  sp_static = (vector double) { a, a };
+}
+
+void
+splat_global (double a)
+{
+  sp_global = (vector double) { a, a };
+}
+
+int  main (void)
+{
+  vector double sv2, sv3;
+  double mem = SPLAT;
+  double mem2[2] = { ELEMENTS };
+
+  check (sv);
+
+  check (pack_reg (ELEMENTS));
+
+  check (pack_from_ptr (&mem2[0], &mem2[1]));
+
+  check (pack_const ());
+
+  pack_ptr (&sv2, ELEMENTS);
+  check (sv2);
+
+  pack_static (ELEMENTS);
+  check (sv_static);
+
+  pack_global (ELEMENTS);
+  check (sv_global);
+
+  check_splat (splat);
+
+  check_splat (splat_reg (SPLAT));
+
+  check_splat (splat_from_ptr (&mem));
+
+  check_splat (splat_const ());
+
+  splat_ptr (&sv2, SPLAT);
+  check_splat (sv2);
+
+  splat_static (SPLAT);
+  check_splat (sp_static);
+
+  splat_global (SPLAT);
+  check_splat (sp_global);
+
+  return 0;
+}