This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Simplify a VEC_SELECT fed by its own inverse
- From: Bill Schmidt <wschmidt at linux dot vnet dot ibm dot com>
- To: Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org, ebotcazou at libertysurf dot fr, marc dot glisse at inria dot fr
- Date: Tue, 22 Apr 2014 10:30:13 -0500
- Subject: Re: [PATCH] Simplify a VEC_SELECT fed by its own inverse
- Authentication-results: sourceware.org; auth=none
- References: <1398088880 dot 19378 dot 28 dot camel at gnopaine> <alpine dot DEB dot 2 dot 10 dot 1404211826001 dot 3716 at laptop-mg dot saclay dot inria dot fr> <1398111582 dot 659 dot 3 dot camel at gnopaine> <5355842F dot 3070801 at redhat dot com>
Hi,
Below is the revised patch addressing Richard's concerns about the
assertions. Bootstrapped and tested on
powerpc64[,le]-unknown-linux-gnu. Ok for trunk?
Thanks,
Bill
[gcc]
2014-04-22 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-22 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);
+ if (!CONST_INT_P (x))
+ return 0;
+ rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
+ if (!CONST_INT_P (y) || 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;
+}
+