diff mbox

[rtl] combine concat+shuffle

Message ID alpine.DEB.2.02.1205081815260.3776@laptop-mg.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse May 8, 2012, 4:32 p.m. UTC
Here is a new version.

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

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

gcc/testsuite/ChangeLog
2012-05-08  Marc Glisse  <marc.glisse@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...

Comments

Richard Sandiford May 8, 2012, 5:53 p.m. UTC | #1
Marc Glisse <marc.glisse@inria.fr> writes:
> Here is a new version.
>
> gcc/ChangeLog
> 2012-05-08  Marc Glisse  <marc.glisse@inria.fr>
>
>  	* simplify-rtx.c (simplify_binary_operation_1): Optimize shuffle
>  	of concatenations.

OK, thanks.  I'll leave an x86 maintainer to review the testcase,
but it looks like it'll need some markup to ensure an SSE target.

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

Yeah :-)  For MIPS tests I tend to add "\t" to the beginning of the regexp.
(And to the end if possible.)

Richard
diff mbox

Patch

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)
 	{