This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Simplify a VEC_SELECT fed by its own inverse


Hi,

Here's a revised patch in response to Marc's comments.  Again,
bootstrapped and tested on powerpc64[,le]-unknown-linux-gnu.  Is this ok
for trunk?

Thanks,
Bill


[gcc]

2014-04-21  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* simplify-rtx.c (simplify_binary_operation_1): Optimize case of
	nested VEC_SELECTs that are inverses of each other.

[gcc/testsuite]

2014-04-21  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

	* gcc.target/powerpc/vsxcopy.c: New test.


Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	(revision 209516)
+++ gcc/simplify-rtx.c	(working copy)
@@ -3673,6 +3673,31 @@ simplify_binary_operation_1 (enum rtx_code code, e
 	    }
 	}
 
+      /* If we have two nested selects that are inverses of each
+	 other, replace them with the source operand.  */
+      if (GET_CODE (trueop0) == VEC_SELECT
+	  && GET_MODE (XEXP (trueop0, 0)) == mode)
+	{
+	  rtx op0_subop1 = XEXP (trueop0, 1);
+	  gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
+	  gcc_assert (XVECLEN (trueop1, 0) == GET_MODE_NUNITS (mode));
+
+	  /* Apply the outer ordering vector to the inner one.  (The inner
+	     ordering vector is expressly permitted to be of a different
+	     length than the outer one.)  If the result is { 0, 1, ..., n-1 }
+	     then the two VEC_SELECTs cancel.  */
+	  for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
+	    {
+	      rtx x = XVECEXP (trueop1, 0, i);
+	      gcc_assert (CONST_INT_P (x));
+	      rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
+	      gcc_assert (CONST_INT_P (y));
+	      if (i != INTVAL (y))
+		return 0;
+	    }
+	  return XEXP (trueop0, 0);
+	}
+
       return 0;
     case VEC_CONCAT:
       {
Index: gcc/testsuite/gcc.target/powerpc/vsxcopy.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/vsxcopy.c	(revision 0)
+++ gcc/testsuite/gcc.target/powerpc/vsxcopy.c	(working copy)
@@ -0,0 +1,15 @@
+/* { dg-do compile { target { powerpc64*-*-* } } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O1" } */
+/* { dg-final { scan-assembler "lxvd2x" } } */
+/* { dg-final { scan-assembler "stxvd2x" } } */
+/* { dg-final { scan-assembler-not "xxpermdi" } } */
+
+typedef float vecf __attribute__ ((vector_size (16)));
+extern vecf j, k;
+
+void fun (void)
+{
+  j = k;
+}
+



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]