Here is a new version.

gcc/ChangeLog
2012-05-08  Marc Glisse  <marc.gli...@inria.fr>

        * simplify-rtx.c (simplify_binary_operation_1): Optimize shuffle
        of concatenations.

gcc/testsuite/ChangeLog
2012-05-08  Marc Glisse  <marc.gli...@inria.fr>

        * gcc.target/i386/shuf-concat.c: New test.


On Tue, 8 May 2012, Richard Sandiford wrote:

Very minor, but this code probably belongs in the else part of the
if (!VECTOR_MODE_P (mode)) block.

I moved it in the block. Note that the piece of code right below, that starts with:

      if (XVECLEN (trueop1, 0) == 1
          && CONST_INT_P (XVECEXP (trueop1, 0, 0))
          && GET_CODE (trueop0) == VEC_CONCAT)

could probably move too. I had put mine right below because they do similar things. By the way, reusing that piece of code and applying it to each of the 2 selected parts of the vector would be one way to generalize my patch so it also applies to the vpermilpd case.

Note to self: if you want to grep for "shuf" in the asm, don't put "shuf" in the name of the file...

--
Marc Glisse
Index: testsuite/gcc.target/i386/shuf-concat.c
===================================================================
--- testsuite/gcc.target/i386/shuf-concat.c     (revision 0)
+++ testsuite/gcc.target/i386/shuf-concat.c     (revision 0)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+
+v2df f(double d,double e){
+  v2df x={-d,d};
+  v2df y={-e,e};
+  return __builtin_ia32_shufpd(x,y,1);
+}
+
+/* { dg-final { scan-assembler-not "shufpd" } } */
+/* { dg-final { scan-assembler-times "unpck" 1 } } */

Property changes on: testsuite/gcc.target/i386/shuf-concat.c
___________________________________________________________________
Added: svn:eol-style
   + native
Added: svn:keywords
   + Author Date Id Revision URL

Index: simplify-rtx.c
===================================================================
--- simplify-rtx.c      (revision 187276)
+++ simplify-rtx.c      (working copy)
@@ -1,10 +1,10 @@
 /* RTL simplification functions for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011  Free Software Foundation, Inc.
+   2011, 2012  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 Software Foundation; either version 3, or (at your option) any later
@@ -3239,12 +3239,33 @@ simplify_binary_operation_1 (enum rtx_co
                  RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
                                                       INTVAL (x));
                }
 
              return gen_rtx_CONST_VECTOR (mode, v);
            }
+
+         /* If we build {a,b} then permute it, build the result directly.  */
+         if (XVECLEN (trueop1, 0) == 2
+             && CONST_INT_P (XVECEXP (trueop1, 0, 0))
+             && CONST_INT_P (XVECEXP (trueop1, 0, 1))
+             && GET_CODE (trueop0) == VEC_CONCAT
+             && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
+             && GET_MODE (XEXP (trueop0, 0)) == mode
+             && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
+             && GET_MODE (XEXP (trueop0, 1)) == mode)
+           {
+             unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
+             unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
+             rtx subop0, subop1;
+
+             gcc_assert (i0 < 4 && i1 < 4);
+             subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
+             subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
+
+             return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
+           }
        }
 
       if (XVECLEN (trueop1, 0) == 1
          && CONST_INT_P (XVECEXP (trueop1, 0, 0))
          && GET_CODE (trueop0) == VEC_CONCAT)
        {

Reply via email to