]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR target/44551 ([missed optimization] AVX vextractf128 after vinsertf128)
authorMarc Glisse <marc.glisse@inria.fr>
Sat, 26 Jul 2014 09:00:31 +0000 (11:00 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Sat, 26 Jul 2014 09:00:31 +0000 (09:00 +0000)
2014-07-26  Marc Glisse  <marc.glisse@inria.fr>

PR target/44551
gcc/
* simplify-rtx.c (simplify_binary_operation_1) <VEC_SELECT>:
Optimize inverse of a VEC_CONCAT.
gcc/testsuite/
* gcc.target/i386/pr44551-1.c: New file.

From-SVN: r213076

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr44551-1.c [new file with mode: 0644]

index b2d5532cb58f1b79ded6ba7f275fea38473814c0..9013ce80c615d18fdb78018d4a92a888da7089e1 100644 (file)
@@ -1,3 +1,9 @@
+2014-07-26  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR target/44551
+       * simplify-rtx.c (simplify_binary_operation_1) <VEC_SELECT>:
+       Optimize inverse of a VEC_CONCAT.
+
 2014-07-25  Xinliang David Li  <davidxl@google.com>
 
        * params.def: New parameter.
index 07b93538969036b0c55e570b801e37c54a07f0a9..9f6dbe119c67416f7fadfe533b5af646873b8c5e 100644 (file)
@@ -3368,6 +3368,50 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
 
              return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
            }
+
+         /* If we select one half of a vec_concat, return that.  */
+         if (GET_CODE (trueop0) == VEC_CONCAT
+             && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
+           {
+             rtx subop0 = XEXP (trueop0, 0);
+             rtx subop1 = XEXP (trueop0, 1);
+             enum machine_mode mode0 = GET_MODE (subop0);
+             enum machine_mode mode1 = GET_MODE (subop1);
+             int li = GET_MODE_SIZE (GET_MODE_INNER (mode0));
+             int l0 = GET_MODE_SIZE (mode0) / li;
+             int l1 = GET_MODE_SIZE (mode1) / li;
+             int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
+             if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
+               {
+                 bool success = true;
+                 for (int i = 1; i < l0; ++i)
+                   {
+                     rtx j = XVECEXP (trueop1, 0, i);
+                     if (!CONST_INT_P (j) || INTVAL (j) != i)
+                       {
+                         success = false;
+                         break;
+                       }
+                   }
+                 if (success)
+                   return subop0;
+               }
+             if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
+               {
+                 bool success = true;
+                 for (int i = 1; i < l1; ++i)
+                   {
+                     rtx j = XVECEXP (trueop1, 0, i);
+                     if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
+                       {
+                         success = false;
+                         break;
+                       }
+                   }
+                 if (success)
+                   return subop1;
+               }
+           }
        }
 
       if (XVECLEN (trueop1, 0) == 1
index 1b842d8bbf37a9114058a8aa962d3692f5b251a3..f63bd99a7bf054f2b93581b7af9fa0eef2fde8e7 100644 (file)
@@ -1,3 +1,8 @@
+2014-07-26  Marc Glisse  <marc.glisse@inria.fr>
+
+       PR target/44551
+       * gcc.target/i386/pr44551-1.c: New file.
+
 2014-07-25  Xinliang David Li  <davidxl@google.com>
 
        * g++.dg/tree-prof/tree-prof.exp: Define macros.
diff --git a/gcc/testsuite/gcc.target/i386/pr44551-1.c b/gcc/testsuite/gcc.target/i386/pr44551-1.c
new file mode 100644 (file)
index 0000000..b65c7bb
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+#include <immintrin.h>
+
+__m128i
+foo (__m256i x, __m128i y)
+{
+  __m256i r = _mm256_insertf128_si256(x, y, 1);
+  __m128i a = _mm256_extractf128_si256(r, 1);
+  return a;
+}
+
+/* { dg-final { scan-assembler-not "vinsertf" } } */
+/* { dg-final { scan-assembler-not "vextractf" } } */