diff mbox

[RTL] (vec_select (vec_concat a b) c) may be just a or b

Message ID alpine.DEB.2.02.1406212008520.18994@stedding.saclay.inria.fr
State New
Headers show

Commit Message

Marc Glisse June 21, 2014, 7:16 p.m. UTC
Hello,

this is another small simplification of RTL for vectors. Note that it 
doesn't really solve the problem, because these simplifications are only 
performed for single-use objects. If I start from vectors [a,b] and [c,d] 
and concatenate them into [a,b,c,d], then extract both halves, as in the 
original testcase in the PR, we won't notice that those are the original 
vectors. Still, better than nothing...

(we output a vzeroupper for the testcase, that seems unnecessary)

Bootstrap+testsuite on x86_64-linux-gnu.

2014-06-22  Marc Glisse  <marc.glisse@inria.fr>

 	PR target/44551
gcc/
 	* simplify-rtx.c (simplify_binary_operation_1) <VEC_SELECT>:
 	Optimize inverse of a VEC_CONCAT.
gcc/testsuite/
 	* gcc.target/i386/pr44551-1.c: New file.

Comments

Jeff Law July 17, 2014, 3:36 a.m. UTC | #1
On 06/21/14 13:16, Marc Glisse wrote:
> Hello,
>
> this is another small simplification of RTL for vectors. Note that it
> doesn't really solve the problem, because these simplifications are only
> performed for single-use objects. If I start from vectors [a,b] and
> [c,d] and concatenate them into [a,b,c,d], then extract both halves, as
> in the original testcase in the PR, we won't notice that those are the
> original vectors. Still, better than nothing...
>
> (we output a vzeroupper for the testcase, that seems unnecessary)
>
> Bootstrap+testsuite on x86_64-linux-gnu.
>
> 2014-06-22  Marc Glisse  <marc.glisse@inria.fr>
>
>      PR target/44551
> gcc/
>      * simplify-rtx.c (simplify_binary_operation_1) <VEC_SELECT>:
>      Optimize inverse of a VEC_CONCAT.
> gcc/testsuite/
>      * gcc.target/i386/pr44551-1.c: New file.
>
OK.

Jeff
diff mbox

Patch

Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c	(revision 211867)
+++ gcc/simplify-rtx.c	(working copy)
@@ -3359,20 +3359,64 @@  simplify_binary_operation_1 (enum rtx_co
 	      unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
 	      unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
 	      rtx subop0, subop1;
 
 	      gcc_assert (i0 < 2 && i1 < 2);
 	      subop0 = XEXP (trueop0, i0);
 	      subop1 = XEXP (trueop0, i1);
 
 	      return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
 	    }
+
+	  /* If we select one half of a vec_concat, return that.  */
+	  if (GET_CODE (trueop0) == VEC_CONCAT
+	      && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
+	    {
+	      rtx subop0 = XEXP (trueop0, 0);
+	      rtx subop1 = XEXP (trueop0, 1);
+	      enum machine_mode mode0 = GET_MODE (subop0);
+	      enum machine_mode mode1 = GET_MODE (subop1);
+	      int li = GET_MODE_SIZE (GET_MODE_INNER (mode0));
+	      int l0 = GET_MODE_SIZE (mode0) / li;
+	      int l1 = GET_MODE_SIZE (mode1) / li;
+	      int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
+	      if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
+		{
+		  bool success = true;
+		  for (int i = 1; i < l0; ++i)
+		    {
+		      rtx j = XVECEXP (trueop1, 0, i);
+		      if (!CONST_INT_P (j) || INTVAL (j) != i)
+			{
+			  success = false;
+			  break;
+			}
+		    }
+		  if (success)
+		    return subop0;
+		}
+	      if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
+		{
+		  bool success = true;
+		  for (int i = 1; i < l1; ++i)
+		    {
+		      rtx j = XVECEXP (trueop1, 0, i);
+		      if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
+			{
+			  success = false;
+			  break;
+			}
+		    }
+		  if (success)
+		    return subop1;
+		}
+	    }
 	}
 
       if (XVECLEN (trueop1, 0) == 1
 	  && CONST_INT_P (XVECEXP (trueop1, 0, 0))
 	  && GET_CODE (trueop0) == VEC_CONCAT)
 	{
 	  rtx vec = trueop0;
 	  int offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
 
 	  /* Try to find the element in the VEC_CONCAT.  */
Index: gcc/testsuite/gcc.target/i386/pr44551-1.c
===================================================================
--- gcc/testsuite/gcc.target/i386/pr44551-1.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr44551-1.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+
+#include <immintrin.h>
+
+__m128i
+foo (__m256i x, __m128i y)
+{
+  __m256i r = _mm256_insertf128_si256(x, y, 1);
+  __m128i a = _mm256_extractf128_si256(r, 1);
+  return a;
+}
+
+/* { dg-final { scan-assembler-not "vinsertf" } } */
+/* { dg-final { scan-assembler-not "vextractf" } } */