]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
simplify-rtx.c (simplify_binary_operation_1): Optimize case of nested VEC_SELECTs...
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Tue, 20 May 2014 14:14:21 +0000 (14:14 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Tue, 20 May 2014 14:14:21 +0000 (14:14 +0000)
[gcc]

2014-05-20  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-05-20  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

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

From-SVN: r210644

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/vsxcopy.c [new file with mode: 0644]

index f0aecbd07df4812fc1bf598384b669dca5c75fe0..7d518b8abcee1efe306c790b9320253416392f56 100644 (file)
@@ -1,3 +1,8 @@
+2014-05-20  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.
+
 2014-05-20  Richard Biener  <rguenther@suse.de>
 
        * tree-ssa-sccvn.c (process_scc): Dump SCC here, when
index 27e04f53439f572abc312bbdb1e8965c7fe1adef..181b56fb8c002b85fcdc528c2ff2f39d09c18878 100644 (file)
@@ -3419,6 +3419,31 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
            }
        }
 
+      /* 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 95ceb3927cae19497106c6f7cfd158229ca2d6e5..1440e049912c905033ba63d7b5abb0b314a5547f 100644 (file)
@@ -1,3 +1,7 @@
+2014-05-20  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       * gcc.target/powerpc/vsxcopy.c: New test.
+
 2014-05-20  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58664
diff --git a/gcc/testsuite/gcc.target/powerpc/vsxcopy.c b/gcc/testsuite/gcc.target/powerpc/vsxcopy.c
new file mode 100644 (file)
index 0000000..fc1f0bd
--- /dev/null
@@ -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;
+}
+