diff --git a/gcc/testsuite/gcc.target/powerpc/p9-dform-0.c b/gcc/testsuite/gcc.target/powerpc/p9-dform-0.c
new file mode 100644
index 0000000..68b0434
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-dform-0.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O3 -mdejagnu-cpu=power9 -funroll-loops" } */
+
+/* This test confirms that the dform instructions are selected in the
+   translation of this main program.  */
+
+extern void first_dummy ();
+extern void dummy (double sacc, int n);
+extern void other_dummy ();
+
+extern float opt_value;
+extern char *opt_desc;
+
+#define M 128
+#define N 512
+
+double x [N];
+double y [N];
+
+int main (int argc, char *argv []) {
+  double sacc;
+
+  first_dummy ();
+  for (int j = 0; j < M; j++) {
+
+    sacc = 0.00;
+    for (unsigned long long int i = 0; i < N; i++) {
+      sacc += x[i] * y[i];
+    }
+    dummy (sacc, N);
+  }
+  opt_value = ((float) N) * 2 * ((float) M);
+  opt_desc = "flops";
+  other_dummy ();
+}
+
+/* At time the dform optimization pass was merged with trunk, 12
+   lxv instructions were emitted in place of the same number of lxvx
+   instructions.  No need to require exactly this number, as it may
+   change when other optimization passes evolve.  */
+
+/* { dg-final { scan-assembler {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-dform-1.c b/gcc/testsuite/gcc.target/powerpc/p9-dform-1.c
new file mode 100644
index 0000000..b80ffbc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-dform-1.c
@@ -0,0 +1,57 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O3 -mdejagnu-cpu=power9 -funroll-loops" } */
+
+/* This test confirms that the dform instructions are selected in the
+   translation of this main program.  */
+
+extern void first_dummy ();
+extern void dummy (double sacc, int n);
+extern void other_dummy ();
+
+extern float opt_value;
+extern char *opt_desc;
+
+#define M 128
+#define N 512
+
+double x [N];
+double y [N];
+double z [N];
+
+int main (int argc, char *argv []) {
+  double sacc;
+
+  first_dummy ();
+  for (int j = 0; j < M; j++) {
+
+    sacc = 0.00;
+    for (unsigned long long int i = 0; i < N; i++) {
+      z[i] = x[i] * y[i];
+      sacc += z[i];
+    }
+    dummy (sacc, N);
+  }
+  opt_value = ((float) N) * 2 * ((float) M);
+  opt_desc = "flops";
+  other_dummy ();
+}
+
+
+
+/* At time the dform optimization pass was merged with trunk, 12
+   lxv instructions were emitted in place of the same number of lxvx
+   instructions.  No need to require exactly this number, as it may
+   change when other optimization passes evolve.  */
+
+/* { dg-final { scan-assembler {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
+
+/* At time the dform optimization pass was merged with trunk, 6
+   stxv instructions were emitted in place of the same number of stxvx
+   instructions.  No need to require exactly this number, as it may
+   change when other optimization passes evolve.  */
+
+/* { dg-final { scan-assembler {\mstxv\M} } } */
+/* { dg-final { scan-assembler-not {\mstxvx\M} } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-dform-2.c b/gcc/testsuite/gcc.target/powerpc/p9-dform-2.c
new file mode 100644
index 0000000..51789d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-dform-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O3 -mdejagnu-cpu=power9 -funroll-loops" } */
+
+#define TYPE int
+#include "p9-dform-generic.h"
+
+/* The precise number of lxv and stxv instructions may be impacted by
+   complex interactions between optimization passes, but we expect at
+   least one of each.  */
+/* { dg-final { scan-assembler {\mlxv\M} } } */
+/* { dg-final { scan-assembler {\mstxv\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
+/* { dg-final { scan-assembler-not {\mstxvx\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-dform-3.c b/gcc/testsuite/gcc.target/powerpc/p9-dform-3.c
new file mode 100644
index 0000000..1a4b6c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-dform-3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O3 -mdejagnu-cpu=power9 -funroll-loops" } */
+
+#define TYPE double
+#include "p9-dform-generic.h"
+
+/* At time the dform optimization pass was merged with trunk, 6
+   lxv instructions were emitted in place of the same number of lxvx
+   instructions and 8 stxv instructions replace the same number of
+   stxvx instructions.  No need to require exactly this number, as it
+   may change when other optimization passes evolve.  */
+
+/* { dg-final { scan-assembler {\mlxv\M} } } */
+/* { dg-final { scan-assembler {\mstxv\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
+/* { dg-final { scan-assembler-not {\mstxvx\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-dform-4.c b/gcc/testsuite/gcc.target/powerpc/p9-dform-4.c
new file mode 100644
index 0000000..752f987
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-dform-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9 -funroll-loops -mfloat128" } */
+
+#define TYPE __float128
+#include "p9-dform-generic.h"
+
+/* The precise number of lxv and stxv instructions may be impacted by
+   complex interactions between optimization passes, but we expect at
+   least one of each.  */
+/* { dg-final { scan-assembler {\mlxv\M} } } */
+/* { dg-final { scan-assembler {\mstxv\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
+/* { dg-final { scan-assembler-not {\mstxvx\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-dform-generic.h b/gcc/testsuite/gcc.target/powerpc/p9-dform-generic.h
new file mode 100644
index 0000000..3caed25
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-dform-generic.h
@@ -0,0 +1,34 @@
+
+#define ITERATIONS 1000000
+
+#define SIZE (16384/sizeof(TYPE))
+
+static TYPE x[SIZE] __attribute__ ((aligned (16)));
+static TYPE y[SIZE] __attribute__ ((aligned (16)));
+static TYPE a;
+
+void obfuscate(void *a, ...);
+
+static void __attribute__((noinline)) do_one(void)
+{
+  unsigned long i;
+
+  obfuscate(x, y, &a);
+
+  for (i = 0; i < SIZE; i++)
+    y[i] = a * x[i];
+
+  obfuscate(x, y, &a);
+
+}
+
+int main(void)
+{
+  unsigned long i;
+
+  for (i = 0; i < ITERATIONS; i++)
+    do_one();
+
+  return 0;
+
+}
