[rs6000] testcases for GIMPLE folding of vec_splat builtin.

Message ID 1533669906.4452.12.camel@brimstone.rchland.ibm.com
State New
Headers show
Series
  • [rs6000] testcases for GIMPLE folding of vec_splat builtin.
Related show

Commit Message

Will Schmidt Aug. 7, 2018, 7:25 p.m.
Hi,
  Some testcases to exercise the vec_splat() built-in.
    
Tested successfully on assorted powerpc Linux systems, in conjunction
with the vec-splat() folding patch, which is being posted separately.
    
In building and updating these tests I consciously violated the
80 char per line rule, as I was doing experimentation with the
assorted values and making lots of local updates.  I've left them as-is
just because, but can update that if so desired.
    
OK for trunk?
    
Thanks,
-Will
    
[testsuite]
    
2018-08-07  Will Schmidt  <will_schmidt@vnet.ibm.com>
    
	* gcc.target/powerpc/fold-vec-splat-char.c: New.
	* gcc.target/powerpc/fold-vec-splat-floatdouble.c: New.
	* gcc.target/powerpc/fold-vec-splat-int.c: New.
	* gcc.target/powerpc/fold-vec-splat-longlong.c: New.
	* gcc.target/powerpc/fold-vec-splat-pixel.c: New.
	* gcc.target/powerpc/fold-vec-splat-short.c: New.

Comments

Segher Boessenkool Aug. 7, 2018, 9:50 p.m. | #1
Hi!

On Tue, Aug 07, 2018 at 02:25:06PM -0500, Will Schmidt wrote:
>   Some testcases to exercise the vec_splat() built-in.

> In building and updating these tests I consciously violated the
> 80 char per line rule, as I was doing experimentation with the
> assorted values and making lots of local updates.  I've left them as-is
> just because, but can update that if so desired.

That is fine in testcases (and even practically unavoidable in many
dg statements).

> +// vec_splat() using variable vectors should generate the vspltb instruction.
> +/* { dg-final { scan-assembler-times "vspltb" 24 } } */
> +// vec_splat() using a constant vector should generate a load.
> +/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvw4x\M} 3 } } */

You may want to use {} and \m\M everywhere, for symmetry and for future-
proofing things a bit.  It's not necessary of course.

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c
> @@ -0,0 +1,54 @@
> +/* Verify that overloaded built-ins for vec_splat with float and
> +   double inputs produce the right code.  */
> +
> +/* { dg-do compile } */
> +/* { dg-require-effective-target powerpc_vsx_ok } */
> +/* { dg-options "-maltivec -mvsx -O1" } */

-mvsx implies -maltivec.

Is there any reason some of these tests use -O2 and some use -O1?

> new file mode 100644
> index 0000000..729b0cc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-longlong.c
> @@ -0,0 +1,62 @@
> +/* Verify that overloaded built-ins for vec_splat with long long
> +   inputs produce the right code.  */
> +
> +/* { dg-do compile } */
> +/* { dg-require-effective-target powerpc_p8vector_ok } */
> +/* { dg-options "-mvsx -O2" } */

What is that p8vector_ok for?  You don't force p8 vector support on.
I think you can remove this.

Okay for trunk with that last one resolved.  Thanks!


Segher

Patch

diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-char.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-char.c
new file mode 100644
index 0000000..7c4c784
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-char.c
@@ -0,0 +1,60 @@ 
+/* Verify that overloaded built-ins for vec_splat with char
+   inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2" } */
+
+#include <altivec.h>
+
+vector bool char testb_0  (vector bool char x) { return vec_splat (x, 0b00000); }
+vector bool char testb_1  (vector bool char x) { return vec_splat (x, 0b00001); }
+vector bool char testb_2  (vector bool char x) { return vec_splat (x, 0b00010); }
+vector bool char testb_4  (vector bool char x) { return vec_splat (x, 0b00100); }
+vector bool char testb_8  (vector bool char x) { return vec_splat (x, 0b01000); }
+vector bool char testb_10 (vector bool char x) { return vec_splat (x, 0b10000); }
+vector bool char testb_1e (vector bool char x) { return vec_splat (x, 0b11110); }
+vector bool char testb_1f (vector bool char x) { return vec_splat (x, 0b11111); }
+
+vector signed char tests_0  (vector signed char x) { return vec_splat (x, 0b00000); }
+vector signed char tests_1  (vector signed char x) { return vec_splat (x, 0b00001); }
+vector signed char tests_2  (vector signed char x) { return vec_splat (x, 0b00010); }
+vector signed char tests_4  (vector signed char x) { return vec_splat (x, 0b00100); }
+vector signed char tests_8  (vector signed char x) { return vec_splat (x, 0b01000); }
+vector signed char tests_10 (vector signed char x) { return vec_splat (x, 0b10000); }
+vector signed char tests_1e (vector signed char x) { return vec_splat (x, 0b11110); }
+vector signed char tests_1f (vector signed char x) { return vec_splat (x, 0b11111); }
+
+vector unsigned char testu_0  (vector unsigned char x) { return vec_splat (x, 0b00000); }
+vector unsigned char testu_1  (vector unsigned char x) { return vec_splat (x, 0b00001); }
+vector unsigned char testu_2  (vector unsigned char x) { return vec_splat (x, 0b00010); }
+vector unsigned char testu_4  (vector unsigned char x) { return vec_splat (x, 0b00100); }
+vector unsigned char testu_8  (vector unsigned char x) { return vec_splat (x, 0b01000); }
+vector unsigned char testu_10 (vector unsigned char x) { return vec_splat (x, 0b10000); }
+vector unsigned char testu_1e (vector unsigned char x) { return vec_splat (x, 0b11110); }
+vector unsigned char testu_1f (vector unsigned char x) { return vec_splat (x, 0b11111); }
+
+/* Similar test as above, but the source vector is a known constant. */
+const vector bool char by = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
+const vector signed char sy = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
+const vector unsigned char uy = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'};
+vector bool char
+test_bc (vector bool char x)
+{
+  return vec_splat (by, 0b00010);
+}
+vector signed char
+test_sc (vector signed char x)
+{
+  return vec_splat (sy, 0b00011);
+}
+vector unsigned char
+test_uc (vector unsigned char x)
+{
+  return vec_splat (uy, 0b00110);
+}
+
+// vec_splat() using variable vectors should generate the vspltb instruction.
+/* { dg-final { scan-assembler-times "vspltb" 24 } } */
+// vec_splat() using a constant vector should generate a load.
+/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvw4x\M} 3 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c
new file mode 100644
index 0000000..a6eaa72
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c
@@ -0,0 +1,54 @@ 
+/* Verify that overloaded built-ins for vec_splat with float and
+   double inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-maltivec -mvsx -O1" } */
+
+#include <altivec.h>
+
+vector float testf_00 (vector float x) { return vec_splat (x, 0b00000); }
+vector float testf_01 (vector float x) { return vec_splat (x, 0b00001); }
+vector float testf_02 (vector float x) { return vec_splat (x, 0b00010); }
+vector float testf_04 (vector float x) { return vec_splat (x, 0b00100); }
+vector float testf_08 (vector float x) { return vec_splat (x, 0b01000); }
+vector float testf_0f (vector float x) { return vec_splat (x, 0b01111); }
+vector float testf_10 (vector float x) { return vec_splat (x, 0b10000); }
+vector float testf_1e (vector float x) { return vec_splat (x, 0b11110); }
+vector float testf_1f (vector float x) { return vec_splat (x, 0b11111); }
+
+vector double testd_00 (vector double x) { return vec_splat (x, 0b00000); }
+vector double testd_01 (vector double x) { return vec_splat (x, 0b00001); }
+vector double testd_02 (vector double x) { return vec_splat (x, 0b00010); }
+vector double testd_04 (vector double x) { return vec_splat (x, 0b00100); }
+vector double testd_08 (vector double x) { return vec_splat (x, 0b01000); }
+vector double testd_0f (vector double x) { return vec_splat (x, 0b01111); }
+vector double testd_10 (vector double x) { return vec_splat (x, 0b10000); }
+vector double testd_1e (vector double x) { return vec_splat (x, 0b11110); }
+vector double testd_1f (vector double x) { return vec_splat (x, 0b11111); }
+
+/* Similar tests as above, but the source vector is a known constant. */
+vector float
+test_fc (vector float x)
+{
+  const vector float y = { 7.1, 8.2, 9.3, 10.4};
+  return vec_splat (y, 0b00010);
+}
+
+vector double
+test_dc (vector double x)
+{
+  const vector double y = { 3.0, 5.0 };
+  return vec_splat (y, 0b00010);
+}
+
+/* lvx for loading of the constants.  */
+/* vspltw or xxspltw for floats.  */
+/* xxpermdi for doubles.  */
+
+// vec_splat() using a constant vector should generate a load.
+/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvd2x\M} 2 } } */
+
+/* { dg-final { scan-assembler-times "vspltw|xxspltw" 9 } } */
+/* { dg-final { scan-assembler-times "xxpermdi" 9 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-int.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-int.c
new file mode 100644
index 0000000..8694ba5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-int.c
@@ -0,0 +1,45 @@ 
+/* Verify that overloaded built-ins for vec_splat with int
+   inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2" } */
+
+#include <altivec.h>
+vector bool int testb_0  (vector bool int x) { return vec_splat (x, 0b00000); }
+vector bool int testb_1  (vector bool int x) { return vec_splat (x, 0b00001); }
+vector bool int testb_2  (vector bool int x) { return vec_splat (x, 0b00010); }
+vector bool int testb_4  (vector bool int x) { return vec_splat (x, 0b00100); }
+vector bool int testb_8  (vector bool int x) { return vec_splat (x, 0b01000); }
+vector bool int testb_10 (vector bool int x) { return vec_splat (x, 0b10000); }
+vector bool int testb_1e (vector bool int x) { return vec_splat (x, 0b11110); }
+vector bool int testb_1f (vector bool int x) { return vec_splat (x, 0b11111); }
+
+vector signed int tests_0  (vector signed int x) { return vec_splat (x, 0b00000); }
+vector signed int tests_1  (vector signed int x) { return vec_splat (x, 0b00001); }
+vector signed int tests_2  (vector signed int x) { return vec_splat (x, 0b00010); }
+vector signed int tests_4  (vector signed int x) { return vec_splat (x, 0b00100); }
+vector signed int tests_8  (vector signed int x) { return vec_splat (x, 0b01000); }
+vector signed int tests_10 (vector signed int x) { return vec_splat (x, 0b10000); }
+vector signed int tests_1e (vector signed int x) { return vec_splat (x, 0b11110); }
+vector signed int tests_1f (vector signed int x) { return vec_splat (x, 0b11111); }
+
+vector unsigned int testu_0  (vector unsigned int x) { return vec_splat (x, 0b00000); }
+vector unsigned int testu_1  (vector unsigned int x) { return vec_splat (x, 0b00001); }
+vector unsigned int testu_2  (vector unsigned int x) { return vec_splat (x, 0b00010); }
+vector unsigned int testu_4  (vector unsigned int x) { return vec_splat (x, 0b00100); }
+vector unsigned int testu_8  (vector unsigned int x) { return vec_splat (x, 0b01000); }
+vector unsigned int testu_10 (vector unsigned int x) { return vec_splat (x, 0b10000); }
+vector unsigned int testu_1e (vector unsigned int x) { return vec_splat (x, 0b11110); }
+vector unsigned int testu_1f (vector unsigned int x) { return vec_splat (x, 0b11111); }
+
+/* Similar test as above, but the source vector is a known constant. */
+vector signed int
+test3_0c (vector signed int x)
+{
+  const vector signed int y = { 1,2,3,4};
+  return vec_splat (y, 0b00010);
+}
+/* { dg-final { scan-assembler-times "vspltisw" 1 } } */
+/* { dg-final { scan-assembler-times "vspltw|xxspltw" 24 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-longlong.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-longlong.c
new file mode 100644
index 0000000..729b0cc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-longlong.c
@@ -0,0 +1,62 @@ 
+/* Verify that overloaded built-ins for vec_splat with long long
+   inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mvsx -O2" } */
+
+#include <altivec.h>
+
+vector bool long long testb_00 (vector bool long long x) { return vec_splat (x, 0b00000); }
+vector bool long long testb_01 (vector bool long long x) { return vec_splat (x, 0b00001); }
+vector bool long long testb_02 (vector bool long long x) { return vec_splat (x, 0b00010); }
+vector bool long long testb_04 (vector bool long long x) { return vec_splat (x, 0b00100); }
+vector bool long long testb_08 (vector bool long long x) { return vec_splat (x, 0b01000); }
+vector bool long long testb_10 (vector bool long long x) { return vec_splat (x, 0b10000); }
+vector bool long long testb_1e (vector bool long long x) { return vec_splat (x, 0b11110); }
+vector bool long long testb_1f (vector bool long long x) { return vec_splat (x, 0b11111); }
+
+vector signed long long tests_00 (vector signed long long x) { return vec_splat (x, 0b00000); }
+vector signed long long tests_01 (vector signed long long x) { return vec_splat (x, 0b00001); }
+vector signed long long tests_02 (vector signed long long x) { return vec_splat (x, 0b00010); }
+vector signed long long tests_04 (vector signed long long x) { return vec_splat (x, 0b00100); }
+vector signed long long tests_08 (vector signed long long x) { return vec_splat (x, 0b01000); }
+vector signed long long tests_10 (vector signed long long x) { return vec_splat (x, 0b10000); }
+vector signed long long tests_1e (vector signed long long x) { return vec_splat (x, 0b11110); }
+vector signed long long tests_1f (vector signed long long x) { return vec_splat (x, 0b11111); }
+
+vector unsigned long long testu_00 (vector unsigned long long x) { return vec_splat (x, 0b00000); }
+vector unsigned long long testu_01 (vector unsigned long long x) { return vec_splat (x, 0b00001); }
+vector unsigned long long testu_02 (vector unsigned long long x) { return vec_splat (x, 0b00010); }
+vector unsigned long long testu_04 (vector unsigned long long x) { return vec_splat (x, 0b00100); }
+vector unsigned long long testu_08 (vector unsigned long long x) { return vec_splat (x, 0b01000); }
+vector unsigned long long testu_10 (vector unsigned long long x) { return vec_splat (x, 0b10000); }
+vector unsigned long long testu_1e (vector unsigned long long x) { return vec_splat (x, 0b11110); }
+vector unsigned long long testu_1f (vector unsigned long long x) { return vec_splat (x, 0b11111); }
+
+/* Similar test as above, but the source vector is a known constant. */
+vector bool long long
+test_bc (vector bool long long x)
+{
+  const vector bool long long y = {12, 23};
+  return vec_splat (y, 0b00010);
+}
+vector signed long long
+test_sc (vector signed long long x)
+{
+  const vector signed long long y = {34, 45};
+  return vec_splat (y, 0b00010);
+}
+vector unsigned long long
+test_uc (vector unsigned long long x)
+{
+  const vector unsigned long long y = {56, 67};
+  return vec_splat (y, 0b00010);
+}
+
+/* lvx for the initialization with known constants. */
+/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvd2x\M} 3 } } */
+/* xxpermdi for vec_splat of long long vectors.   The bool and unsigned long long
+   calls generate a pair of xxpermdi, so an additional +2. */
+/* { dg-final { scan-assembler-times "xxpermdi" 26 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-pixel.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-pixel.c
new file mode 100644
index 0000000..5e13468
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-pixel.c
@@ -0,0 +1,28 @@ 
+/* Verify that overloaded built-ins for vec_splat with pixel
+   inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mvsx -O2" } */
+
+#include <altivec.h>
+
+vector pixel test1_00 (vector pixel x) { return vec_splat (x, 0b00000); }
+vector pixel test1_01 (vector pixel x) { return vec_splat (x, 0b00001); }
+vector pixel test1_02 (vector pixel x) { return vec_splat (x, 0b00010); }
+vector pixel test1_04 (vector pixel x) { return vec_splat (x, 0b00100); }
+vector pixel test1_08 (vector pixel x) { return vec_splat (x, 0b01000); }
+vector pixel test1_10 (vector pixel x) { return vec_splat (x, 0b10000); }
+vector pixel test1_1e (vector pixel x) { return vec_splat (x, 0b11110); }
+vector pixel test1_1f (vector pixel x) { return vec_splat (x, 0b11111); }
+
+/* Similar test as above, but the source vector is a known constant. */
+vector signed int
+test3_0c (vector signed int x)
+{
+  const vector signed int y = { 1,2,3,4};
+  return vec_splat (y, 0b00010);
+}
+
+/* { dg-final { scan-assembler-times "vspltisw" 1 } } */
+/* { dg-final { scan-assembler-times "vsplth" 8 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-short.c b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-short.c
new file mode 100644
index 0000000..b240aa1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-short.c
@@ -0,0 +1,57 @@ 
+/* Verify that overloaded built-ins for vec_splat with short
+   inputs produce the right results.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2" } */
+
+#include <altivec.h>
+
+vector bool short testb_00 (vector bool short x) { return vec_splat (x, 0b00000); }
+vector bool short testb_01 (vector bool short x) { return vec_splat (x, 0b00001); }
+vector bool short testb_02 (vector bool short x) { return vec_splat (x, 0b00010); }
+vector bool short testb_04 (vector bool short x) { return vec_splat (x, 0b00100); }
+vector bool short testb_08 (vector bool short x) { return vec_splat (x, 0b01000); }
+vector bool short testb_10 (vector bool short x) { return vec_splat (x, 0b10000); }
+vector bool short testb_1e (vector bool short x) { return vec_splat (x, 0b11110); }
+vector bool short testb_1f (vector bool short x) { return vec_splat (x, 0b11111); }
+
+vector signed short tests_00 (vector signed short x) { return vec_splat (x, 0b00000); }
+vector signed short tests_01 (vector signed short x) { return vec_splat (x, 0b00001); }
+vector signed short tests_02 (vector signed short x) { return vec_splat (x, 0b00010); }
+vector signed short tests_04 (vector signed short x) { return vec_splat (x, 0b00100); }
+vector signed short tests_08 (vector signed short x) { return vec_splat (x, 0b01000); }
+vector signed short tests_10 (vector signed short x) { return vec_splat (x, 0b10000); }
+vector signed short tests_1e (vector signed short x) { return vec_splat (x, 0b11110); }
+vector signed short tests_1f (vector signed short x) { return vec_splat (x, 0b11111); }
+
+vector unsigned short testu_00 (vector unsigned short x) { return vec_splat (x, 0b00000); }
+vector unsigned short testu_01 (vector unsigned short x) { return vec_splat (x, 0b00001); }
+vector unsigned short testu_02 (vector unsigned short x) { return vec_splat (x, 0b00010); }
+vector unsigned short testu_04 (vector unsigned short x) { return vec_splat (x, 0b00100); }
+vector unsigned short testu_08 (vector unsigned short x) { return vec_splat (x, 0b01000); }
+vector unsigned short testu_10 (vector unsigned short x) { return vec_splat (x, 0b10000); }
+vector unsigned short testu_1e (vector unsigned short x) { return vec_splat (x, 0b11110); }
+vector unsigned short testu_1f (vector unsigned short x) { return vec_splat (x, 0b11111); }
+
+/* Similar test as above, but the source vector is a known constant. */
+vector bool short
+test_bs (vector signed short x)
+{
+  const vector bool short y = {1, 2, 3, 4, 5, 6, 7, 8};
+  return vec_splat (y, 0b00010);
+}
+vector signed short
+test_ss (vector signed short x)
+{
+  const vector signed short y = {1, 2, 3, 4, 5, 6, 7, 8};
+  return vec_splat (y, 0b00010);
+}
+vector unsigned short
+test_us (vector unsigned short x)
+{
+  const vector unsigned short y = {1, 2, 3, 4, 5, 6, 7, 8};
+  return vec_splat (y, 0b00010);
+}
+/* { dg-final { scan-assembler-times "vspltish" 3 } } */
+/* { dg-final { scan-assembler-times "vsplth" 24 } } */