Re: [PATCH, rs6000, 4.8, 4.9, trunk] Fix little endian behavior of vec_merge[hl] for V4SI/V4SF with VSX

2014-04-18 Thread David Edelsohn
On Thu, Apr 17, 2014 at 11:06 PM, Bill Schmidt
wschm...@linux.vnet.ibm.com wrote:
 Hi,

 I missed a case in the vector API work for little endian.  When VSX is
 enabled, the vec_mergeh and vec_mergel interfaces for 4x32 vectors are
 translated into xxmrghw and xxmrglw.  The patterns for these were not
 adjusted for little endian.  This patch fixes this and adds tests for
 V4SI and V4SF modes when VSX is available.

 Bootstrapped and tested on 4.8, 4.9, and trunk for
 powerpc64le-unknown-linux-gnu with no regressions.  Tests are still
 ongoing for powerpc64-unknown-linux-gnu.  Provided those complete
 without regressions, is this fix ok for trunk, 4.9, and 4.8?

 Thanks,
 Bill


 [gcc]

 2014-04-17  Bill Schmidt  wschm...@linux.vnet.ibm.com

 * config/rs6000/vsx.md (vsx_xxmrghw_mode): Adjust for
 little-endian.
 (vsx_xxmrglw_mode): Likewise.

 [gcc/testsuite]

 2014-04-17  Bill Schmidt  wschm...@linux.vnet.ibm.com

 * gcc.dg/vmx/merge-vsx.c: Add V4SI and V4SF tests.
 * gcc.dg/vmx/merge-vsx-be-order.c: Likewise.

This is okay for trunk, 4.9.1 and 4.8.3.  Note that the 4.9 branch is
frozen at the moment.

Thanks, David


[PATCH, rs6000, 4.8, 4.9, trunk] Fix little endian behavior of vec_merge[hl] for V4SI/V4SF with VSX

2014-04-17 Thread Bill Schmidt
Hi,

I missed a case in the vector API work for little endian.  When VSX is
enabled, the vec_mergeh and vec_mergel interfaces for 4x32 vectors are
translated into xxmrghw and xxmrglw.  The patterns for these were not
adjusted for little endian.  This patch fixes this and adds tests for
V4SI and V4SF modes when VSX is available.

Bootstrapped and tested on 4.8, 4.9, and trunk for
powerpc64le-unknown-linux-gnu with no regressions.  Tests are still
ongoing for powerpc64-unknown-linux-gnu.  Provided those complete
without regressions, is this fix ok for trunk, 4.9, and 4.8?

Thanks,
Bill


[gcc]

2014-04-17  Bill Schmidt  wschm...@linux.vnet.ibm.com

* config/rs6000/vsx.md (vsx_xxmrghw_mode): Adjust for
little-endian.
(vsx_xxmrglw_mode): Likewise.

[gcc/testsuite]

2014-04-17  Bill Schmidt  wschm...@linux.vnet.ibm.com

* gcc.dg/vmx/merge-vsx.c: Add V4SI and V4SF tests.
* gcc.dg/vmx/merge-vsx-be-order.c: Likewise.


Index: gcc/config/rs6000/vsx.md
===
--- gcc/config/rs6000/vsx.md(revision 209513)
+++ gcc/config/rs6000/vsx.md(working copy)
@@ -1891,7 +1891,12 @@
  (parallel [(const_int 0) (const_int 4)
 (const_int 1) (const_int 5)])))]
   VECTOR_MEM_VSX_P (MODEmode)
-  xxmrghw %x0,%x1,%x2
+{
+  if (BYTES_BIG_ENDIAN)
+return xxmrghw %x0,%x1,%x2;
+  else
+return xxmrglw %x0,%x2,%x1;
+}
   [(set_attr type vecperm)])
 
 (define_insn vsx_xxmrglw_mode
@@ -1903,7 +1908,12 @@
  (parallel [(const_int 2) (const_int 6)
 (const_int 3) (const_int 7)])))]
   VECTOR_MEM_VSX_P (MODEmode)
-  xxmrglw %x0,%x1,%x2
+{
+  if (BYTES_BIG_ENDIAN)
+return xxmrglw %x0,%x1,%x2;
+  else
+return xxmrghw %x0,%x2,%x1;
+}
   [(set_attr type vecperm)])
 
 ;; Shift left double by word immediate
Index: gcc/testsuite/gcc.dg/vmx/merge-vsx-be-order.c
===
--- gcc/testsuite/gcc.dg/vmx/merge-vsx-be-order.c   (revision 209513)
+++ gcc/testsuite/gcc.dg/vmx/merge-vsx-be-order.c   (working copy)
@@ -21,10 +21,19 @@ static void test()
   vector long long vlb = {0,1};
   vector double vda = {-2.0,-1.0};
   vector double vdb = {0.0,1.0};
+  vector unsigned int vuia = {0,1,2,3};
+  vector unsigned int vuib = {4,5,6,7};
+  vector signed int vsia = {-4,-3,-2,-1};
+  vector signed int vsib = {0,1,2,3};
+  vector float vfa = {-4.0,-3.0,-2.0,-1.0};
+  vector float vfb = {0.0,1.0,2.0,3.0};
 
   /* Result vectors.  */
   vector long long vlh, vll;
   vector double vdh, vdl;
+  vector unsigned int vuih, vuil;
+  vector signed int vsih, vsil;
+  vector float vfh, vfl;
 
   /* Expected result vectors.  */
 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
@@ -32,11 +41,23 @@ static void test()
   vector long long vlrl = {0,-2};
   vector double vdrh = {1.0,-1.0};
   vector double vdrl = {0.0,-2.0};
+  vector unsigned int vuirh = {6,2,7,3};
+  vector unsigned int vuirl = {4,0,5,1};
+  vector signed int vsirh = {2,-2,3,-1};
+  vector signed int vsirl = {0,-4,1,-3};
+  vector float vfrh = {2.0,-2.0,3.0,-1.0};
+  vector float vfrl = {0.0,-4.0,1.0,-3.0};
 #else
   vector long long vlrh = {-2,0};
   vector long long vlrl = {-1,1};
   vector double vdrh = {-2.0,0.0};
   vector double vdrl = {-1.0,1.0};
+  vector unsigned int vuirh = {0,4,1,5};
+  vector unsigned int vuirl = {2,6,3,7};
+  vector signed int vsirh = {-4,0,-3,1};
+  vector signed int vsirl = {-2,2,-1,3};
+  vector float vfrh = {-4.0,0.0,-3.0,1.0};
+  vector float vfrl = {-2.0,2.0,-1.0,3.0};
 #endif
 
   vlh = vec_mergeh (vla, vlb);
@@ -43,9 +64,21 @@ static void test()
   vll = vec_mergel (vla, vlb);
   vdh = vec_mergeh (vda, vdb);
   vdl = vec_mergel (vda, vdb);
+  vuih = vec_mergeh (vuia, vuib);
+  vuil = vec_mergel (vuia, vuib);
+  vsih = vec_mergeh (vsia, vsib);
+  vsil = vec_mergel (vsia, vsib);
+  vfh  = vec_mergeh (vfa,  vfb );
+  vfl  = vec_mergel (vfa,  vfb );
 
   check (vec_long_long_eq (vlh, vlrh), vlh);
   check (vec_long_long_eq (vll, vlrl), vll);
   check (vec_double_eq (vdh, vdrh), vdh );
   check (vec_double_eq (vdl, vdrl), vdl );
+  check (vec_all_eq (vuih, vuirh), vuih);
+  check (vec_all_eq (vuil, vuirl), vuil);
+  check (vec_all_eq (vsih, vsirh), vsih);
+  check (vec_all_eq (vsil, vsirl), vsil);
+  check (vec_all_eq (vfh,  vfrh),  vfh);
+  check (vec_all_eq (vfl,  vfrl),  vfl);
 }
Index: gcc/testsuite/gcc.dg/vmx/merge-vsx.c
===
--- gcc/testsuite/gcc.dg/vmx/merge-vsx.c(revision 209513)
+++ gcc/testsuite/gcc.dg/vmx/merge-vsx.c(working copy)
@@ -21,10 +21,19 @@ static void test()
   vector long long vlb = {0,1};
   vector double vda = {-2.0,-1.0};
   vector double vdb = {0.0,1.0};
+  vector unsigned int vuia = {0,1,2,3};
+  vector unsigned int vuib = {4,5,6,7};
+  vector signed int vsia = {-4,-3,-2,-1};
+  vector signed int vsib = {0,1,2,3};
+  vector float vfa =