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.gli...@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