This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[rtl] combine a vec_concat of 2 vec_selects from the same vector
- From: Marc Glisse <marc dot glisse at inria dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 9 Sep 2012 13:13:20 +0200 (CEST)
- Subject: [rtl] combine a vec_concat of 2 vec_selects from the same vector
Hello,
this patch lets the compiler try to rewrite:
(vec_concat (vec_select x [a]) (vec_select x [b]))
as:
vec_select x [a b]
or even just "x" if appropriate.
In a first iteration I was restricting it to b-a==1, but it seemed better
not to: it helps for {v[1],v[0]} and doesn't change anything for unknown
patterns.
Note that I am planning to do a similar optimization at tree level, but it
shouldn't make this one useless because such patterns can be created
during rtl passes. The testcase may need an additional -fno-tree-xxx to
still be useful at that point though.
bootstrap+testsuite on x86_64-linux-gnu.
2012-09-09 Marc Glisse <marc.glisse@inria.fr>
gcc/
* simplify-rtx.c (simplify_binary_operation_1): Handle vec_concat
of vec_selects from the same vector.
gcc/testsuite/
* gcc.target/i386/vect-rebuild.c: New testcase.
--
Marc Glisse
Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c (revision 191106)
+++ simplify-rtx.c (working copy)
@@ -3357,20 +3357,38 @@ simplify_binary_operation_1 (enum rtx_co
if (!VECTOR_MODE_P (op1_mode))
RTVEC_ELT (v, i) = trueop1;
else
RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
i - in_n_elts);
}
}
return gen_rtx_CONST_VECTOR (mode, v);
}
+
+ if (GET_CODE (trueop0) == VEC_SELECT
+ && GET_CODE (trueop1) == VEC_SELECT
+ && !VECTOR_MODE_P (op0_mode)
+ && !VECTOR_MODE_P (op1_mode)
+ && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0)))
+ {
+ if (GET_MODE (XEXP (trueop0, 0)) == mode
+ && INTVAL (XVECEXP (XEXP (trueop1, 1), 0, 0))
+ - INTVAL (XVECEXP (XEXP (trueop0, 1), 0, 0)) == 1)
+ return XEXP (trueop0, 0);
+
+ rtvec vec = rtvec_alloc (2);
+ RTVEC_ELT (vec, 0) = XVECEXP (XEXP (trueop0, 1), 0, 0);
+ RTVEC_ELT (vec, 1) = XVECEXP (XEXP (trueop1, 1), 0, 0);
+ return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
+ gen_rtx_PARALLEL (VOIDmode, vec));
+ }
}
return 0;
default:
gcc_unreachable ();
}
return 0;
}
Index: testsuite/gcc.target/i386/vect-rebuild.c
===================================================================
--- testsuite/gcc.target/i386/vect-rebuild.c (revision 0)
+++ testsuite/gcc.target/i386/vect-rebuild.c (revision 0)
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mavx" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+typedef double v4df __attribute__ ((__vector_size__ (32)));
+
+v2df f (v2df x)
+{
+ v2df xx = { x[0], x[1] };
+ return xx;
+}
+
+v2df g (v2df x)
+{
+ v2df xx = { x[1], x[0] };
+ return xx;
+}
+
+v2df h (v4df x)
+{
+ v2df xx = { x[2], x[3] };
+ return xx;
+}
+
+/* { dg-final { scan-assembler-not "unpck" } } */
+/* { dg-final { scan-assembler-times "\tv?permilpd\[ \t\]" 1 } } */
+/* { dg-final { scan-assembler-times "\tv?extractf128\[ \t\]" 1 } } */
Property changes on: testsuite/gcc.target/i386/vect-rebuild.c
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision URL
Added: svn:eol-style
+ native