Patchwork [rtl] combine concat+shuffle

login
register
mail settings
Submitter Marc Glisse
Date May 8, 2012, 4:32 p.m.
Message ID <alpine.DEB.2.02.1205081815260.3776@laptop-mg.saclay.inria.fr>
Download mbox | patch
Permalink /patch/157741/
State New
Headers show

Comments

Marc Glisse - May 8, 2012, 4:32 p.m.
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...
Richard Sandiford - May 8, 2012, 5:53 p.m.
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

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