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

Reply via email to