i386.c (ix86_expand_vector_init_one_nonzero): Use ix86_expand_vector_set if supported.
authorH.J. Lu <hongjiu.lu@intel.com>
Tue, 13 May 2008 19:42:30 +0000 (19:42 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Tue, 13 May 2008 19:42:30 +0000 (12:42 -0700)
gcc/

2008-05-13  H.J. Lu  <hongjiu.lu@intel.com>

* config/i386/i386.c (ix86_expand_vector_init_one_nonzero): Use
ix86_expand_vector_set if supported.

gcc/testsuite/

2008-05-13  H.J. Lu  <hongjiu.lu@intel.com>

* gcc.target/i386/sse-init-v4hi-1.c: New.
* gcc.target/i386/sse-init-v4sf-1.c: Likewise.
* gcc.target/i386/sse2-init-v16qi-1.c: Likewise.
* gcc.target/i386/sse2-init-v2di-1.c: Likewise.
* gcc.target/i386/sse2-init-v4si-1.c: Likewise.
* gcc.target/i386/sse2-init-v8hi-1.c: Likewise.
* gcc.target/i386/sse4_1-init-v16qi-1.c: Likewise.
* gcc.target/i386/sse4_1-init-v2di-1.c: Likewise.
* gcc.target/i386/sse4_1-init-v4sf-1.c: Likewise.
* gcc.target/i386/sse4_1-init-v4si-1.c: Likewise.

From-SVN: r135272

13 files changed:
gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v16qi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v2di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v4si-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-init-v8hi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-1.c [new file with mode: 0644]

index cd5f12b6d6eb818462588f7f1dbb1d4ae9c18a17..246bf13fcb0d16eaae560313a908ea21bccf0543 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/i386/i386.c (ix86_expand_vector_init_one_nonzero): Use
+       ix86_expand_vector_set if supported.
+
 2008-05-13  Diego Novillo  <dnovillo@google.com>
            Kenneth Zadeck  <zadeck@naturalbridge.com>
 
index 0ebfb1b7617d37856ea22e80c5b47ed639b04520..6d551e0f5ad52a89b4628c196e851a1c7acb53a3 100644 (file)
@@ -23643,6 +23643,34 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, enum machine_mode mode,
   enum machine_mode vsimode;
   rtx new_target;
   rtx x, tmp;
+  bool use_vector_set = false;
+
+  switch (mode)
+    {
+    case V2DImode:
+      use_vector_set = TARGET_64BIT && TARGET_SSE4_1;
+      break;
+    case V16QImode:
+    case V4SImode:
+    case V4SFmode:
+      use_vector_set = TARGET_SSE4_1;
+      break;
+    case V8HImode:
+      use_vector_set = TARGET_SSE2;
+      break;
+    case V4HImode:
+      use_vector_set = TARGET_SSE || TARGET_3DNOW_A;
+    default:
+      break;
+    }
+
+  if (use_vector_set)
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, target, CONST0_RTX (mode)));
+      var = force_reg (GET_MODE_INNER (mode), var);
+      ix86_expand_vector_set (mmx_ok, target, var, one_var);
+      return true; 
+    }
 
   switch (mode)
     {
index cc85d14985f06c6140a80d5ade3c5669fc6be3ea..d26c9098173b18d13430bba2538c29c837d9411c 100644 (file)
@@ -1,3 +1,16 @@
+2008-05-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * gcc.target/i386/sse-init-v4hi-1.c: New.
+       * gcc.target/i386/sse-init-v4sf-1.c: Likewise.
+       * gcc.target/i386/sse2-init-v16qi-1.c: Likewise.
+       * gcc.target/i386/sse2-init-v2di-1.c: Likewise.
+       * gcc.target/i386/sse2-init-v4si-1.c: Likewise.
+       * gcc.target/i386/sse2-init-v8hi-1.c: Likewise.
+       * gcc.target/i386/sse4_1-init-v16qi-1.c: Likewise.
+       * gcc.target/i386/sse4_1-init-v2di-1.c: Likewise.
+       * gcc.target/i386/sse4_1-init-v4sf-1.c: Likewise.
+       * gcc.target/i386/sse4_1-init-v4si-1.c: Likewise.
+
 2008-05-13  Janis Johnson  <janis187@us.ibm.com>
 
        PR testsuite/35127
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v4hi-1.c
new file mode 100644 (file)
index 0000000..5c25477
--- /dev/null
@@ -0,0 +1,67 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse" } */
+
+#include "sse-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <mmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m64 x, unsigned short *v, int j)
+{
+  union
+    {
+      __m64 x;
+      unsigned short i[8];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%x != 0x%x\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%x != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned short *v)
+{
+  __m64 x;
+
+  x = _mm_set_pi16 (0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_pi16 (0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_pi16 (0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_pi16 (v[3], 0, 0, 0);
+  check (x, v, 3);
+}
+
+static void
+sse_test (void)
+{
+  unsigned short v[4]
+    = { 0x7B5B, 0x5465, 0x7374, 0x5665};
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c b/gcc/testsuite/gcc.target/i386/sse-init-v4sf-1.c
new file mode 100644 (file)
index 0000000..4cb1f33
--- /dev/null
@@ -0,0 +1,66 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse" } */
+
+#include "sse-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <xmmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128 x, float *v, int j)
+{
+  union
+    {
+      __m128 x;
+      float f[4];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.f[i])
+         {
+#ifdef DEBUG
+           printf ("%i: %f != %f\n", i, v[i], u.f[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.f[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: %f != 0\n", i, u.f[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (float *v)
+{
+  __m128 x;
+
+  x = _mm_set_ps (0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_ps (0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_ps (0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_ps (v[3], 0, 0, 0);
+  check (x, v, 3);
+}
+
+static void
+sse_test (void)
+{
+  float v[4] = { -3, 2, 1, 9 };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-1.c b/gcc/testsuite/gcc.target/i386/sse2-init-v16qi-1.c
new file mode 100644 (file)
index 0000000..903a5ad
--- /dev/null
@@ -0,0 +1,76 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+
+#include "sse2-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned char *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned char i[16];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%x != 0x%x\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%x != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned char *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[3], 0, 0, 0);
+  check (x, v, 3);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[4], 0, 0, 0, 0);
+  check (x, v, 4);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[5], 0, 0, 0, 0, 0);
+  check (x, v, 5);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, v[6], 0, 0, 0, 0, 0, 0);
+  check (x, v, 6);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, v[7], 0, 0, 0, 0, 0, 0, 0);
+  check (x, v, 7);
+}
+
+static void
+sse2_test (void)
+{
+  unsigned char v[16]
+    = { 0x7B, 0x5B, 0x54, 0x65, 0x73, 0x74, 0x56, 0x65,
+       0x63, 0x74, 0x6F, 0x72, 0x5D, 0x53, 0x47, 0x5D };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v2di-1.c b/gcc/testsuite/gcc.target/i386/sse2-init-v2di-1.c
new file mode 100644 (file)
index 0000000..7dc80a3
--- /dev/null
@@ -0,0 +1,63 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+
+#include "sse2-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned long long *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned long long i[2];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%llx != 0x%llx\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%llx != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned long long *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi64x (0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi64x (v[1], 0);
+  check (x, v, 1);
+}
+
+static void
+sse2_test (void)
+{
+  unsigned long long v[2]
+    = { 0x7B5B546573745665LL, 0x63746F725D53475DLL };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v4si-1.c b/gcc/testsuite/gcc.target/i386/sse2-init-v4si-1.c
new file mode 100644 (file)
index 0000000..71e27be
--- /dev/null
@@ -0,0 +1,67 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+
+#include "sse2-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned int *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned int i[4];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%x != 0x%x\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%x != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned int *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi32 (0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi32 (0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_epi32 (0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_epi32 (v[3], 0, 0, 0);
+  check (x, v, 3);
+}
+
+static void
+sse2_test (void)
+{
+  unsigned int v[4]
+    = { 0x7B5B5465, 0x73745665, 0x63746F72, 0x5D53475D };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-init-v8hi-1.c b/gcc/testsuite/gcc.target/i386/sse2-init-v8hi-1.c
new file mode 100644 (file)
index 0000000..3874b2e
--- /dev/null
@@ -0,0 +1,76 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse2" } */
+
+#include "sse2-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned short *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned short i[8];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%x != 0x%x\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%x != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned short *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi16 (0, 0, 0, 0, 0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi16 (0, 0, 0, 0, 0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_epi16 (0, 0, 0, 0, 0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_epi16 (0, 0, 0, 0, v[3], 0, 0, 0);
+  check (x, v, 3);
+  x = _mm_set_epi16 (0, 0, 0, v[4], 0, 0, 0, 0);
+  check (x, v, 4);
+  x = _mm_set_epi16 (0, 0, v[5], 0, 0, 0, 0, 0);
+  check (x, v, 5);
+  x = _mm_set_epi16 (0, v[6], 0, 0, 0, 0, 0, 0);
+  check (x, v, 6);
+  x = _mm_set_epi16 (v[7], 0, 0, 0, 0, 0, 0, 0);
+  check (x, v, 7);
+}
+
+static void
+sse2_test (void)
+{
+  unsigned short v[8]
+    = { 0x7B5B, 0x5465, 0x7374, 0x5665,
+       0x6374, 0x6F72, 0x5D53, 0x475D };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v16qi-1.c
new file mode 100644 (file)
index 0000000..6a3ccee
--- /dev/null
@@ -0,0 +1,77 @@
+/* { dg-do run } */
+/* { dg-require-effective-target sse4 } */
+/* { dg-options "-O2 -msse4.1" } */
+
+#include "sse4_1-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned char *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned char i[16];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%x != 0x%x\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%x != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned char *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[3], 0, 0, 0);
+  check (x, v, 3);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[4], 0, 0, 0, 0);
+  check (x, v, 4);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v[5], 0, 0, 0, 0, 0);
+  check (x, v, 5);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, 0, v[6], 0, 0, 0, 0, 0, 0);
+  check (x, v, 6);
+  x = _mm_set_epi8 (0, 0, 0, 0, 0, 0, 0, 0, v[7], 0, 0, 0, 0, 0, 0, 0);
+  check (x, v, 7);
+}
+
+static void
+sse4_1_test (void)
+{
+  unsigned char v[16]
+    = { 0x7B, 0x5B, 0x54, 0x65, 0x73, 0x74, 0x56, 0x65,
+       0x63, 0x74, 0x6F, 0x72, 0x5D, 0x53, 0x47, 0x5D };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v2di-1.c
new file mode 100644 (file)
index 0000000..cd9fa79
--- /dev/null
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+/* { dg-require-effective-target sse4 } */
+/* { dg-options "-O2 -msse4.1" } */
+
+#include "sse4_1-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned long long *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned long long i[2];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%llx != 0x%llx\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%llx != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned long long *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi64x (0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi64x (v[1], 0);
+  check (x, v, 1);
+}
+
+static void
+sse4_1_test (void)
+{
+  unsigned long long v[2]
+    = { 0x7B5B546573745665LL, 0x63746F725D53475DLL };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4sf-1.c
new file mode 100644 (file)
index 0000000..f976042
--- /dev/null
@@ -0,0 +1,67 @@
+/* { dg-do run } */
+/* { dg-require-effective-target sse4 } */
+/* { dg-options "-O2 -msse4.1" } */
+
+#include "sse4_1-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128 x, float *v, int j)
+{
+  union
+    {
+      __m128 x;
+      float f[4];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.f[i])
+         {
+#ifdef DEBUG
+           printf ("%i: %f != %f\n", i, v[i], u.f[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.f[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: %f != 0\n", i, u.f[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (float *v)
+{
+  __m128 x;
+
+  x = _mm_set_ps (0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_ps (0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_ps (0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_ps (v[3], 0, 0, 0);
+  check (x, v, 3);
+}
+
+static void
+sse4_1_test (void)
+{
+  float v[4] = { -3, 2, 1, 9 };
+  test (v);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-init-v4si-1.c
new file mode 100644 (file)
index 0000000..63501b7
--- /dev/null
@@ -0,0 +1,68 @@
+/* { dg-do run } */
+/* { dg-require-effective-target sse4 } */
+/* { dg-options "-O2 -msse4.1" } */
+
+#include "sse4_1-check.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#include <emmintrin.h>
+
+static void
+__attribute__((noinline))
+check (__m128i x, unsigned int *v, int j)
+{
+  union
+    {
+      __m128i x;
+      unsigned int i[4];
+    } u;
+  unsigned int i;
+
+  u.x = x;
+  
+  for (i = 0; i < sizeof (v) / sizeof (v[0]); i++)
+    if (i == j)
+      {
+       if (v[i] != u.i[i])
+         {
+#ifdef DEBUG
+           printf ("%i: 0x%x != 0x%x\n", i, v[i], u.i[i]);
+#endif
+           abort ();
+         }
+      }
+    else if (u.i[i] != 0)
+      {
+#ifdef DEBUG
+       printf ("%i: 0x%x != 0\n", i, u.i[i]);
+#endif
+       abort ();
+      }
+}
+
+static void
+__attribute__((noinline))
+test (unsigned int *v)
+{
+  __m128i x;
+
+  x = _mm_set_epi32 (0, 0, 0, v[0]);
+  check (x, v, 0);
+  x = _mm_set_epi32 (0, 0, v[1], 0);
+  check (x, v, 1);
+  x = _mm_set_epi32 (0, v[2], 0, 0);
+  check (x, v, 2);
+  x = _mm_set_epi32 (v[3], 0, 0, 0);
+  check (x, v, 3);
+}
+
+static void
+sse4_1_test (void)
+{
+  unsigned int v[4]
+    = { 0x7B5B5465, 0x73745665, 0x63746F72, 0x5D53475D };
+  test (v);
+}