simplify-rtx.c (simplify_binary_operation_1): Optimize shuffle of concatenations.
authorMarc Glisse <marc.glisse@inria.fr>
Wed, 30 May 2012 10:48:06 +0000 (12:48 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Wed, 30 May 2012 10:48:06 +0000 (10:48 +0000)
2012-05-30  Marc Glisse  <marc.glisse@inria.fr>

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

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

From-SVN: r188006

gcc/ChangeLog
gcc/simplify-rtx.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/shuf-concat.c [new file with mode: 0644]

index 6c59322e7d7fc394a3d233cbd96c748a23fea856..f19ac409607f235e2e4f7532cad4ed2813e69260 100644 (file)
@@ -1,3 +1,8 @@
+2012-05-30  Marc Glisse  <marc.glisse@inria.fr>
+
+       * simplify-rtx.c (simplify_binary_operation_1): Optimize shuffle of
+       concatenations.
+
 2012-05-30  Richard Guenther  <rguenther@suse.de>
 
        PR middle-end/53522
index 6b0d56ed3ea480c2c8417b87adccb588426ddce3..6b645fe027cd2badf5630c516d98b1f1cc6523c8 100644 (file)
@@ -1,7 +1,7 @@
 /* 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.
 
@@ -3242,6 +3242,27 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
 
              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
index 2f42a8e671e98508637df4938fa9006e065a59e3..b36bc06a25c0cab44087aafbdcd24ab1a7e51e1e 100644 (file)
@@ -1,3 +1,7 @@
+2012-05-30  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.target/i386/shuf-concat.c: New test.
+
 2012-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/53519
diff --git a/gcc/testsuite/gcc.target/i386/shuf-concat.c b/gcc/testsuite/gcc.target/i386/shuf-concat.c
new file mode 100644 (file)
index 0000000..04ed4a9
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msse2 -mfpmath=sse" } */
+
+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 "\tv?shufpd\[ \t\]" } } */
+/* { dg-final { scan-assembler-times "\tv?unpcklpd\[ \t\]" 1 } } */