aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-01-26 10:27:18 +1030
committerAlan Modra <amodra@gcc.gnu.org>2018-01-26 10:27:18 +1030
commit73598b3330377a9970f4489f5c5d517f62b51386 (patch)
tree359af78554346f366a1c1b304b5d5009c12ba6b2
parent1bfbe9adbc554930163eb551f9904cf4fe096696 (diff)
downloadgcc-73598b3330377a9970f4489f5c5d517f62b51386.zip
gcc-73598b3330377a9970f4489f5c5d517f62b51386.tar.gz
gcc-73598b3330377a9970f4489f5c5d517f62b51386.tar.bz2
PR84033, powerpc64le -moptimize-swaps bad code with vec_vbpermq
vbpermq produces its output in bits 48..63 of the target vector reg, so the output cannot be lane swapped. gcc/ PR target/84033 * config/rs6000/rs6000-p8swap.c (rtx_is_swappable_p): Exclude UNSPEC_VBPERMQ. Sort other unspecs. gcc/testsuite/ PR target/84033 * gcc.target/powerpc/swaps-p8-46.c: New. From-SVN: r257070
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000-p8swap.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c34
4 files changed, 52 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ecbcb260..62dbe56 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2018-01-26 Alan Modra <amodra@gmail.com>
+
+ PR target/84033
+ * config/rs6000/rs6000-p8swap.c (rtx_is_swappable_p): Exclude
+ UNSPEC_VBPERMQ. Sort other unspecs.
+
2018-01-25 David Edelsohn <dje.gcc@gmail.com>
* doc/invoke.texi (PowerPC Options): Document 'native' cpu type.
diff --git a/gcc/config/rs6000/rs6000-p8swap.c b/gcc/config/rs6000/rs6000-p8swap.c
index 1f95290..ffcbba9 100644
--- a/gcc/config/rs6000/rs6000-p8swap.c
+++ b/gcc/config/rs6000/rs6000-p8swap.c
@@ -741,6 +741,7 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
{
default:
break;
+ case UNSPEC_VBPERMQ:
case UNSPEC_VMRGH_DIRECT:
case UNSPEC_VMRGL_DIRECT:
case UNSPEC_VPACK_SIGN_SIGN_SAT:
@@ -762,8 +763,14 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
case UNSPEC_VSUMSWS:
case UNSPEC_VSUMSWS_DIRECT:
case UNSPEC_VSX_CONCAT:
+ case UNSPEC_VSX_CVDPSPN:
+ case UNSPEC_VSX_CVSPDP:
+ case UNSPEC_VSX_CVSPDPN:
+ case UNSPEC_VSX_EXTRACT:
case UNSPEC_VSX_SET:
case UNSPEC_VSX_SLDWI:
+ case UNSPEC_VSX_VEC_INIT:
+ case UNSPEC_VSX_VSLO:
case UNSPEC_VUNPACK_HI_SIGN:
case UNSPEC_VUNPACK_HI_SIGN_DIRECT:
case UNSPEC_VUNPACK_LO_SIGN:
@@ -774,12 +781,6 @@ rtx_is_swappable_p (rtx op, unsigned int *special)
case UNSPEC_VUPKLPX:
case UNSPEC_VUPKLS_V4SF:
case UNSPEC_VUPKLU_V4SF:
- case UNSPEC_VSX_CVDPSPN:
- case UNSPEC_VSX_CVSPDP:
- case UNSPEC_VSX_CVSPDPN:
- case UNSPEC_VSX_EXTRACT:
- case UNSPEC_VSX_VSLO:
- case UNSPEC_VSX_VEC_INIT:
return 0;
case UNSPEC_VSPLT_DIRECT:
case UNSPEC_VSX_XXSPLTD:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ff91f1e..6b3c743 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-01-26 Alan Modra <amodra@gmail.com>
+
+ PR target/84033
+ * gcc.target/powerpc/swaps-p8-46.c: New.
+
2018-25-01 Paul Thomas <pault@gcc.gnu.org>
PR fortran/37577
diff --git a/gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c b/gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c
new file mode 100644
index 0000000..23494b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/swaps-p8-46.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target { powerpc64le-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O2 " } */
+
+typedef __attribute__ ((__aligned__ (8))) unsigned long long __m64;
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
+
+/* PR84033. Extracted from xmmintrin.h but with a pointer param to
+ allow swaps to happen when not inline. */
+int __attribute__ ((__noinline__))
+_mm_movemask_ps (__m128 *__A)
+{
+ __vector __m64 result;
+ static const __vector unsigned int perm_mask =
+ {
+ 0x00204060, 0x80808080, 0x80808080, 0x80808080
+ };
+
+ result = (__vector __m64)
+ __builtin_vec_vbpermq ((__vector unsigned char) (*__A),
+ (__vector unsigned char) perm_mask);
+ return result[1];
+}
+
+int
+main (void)
+{
+ union { unsigned int i[4]; __m128 m; } x
+ = { 0x80000000, 0x80000000, 0x7fffffff, 0x7fffffff };
+ if (_mm_movemask_ps (&x.m) != 3)
+ __builtin_abort ();
+ return 0;
+}