aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2014-07-26 11:00:31 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2014-07-26 09:00:31 +0000
commit82e3a7199574db824fc468831c6db6378fb7f87e (patch)
treee8b9693bc900f0d8aad8815a34289112f63059e5
parente39a6482962a81d206b36ac9c3881c380c8d5241 (diff)
downloadgcc-82e3a7199574db824fc468831c6db6378fb7f87e.zip
gcc-82e3a7199574db824fc468831c6db6378fb7f87e.tar.gz
gcc-82e3a7199574db824fc468831c6db6378fb7f87e.tar.bz2
re PR target/44551 ([missed optimization] AVX vextractf128 after vinsertf128)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/simplify-rtx.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr44551-1.c15
4 files changed, 70 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b2d5532..9013ce8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 07b9353..9f6dbe1 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1b842d8..f63bd99 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..b65c7bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr44551-1.c
@@ -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" } } */