[ver2,4/4] rs6000, Add tests and documentation for vector, conversions between integer and float

Message ID e50d9928-4995-4032-b6e6-cd6cb7739a75@linux.ibm.com
State New
Headers
Series rs6000, remove redundant built-ins and add more test cases |

Commit Message

Carl Love Oct. 1, 2024, 3:28 p.m. UTC
  GCC maintainers:

Version 2, added the argument changes for the__builtin_vsx_uns_double[e 
| o | h | l ]_v4si built-ins. Added support to the vector {un,}signed 
int to vector float builtins so they are supported using Altivec 
instructions if VSX is not available per the feedback comments.

The following patch fixes errors in the definition of the 
__builtin_vsx_uns_floate_v2di, __builtin_vsx_uns_floato_v2di and 
__builtin_vsx_uns_float2_v2di built-ins.  The arguments should be 
unsigned but are listed as signed.

Additionally, there are a number of test cases that are missing for the 
various instances of the built-ins.  Additionally, the documentation for 
the various built-ins is missing.

This patch adds the missing test cases and documentation.

The patch has been tested on Power 10 LE and BE with no regressions.

Please let me know if it is acceptable for mainline.  Thanks.

                                             Carl

---------------------------------------------------------------------------------------------------------
rs6000, Add tests and documentation for vector conversions between 
integer and float

The arguments for the __builtin_vsx_uns_floate_v2di,
__builtin_vsx_uns_floato_v2di, __builtin_vsx_uns_float2_v2di,
__builtin_vsx_xvcvuxwsp built-ins,__builtin_vsx_uns_doublee_v4si,
__builtin_vsx_uns_doubleh_v4si, __builtin_vsx_uns_doublel_v4si and
__builtin_vsx_uns_doubleo_v4si built-ins should be unsigned not signed.

Add tests for the following existing vector integer and vector long long
int to vector float built-ins:
   __builtin_altivec_float_sisf (vsi);
   __builtin_altivec_uns_float_sisf (vui);

Add tests for the vector float to vector int built-ins:
   __builtin_altivec_fix_sfsi
   __builtin_altivec_fixuns_sfsi

The four built-ins are not documented.  The patch adds the missing
documentation for the built-ins.

The vector signed/unsigned integer to vector floating point built-ins
__builtin_vsx_xvcvsxwsp, __builtin_vsx_xvcvuxwsp are extended to generate
Altivec instructions if VSX is not available.  A new test case for these
built-ins with Altivec is added to test the new functionality.

This patch fixes the incorrect __builtin_vsx_uns_float[o|e|2]_v2di
and __builtin_vsx_xvcvuxwsp argument types and adds test cases for each
of the built-ins listed above.

gcc/ChangeLog:
     * config/rs6000/rs6000-builtins.def (__builtin_vsx_uns_floate_v2di,
     __builtin_vsx_uns_floato_v2di,__builtin_vsx_uns_float2_v2di,
     __builtin_vsx_xvcvuxwspm __builtin_vsx_uns_doublee_v4si,
     __builtin_vsx_uns_doubleh_v4si, __builtin_vsx_uns_doublel_v4si,
     __builtin_vsx_uns_doubleo_v4si): Change argument from signed to
     unsigned.
     ( __builtin_vsx_xvcvsxwsp, __builtin_vsx_xvcvuxwsp): Move to
     section Altivec.
     * config/rs6000/vsx.md (vsx_floatv4siv4sf2, vsx_floatunsv4siv4sf2):
     Add define expand to generate VSX instructions if VSX is enabled
     and Altivec instructions otherwise.
     (vsx_float<VSi><mode>2, vsx_floatuns<VSi><mode>2): Change
     define_insns to define_insn for vsx_float<VSi><mode>2_internal and
     vsx_floatuns<VSi><mode>2_internal.
     (vsx_floatv2div2df2, vsx_floatunsv2div2df2): Add define expands.
     * doc/extend.texi: Add documentation for each of the built-ins.

gcc/testsuite/ChangeLog:
     * gcc.target/powerpc/builtins-3-altivec-runnable.c: New file.
     * gcc.target/powerpc/builtins-3-runnable.c: Move functions void
     and test_result_sp to file builtins-3-runnable.h. Add include for
     builtins3-runnable.h.
     gcc.target/powerpc/builtins-3-altivec-runnable.h: New file.
     * gcc.target/powerpc/vsx-int-to-float-runnable.c: New file.
---
  gcc/config/rs6000/rs6000-builtins.def         |  28 +-
  gcc/config/rs6000/vsx.md                      |  50 +++-
  gcc/doc/extend.texi                           |  22 ++
  .../powerpc/builtins-3-altivec-runnable.c     |  35 +++
  .../gcc.target/powerpc/builtins-3-runnable.c  |  43 +--
  .../gcc.target/powerpc/builtins-3-runnable.h  |  51 ++++
  .../powerpc/vsx-int-to-float-runnable.c       | 260 ++++++++++++++++++
  7 files changed, 432 insertions(+), 57 deletions(-)
  create mode 100644 
gcc/testsuite/gcc.target/powerpc/builtins-3-altivec-runnable.c
  create mode 100644 gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.h
  create mode 100644 
gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c

+      printf ("ERROR, __builtin_altivec_fixuns_sfsi (src_f) result doe 
not match expected output.\n");
+      printf ("  result_uint[%d] = %d  ", i, result_uint[i]);
+      printf ("  expected_result_uint[%d] = %d\n", i,
+          expected_result_uint[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+}
  

Patch

diff --git a/gcc/config/rs6000/rs6000-builtins.def 
b/gcc/config/rs6000/rs6000-builtins.def
index 7350b913d03..9bda109d955 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -1119,6 +1119,14 @@ 
    const signed short __builtin_vec_ext_v8hi (vss, signed int);
      VEC_EXT_V8HI nothing {extract}

+;; __builtin_vsx_xvcvsxwsp, __builtin_vsx_xvcvuxwsp generate VSX 
instructions
+;; if VSX enabled and Altivec instructions if VSX is not enabled.
+  const vf __builtin_vsx_xvcvsxwsp (vsi);
+    XVCVSXWSP vsx_floatv4siv4sf2 {}
+
+  const vf __builtin_vsx_xvcvuxwsp (vui);
+    XVCVUXWSP vsx_floatunsv4siv4sf2 {}
+
  ; Cell builtins.
  [cell]
    pure vsc __builtin_altivec_lvlx (signed long, const void *);
@@ -1454,22 +1462,22 @@ 
    const vull __builtin_vsx_udiv_2di (vull, vull);
      UDIV_V2DI vsx_udiv_v2di {}

-  const vd __builtin_vsx_uns_doublee_v4si (vsi);
+  const vd __builtin_vsx_uns_doublee_v4si (vui);
      UNS_DOUBLEE_V4SI unsdoubleev4si2 {}

-  const vd __builtin_vsx_uns_doubleh_v4si (vsi);
+  const vd __builtin_vsx_uns_doubleh_v4si (vui);
      UNS_DOUBLEH_V4SI unsdoublehv4si2 {}

-  const vd __builtin_vsx_uns_doublel_v4si (vsi);
+  const vd __builtin_vsx_uns_doublel_v4si (vui);
      UNS_DOUBLEL_V4SI unsdoublelv4si2 {}

-  const vd __builtin_vsx_uns_doubleo_v4si (vsi);
+  const vd __builtin_vsx_uns_doubleo_v4si (vui);
      UNS_DOUBLEO_V4SI unsdoubleov4si2 {}

-  const vf __builtin_vsx_uns_floate_v2di (vsll);
+  const vf __builtin_vsx_uns_floate_v2di (vull);
      UNS_FLOATE_V2DI unsfloatev2di {}

-  const vf __builtin_vsx_uns_floato_v2di (vsll);
+  const vf __builtin_vsx_uns_floato_v2di (vull);
      UNS_FLOATO_V2DI unsfloatov2di {}

    const vsll __builtin_vsx_vsigned_v2df (vd);
@@ -1604,9 +1612,6 @@ 
    const vf __builtin_vsx_xvcvsxdsp (vsll);
      XVCVSXDSP vsx_xvcvsxdsp {}

-  const vf __builtin_vsx_xvcvsxwsp (vsi);
-    XVCVSXWSP vsx_floatv4siv4sf2 {}
-
    const vd __builtin_vsx_xvcvuxddp (vsll);
      XVCVUXDDP vsx_floatunsv2div2df2 {}

@@ -1616,9 +1621,6 @@ 
    const vf __builtin_vsx_xvcvuxdsp (vull);
      XVCVUXDSP vsx_xvcvuxdsp {}

-  const vf __builtin_vsx_xvcvuxwsp (vsi);
-    XVCVUXWSP vsx_floatunsv4siv4sf2 {}
-
    fpmath vd __builtin_vsx_xvdivdp (vd, vd);
      XVDIVDP divv2df3 {}

@@ -2278,7 +2280,7 @@ 
    const vss __builtin_vsx_revb_v8hi (vss);
      REVB_V8HI revb_v8hi {}

-  const vf __builtin_vsx_uns_float2_v2di (vsll, vsll);
+  const vf __builtin_vsx_uns_float2_v2di (vull, vull);
      UNS_FLOAT2_V2DI uns_float2_v2di {}

    const vsi __builtin_vsx_vsigned2_v2df (vd, vd);
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index b2fc39acf4e..f66972e7507 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -2272,14 +2272,60 @@  (define_insn "vsx_copysign<mode>3"
  ;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX.
  ;; Don't use vsx_register_operand here, use gpc_reg_operand to match 
rs6000.md
  ;; in allowing virtual registers.
-(define_insn "vsx_float<VSi><mode>2"
+(define_expand "vsx_floatv4siv4sf2"
+  [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa")
+    (float:V4SF (match_operand:V4SI 1 "gpc_reg_operand" "wa")))]
+  "VECTOR_UNIT_VSX_P (V4SFmode)"
+{
+  if (VECTOR_UNIT_VSX_P (V4SFmode))
+    emit_insn (gen_vsx_floatv4siv4sf2_internal (operands[0],
+           operands[1]));
+  else
+    emit_insn (gen_altivec_vcfsx (operands[0], operands[1],
+           const0_rtx));
+  DONE;
+})
+
+(define_expand "vsx_floatv2div2df2"
+  [(set (match_operand:V2DF 0 "gpc_reg_operand" "=wa")
+    (float:V2DF (match_operand:V2DI 1 "gpc_reg_operand" "wa")))]
+  "VECTOR_UNIT_VSX_P (V2DFmode)"
+{
+  emit_insn (gen_vsx_floatv2div2df2_internal (operands[0],
+         operands[1]));
+})
+
+(define_insn "vsx_float<VSi><mode>2_internal"
    [(set (match_operand:VSX_F 0 "gpc_reg_operand" "=wa")
      (float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand" "wa")))]
    "VECTOR_UNIT_VSX_P (<MODE>mode)"
    "xvcvsx<VSc><sd>p %x0,%x1"
    [(set_attr "type" "<VStype_simple>")])

-(define_insn "vsx_floatuns<VSi><mode>2"
+(define_expand "vsx_floatunsv4siv4sf2"
+  [(set (match_operand:V4SF 0 "gpc_reg_operand" "=wa")
+    (unsigned_float:V4SF (match_operand:V4SI 1 "gpc_reg_operand" "wa")))]
+  "VECTOR_UNIT_VSX_P (V4SFmode)"
+{
+  if (VECTOR_UNIT_VSX_P (V4SFmode))
+    emit_insn (gen_vsx_floatunsv4siv4sf2_internal (operands[0],
+           operands[1]));
+  else
+    emit_insn (gen_altivec_vcfux (operands[0], operands[1],
+           const0_rtx));
+  DONE;
+})
+
+(define_expand "vsx_floatunsv2div2df2"
+  [(set (match_operand:V2DF 0 "gpc_reg_operand" "=wa")
+    (unsigned_float:V2DF (match_operand:V2DI 1 "gpc_reg_operand" "wa")))]
+  "VECTOR_UNIT_VSX_P (V2DFmode)"
+{
+  emit_insn (gen_vsx_floatunsv2div2df2_internal (operands[0],
+         operands[1]));
+})
+
+(define_insn "vsx_floatuns<VSi><mode>2_internal"
    [(set (match_operand:VSX_F 0 "gpc_reg_operand" "=wa")
      (unsigned_float:VSX_F (match_operand:<VSI> 1 "gpc_reg_operand" 
"wa")))]
    "VECTOR_UNIT_VSX_P (<MODE>mode)"
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index adc4a54c5fa..07d6b049a7d 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -23008,6 +23008,28 @@  but the index value must be 0.

  Only functions excluded from the PVIPR are listed here.

+The following built-ins convert signed and unsigned vectors of ints and
+long long ints to a vector of 32-bit floating point values.
+
+@smallexample
+vector float __builtin_altivec_float_sisf (vector int);
+vector float __builtin_altivec_uns_float_sisf (vector unsigned int);
+@end smallexample
+
+The @code{__builtin_altivec_float_sisf} and
+@code{__builtin_altivec_uns_float_sisf} built-ins convert signed and
+unsigned vectors of 32-bit integers to a vector of 32-bit floating point
+values.
+
+@smallexample
+vector int __builtin_altivec_fix_sfsi (vector float);
+vector int __builtin_altivec_fixuns_sfsi (vector float);
+@end smallexample
+
+The @code{__builtin_altivec_fix_sfsi} and 
@code{__builtin_altivec_fixuns_sfsi}
+built-ins convert vectors of 32-bit floating point values to
+signed or unsigned 32-bit integers respectively.
+
  @smallexample
  vector __int128 vec_vaddcuq (vector __int128, vector __int128);
  vector __uint128 vec_vaddcuq (vector __uint128, vector __uint128);
diff --git 
a/gcc/testsuite/gcc.target/powerpc/builtins-3-altivec-runnable.c 
b/gcc/testsuite/gcc.target/powerpc/builtins-3-altivec-runnable.c
new file mode 100644
index 00000000000..d208e25dfc4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-altivec-runnable.c
@@ -0,0 +1,35 @@ 
+/* { dg-do run { target { vsx_hw } } } */
+/* { dg-options "-mdejagnu-cpu=power6 -maltivec -O2" } */
+/* { dg-require-effective-target powerpc_altivec } */
+
+/* This test if for the vector signed/unsigned integer to vector float
+   conversions when VSX is not available.  The overloaded built-ins for the
+   conversions will generate Altivec conversions when VSX is not available.
+*/
+
+#include <altivec.h> // vector
+#include "builtins-3-runnable.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int main()
+{
+    int i;
+    vector unsigned int vec_unint, vec_uns_int_expected, 
vec_uns_int_result;
+    vector signed int vec_int, vec_int_expected, vec_int_result;
+    vector float  vec_flt_result, vec_flt_expected;
+
+    vec_int = (vector signed int){ -1, 3, -5, 1234567 };
+    vec_unint = (vector unsigned int){ 9, 11, 15, 2468013579 };
+
+    /* conversion of integer vector to single precision float vector */
+    vec_flt_expected = (vector float){-1.00, 3.00, -5.00, 1234567.00};
+    vec_flt_result = vec_float (vec_int);
+    test_result_sp(ALL, vec_flt_result, vec_flt_expected);
+
+    vec_flt_expected = (vector float){9.00, 11.00, 15.00, 2468013579.0};
+    vec_flt_result = vec_float (vec_unint);
+    test_result_sp(ALL, vec_flt_result, vec_flt_expected);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.c 
b/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.c
index 5c2481dd612..bbd5ecb5f00 100644
--- a/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.c
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.c
@@ -3,16 +3,8 @@ 
  /* { dg-options "-maltivec -mvsx" } */

  #include <altivec.h> // vector
+#include "builtins-3-runnable.h"

-#ifdef DEBUG
-#include <stdio.h>
-#endif
-
-#define ALL  1
-#define EVEN 2
-#define ODD  3
-
-void abort (void);

  void test_int_result(int check, vector int vec_result, vector int 
vec_expected)
  {
@@ -116,39 +108,6 @@  void test_ll_unsigned_int_result(vector long long 
unsigned int vec_result,
          }
  }

-void test_result_sp(int check, vector float vec_result,
-            vector float vec_expected)
-{
-    int i;
-    for(i = 0; i<4; i++) {
-
-        switch (check) {
-        case ALL:
-            break;
-        case EVEN:
-            if (i%2 == 0)
-                break;
-            else
-                continue;
-        case ODD:
-            if (i%2 != 0)
-                break;
-            else
-                continue;
-        }
-
-        if (vec_result[i] != vec_expected[i]) {
-#ifdef DEBUG
-            printf("Test_result_sp: ");
-            printf("vec_result[%d] (%f) != vec_expected[%d] (%f)\n",
-                   i, vec_result[i], i, vec_expected[i]);
-#else
-            abort();
-#endif
-        }
-    }
-}
-
  void test_result_dp(vector double vec_result, vector double vec_expected)
  {
      if (vec_result[0] != vec_expected[0]) {
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.h 
b/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.h
new file mode 100644
index 00000000000..962a86750cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/builtins-3-runnable.h
@@ -0,0 +1,51 @@ 
+/* Builtins vsx_floatv4siv4sf2 and vsx_floatunsv4siv4sf2 generate VSX
+   instructions if VSX if available.  They fall back to Altivec 
instructions
+   if VSX is not available.  The functions are used in the test the 
conversion
+   of signed and unsigned vectors of integers to a vector of single 
precision
+   floating point values.  The function is used in the VSX text
+   builtins-3-runnable.c and in the altivec test 
builtins-3-altivec-runnable.c.
+*/
+
+#define ALL  1
+#define EVEN 2
+#define ODD  3
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+void test_result_sp(int check, vector float vec_result,
+            vector float vec_expected)
+{
+    int i;
+    for(i = 0; i<4; i++) {
+
+        switch (check) {
+        case ALL:
+            break;
+        case EVEN:
+            if (i%2 == 0)
+                break;
+            else
+                continue;
+        case ODD:
+            if (i%2 != 0)
+                break;
+            else
+                continue;
+        }
+
+        if (vec_result[i] != vec_expected[i]) {
+#ifdef DEBUG
+            printf("Test_result_sp: ");
+            printf("vec_result[%d] (%f) != vec_expected[%d] (%f)\n",
+                   i, vec_result[i], i, vec_expected[i]);
+#else
+            abort();
+#endif
+        }
+    }
+}
+
diff --git 
a/gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c 
b/gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c
new file mode 100644
index 00000000000..e01bb274721
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c
@@ -0,0 +1,260 @@ 
+/* { dg-do run } */
+/* { dg-options "-mvsx -mdejagnu-cpu=power8 -O2" } */
+/* { dg-require-effective-target powerpc_vsx } */
+
+/* The __builtin_vsx_float2_v2di builtin uses the vmgrow instruction 
which is
+   Power 8.  The conversion instructions are all Power 7.  */
+
+#include <altivec.h> // vector
+
+#define DEBUG 0
+
+#if DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+int main (void)
+{
+  int i;
+  vector int src_int = { 5, 17, 400, 9000 };
+  vector unsigned int src_uint = { 1, 20, 300, 4000 };
+  vector signed long long int src_sll = { 13, 513 };
+  vector unsigned long long int src_ull = { 27, 731 };
+  vector signed long long int srcB_sll = { 27, 739 };
+  vector unsigned long long int srcB_ull = { 19, 57 };
+  vector int result_int, expected_result_int;
+  vector unsigned int result_uint, expected_result_uint;
+  vector float src_f = { 3.1, -9.1, 20.9, -99.99};
+  vector float result_float, expected_result_float;
+  vector double result_double, expected_result_double;
+
+  /* Test vector signed and unsigned int to float.  */
+  expected_result_float[0] = 5.0;
+  expected_result_float[1] = 17.0;
+  expected_result_float[2] = 400.0;
+  expected_result_float[3] = 9000.0;
+
+  result_float = __builtin_altivec_float_sisf (src_int);
+
+  for (i = 0; i < 4; i++)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_float_sisf (src_uint) result 
doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+
+  expected_result_float[0] = 1.0;
+  expected_result_float[1] = 20.0;
+  expected_result_float[2] = 300.0;
+  expected_result_float[3] = 4000.0;
+
+  result_float = __builtin_altivec_uns_float_sisf (src_uint);
+
+  for (i = 0; i < 4; i++)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_uns_float_sisf (src_uint) 
result doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+
+  /* Test vector signed and unsigned long long int to Double.  */
+
+  /* Test even result elements.  */
+  expected_result_float[0] = 13.0;
+  expected_result_float[1] = 0.0;
+  expected_result_float[2] = 513.0;
+  expected_result_float[3] = 0.0;
+
+  result_float = __builtin_vsx_floate_v2di(src_sll);
+
+  for (i = 0; i < 4; i = i + 2)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_floate_v2di (src_sll) result 
doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+
+  expected_result_float[0] = 27.0;
+  expected_result_float[1] = 0.0;
+  expected_result_float[2] = 731.0;
+  expected_result_float[3] = 0.0;
+
+  result_float = __builtin_vsx_uns_floate_v2di(src_ull);
+
+  for (i = 0; i < 4; i = i + 2)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_uns_floate_v2di (src_ull) 
result doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+
+    }
+
+  /* Test odd result elements.  */
+  expected_result_float[0] = 0.0;
+  expected_result_float[1] = 13.0;
+  expected_result_float[2] = 0.0;
+  expected_result_float[3] = 513.0;
+
+  result_float = __builtin_vsx_floato_v2di(src_sll);
+
+  for (i = 1; i < 4; i = i + 2)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_floato_v2di (src_sll) result 
doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+
+    }
+
+  expected_result_float[0] = 0.0;
+  expected_result_float[1] = 27.0;
+  expected_result_float[2] = 0.0;
+  expected_result_float[3] = 731.0;
+
+  result_float = __builtin_vsx_uns_floato_v2di(src_ull);
+
+  for (i = 1; i < 4; i = i + 2)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_uns_floato_v2di (src_ull) 
result doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+
+  /* Test two source args.  */
+  expected_result_float[0] = 13.0;
+  expected_result_float[1] = 513.0;
+  expected_result_float[2] = 27.0;
+  expected_result_float[3] = 739.0;
+
+  result_float = __builtin_vsx_float2_v2di(src_sll, srcB_sll);
+
+  for (i = 1; i < 4; i++)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_uns_float2_v2di (src_sll, 
src_sll) result doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+  expected_result_float[0] = 27.0;
+  expected_result_float[1] = 731.0;
+  expected_result_float[2] = 19.0;
+  expected_result_float[3] = 57.0;
+
+  result_float = __builtin_vsx_uns_float2_v2di(src_ull, srcB_ull);
+
+  for (i = 1; i < 4; i++)
+    {
+      if (result_float[i] != expected_result_float[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_uns_float2_v2di (src_ull, 
src_ull) result doe not match expected output.\n");
+      printf ("  result_float[%d] = %f  ", i, result_float[i]);
+      printf ("  expected result_float[%d] = %f\n", i,
+          expected_result_float[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+
+  /* Test vector float to signed/unsigned vector int.  */
+  expected_result_int[0] = 3;
+  expected_result_int[1] = -9;
+  expected_result_int[2] = 20;
+  expected_result_int[3] = -99;
+
+  result_int = __builtin_altivec_fix_sfsi(src_f);
+
+  for (i = 0; i < 4; i++)
+    {
+      if (result_int[i] != expected_result_int[i])
+#if DEBUG
+    {
+      printf ("ERROR, __builtin_altivec_fix_sfsi (src_f) result doe not 
match expected output.\n");
+      printf ("  result_int[%d] = %d  ", i, result_int[i]);
+      printf ("  expected_result_int[%d] = %d\n", i,
+          expected_result_int[i]);
+    }
+#else
+        abort ();
+#endif
+    }
+
+  expected_result_uint[0] = 3;
+  expected_result_uint[1] = 0;
+  expected_result_uint[2] = 20;
+  expected_result_uint[3] = 0;
+
+  result_uint = __builtin_altivec_fixuns_sfsi(src_f);
+
+  for (i = 0; i < 4; i++)
+    {
+      if (result_uint[i] != expected_result_uint[i])
+#if DEBUG
+    {