GCC maintainers:
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 and __builtin_vsx_uns_float2_v2di built-ins
should be unsigned.
Add tests for the following existing integer and long long int to float
built-ins:
__builtin_altivecfloat_sisf (vsi);
__builtin_altivec_uns_float_sisf (vui);
__builtin_vsxfloate_v2di (vsll);
__builtin_vsx_uns_floate_v2di (vull);
__builtin_vsx_floato_v2di (vsll);
__builtin_vsx_uns_floato_v2di (vull);
__builtin_vsx_float2_v2di (vsll, vsll);
__builtin_vsx_uns_float2_v2di (vull, vull);
Add tests for the vector float to vector int built-ins:
__builtin_altivec_fix_sfsi
__builtin_altivec_fixuns_sfsi
The various built-ins are not documented. The patch adds the missing
documentation for the variouls built-ins.
This patch fixes the incorrect __builtin_vsx_uns_float[o|e|2]_v2di
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): Change
argument from signed to unsigned.
* doc/extend.texi: Add documentation for each of the built-ins.
gcc/testsuite/ChangeLog:
* gcc.target/powerpc/vsx-int-to-float-runnable.c: New file.
---
gcc/config/rs6000/rs6000-builtins.def | 6 +-
gcc/doc/extend.texi | 37 +++
.../powerpc/vsx-int-to-float-runnable.c | 260 ++++++++++++++++++
3 files changed, 300 insertions(+), 3 deletions(-)
create mode 100644
gcc/testsuite/gcc.target/powerpc/vsx-int-to-float-runnable.c
diff --git a/gcc/config/rs6000/rs6000-builtins.def
b/gcc/config/rs6000/rs6000-builtins.def
index f2bebd299b2..1227daa1555 100644
--- a/gcc/config/rs6000/rs6000-builtins.def
+++ b/gcc/config/rs6000/rs6000-builtins.def
@@ -1463,10 +1463,10 @@
const vd __builtin_vsx_uns_doubleo_v4si (vsi);
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);
@@ -2272,7 +2272,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/doc/extend.texi b/gcc/doc/extend.texi
index bf6f4094040..7ec4f19a6bf 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -22919,6 +22919,43 @@ 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);
+vector float __builtin_vsx_floate_v2di (vector signed long long int);
+vector float __builtin_vsx_uns_floate_v2di (vector unsigned long long
int);
+vector float __builtin_vsx_floato_v2di (vector signed long long int);
+vector float __builtin_vsx_uns_floato_v2di (vector unsigned long long
int);
+vector float __builtin_vsx_float2_v2di (vector signed long long int,
+ vector signed long long int);
+vector float __builtin_vsx_uns_float2_v2di (vector unsigned long long
int,
+ vector signed long long
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. The @code{__builtin_vsx_floate_v2di} and
+@code{__builtin_vsx_uns_floate_v2di} built-ins converts a vector
+long long ints to 32-bit floating point values storing the results in
+the corresonding even vector element locations. Similarly,
+@code{__builtin_vsx_floato_v2di} and
@code{__builtin_vsx_uns_floato_v2di}
+convert the long long ints and store them in the odd vector element
locations.
+The @code{__builtin_vsx_uns_float2_v2di} takes two long long int vectors
+and converts them to single 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/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
+ {
+ 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
+ }
+}