diff mbox

[rs6000,4.8] Fix V2DI/V2DF load/extract logic for LE

Message ID 1427378427.2939.16.camel@gnopaine
State New
Headers show

Commit Message

Bill Schmidt March 26, 2015, 2 p.m. UTC
Hi,

While working on a backport, I discovered a bug that only exists in the
4.8 branch (the buggy code was rewritten with the direct move additions
in 4.9).  A load-and-extract of the first doubleword in memory can
always be done with the lxsd[u]x instruction.  In 4.8 I wrongly added
code to use this to load the second doubleword instead for
little-endian.  This is wrong because the order of array elements in
memory remains the same for both endiannesses (versus in registers where
they differ).  Unfortunately the existing test case didn't exercise this
properly, so the bug was missed.  This patch corrects the bug and
expands the test case to cover this case.

Tested on powerpc64le-unknown-linux-gnu with no regressions.  Ok for
4.8?

Thanks,
Bill


[gcc]

2015-03-26  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* config/rs6000/vsx.md (*vsx_extract_<mode>_zero): Remove
	endianness requirement.
	(*vsx_extract_<mode>_one_le): Remove define_insn.


[gcc/testsuite]

2015-03-26  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* gcc.dg/vmx/extract-vsx.c: Add more cases.

Comments

David Edelsohn March 26, 2015, 2:01 p.m. UTC | #1
On Thu, Mar 26, 2015 at 10:00 AM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Hi,
>
> While working on a backport, I discovered a bug that only exists in the
> 4.8 branch (the buggy code was rewritten with the direct move additions
> in 4.9).  A load-and-extract of the first doubleword in memory can
> always be done with the lxsd[u]x instruction.  In 4.8 I wrongly added
> code to use this to load the second doubleword instead for
> little-endian.  This is wrong because the order of array elements in
> memory remains the same for both endiannesses (versus in registers where
> they differ).  Unfortunately the existing test case didn't exercise this
> properly, so the bug was missed.  This patch corrects the bug and
> expands the test case to cover this case.
>
> Tested on powerpc64le-unknown-linux-gnu with no regressions.  Ok for
> 4.8?
>
> Thanks,
> Bill
>
>
> [gcc]
>
> 2015-03-26  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>
>         * config/rs6000/vsx.md (*vsx_extract_<mode>_zero): Remove
>         endianness requirement.
>         (*vsx_extract_<mode>_one_le): Remove define_insn.
>
>
> [gcc/testsuite]
>
> 2015-03-26  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>
>         * gcc.dg/vmx/extract-vsx.c: Add more cases.

Okay.

Thanks, David
diff mbox

Patch

Index: gcc/config/rs6000/vsx.md
===================================================================
--- gcc/config/rs6000/vsx.md	(revision 221668)
+++ gcc/config/rs6000/vsx.md	(working copy)
@@ -1781,7 +1781,7 @@ 
 	(vec_select:<VS_scalar>
 	 (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z")
 	 (parallel [(const_int 0)])))]
-  "VECTOR_MEM_VSX_P (<MODE>mode) && WORDS_BIG_ENDIAN"
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
   "lxsd%U1x %x0,%y1"
   [(set (attr "type")
       (if_then_else
@@ -1790,21 +1790,6 @@ 
 	(const_string "fpload")))
    (set_attr "length" "4")])  
 
-;; Optimize extracting element 1 from memory for little endian
-(define_insn "*vsx_extract_<mode>_one_le"
-  [(set (match_operand:<VS_scalar> 0 "vsx_register_operand" "=ws,d,?wa")
-	(vec_select:<VS_scalar>
-	 (match_operand:VSX_D 1 "indexed_or_indirect_operand" "Z,Z,Z")
-	 (parallel [(const_int 1)])))]
-  "VECTOR_MEM_VSX_P (<MODE>mode) && !WORDS_BIG_ENDIAN"
-  "lxsd%U1x %x0,%y1"
-  [(set (attr "type")
-      (if_then_else
-	(match_test "update_indexed_address_mem (operands[1], VOIDmode)")
-	(const_string "fpload_ux")
-	(const_string "fpload")))
-   (set_attr "length" "4")])  
-
 ;; Extract a SF element from V4SF
 (define_insn_and_split "vsx_extract_v4sf"
   [(set (match_operand:SF 0 "vsx_register_operand" "=f,f")
Index: gcc/testsuite/gcc.dg/vmx/extract-vsx.c
===================================================================
--- gcc/testsuite/gcc.dg/vmx/extract-vsx.c	(revision 221668)
+++ gcc/testsuite/gcc.dg/vmx/extract-vsx.c	(working copy)
@@ -10,7 +10,11 @@  static void test()
   vector double vd = {0.0, 1.0};
 
   check (vec_extract (vl, 0) == 0, "vec_extract, vl, 0");
+  check (vec_extract (vl, 1) == 1, "vec_extract, vl, 1");
+  check (vec_extract (vd, 0) == 0.0, "vec_extract, vd, 0");
   check (vec_extract (vd, 1) == 1.0, "vec_extract, vd, 1");
   check (vl[0] == 0, "[], vl, 0");
-  check (vd[1] == 1.0, "[], vd, 0");
+  check (vl[1] == 1, "[], vl, 1");
+  check (vd[0] == 0.0, "[], vd, 0");
+  check (vd[1] == 1.0, "[], vd, 1");
 }