This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[rtl] combine a vec_concat of 2 vec_selects from the same vector


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.glisse@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]