diff mbox

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

Message ID 1397790406.7170.8.camel@gnopaine
State New
Headers show

Commit Message

Bill Schmidt April 18, 2014, 3:06 a.m. UTC
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  <wschmidt@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  <wschmidt@linux.vnet.ibm.com>

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

Comments

David Edelsohn April 18, 2014, 1:16 p.m. UTC | #1
On Thu, Apr 17, 2014 at 11:06 PM, Bill Schmidt
<wschmidt@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  <wschmidt@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  <wschmidt@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
diff mbox

Patch

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 (<MODE>mode)"
-  "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 (<MODE>mode)"
-  "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 = {-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.  */
   vector long long vlrh = {-2,0};
@@ -31,14 +40,32 @@  static void test()
   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};
 
   vlh = vec_mergeh (vla, vlb);
   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");
 }