[committed] Recognize more SIMD lane access patterns

Jakub Jelinek jakub@redhat.com
Fri Jun 21 21:38:00 GMT 2019


Hi!

The following testcases weren't vectorized, because the simd lane accesses
weren't recognized there.
Usually SIMD lane accesses look like:
  _22 = .GOMP_SIMD_LANE (simduid.0_14(D), ??);
...
  MEM <struct S[16]> [(struct S *)&D.2456][_22].s = _25;
but on these two testcases we ended up with:
  _18 = .GOMP_SIMD_LANE (simduid.0_14(D), ??);
...
  _11 = (sizetype) _18;
  _9 = _11 * 4;
  _28 = &D.2456 + _9;
  _32 = MEM[(int *)_28];
which nothing folded.  create_data_ref in this case sets DR_BASE_ADDRESS
to POINTER_PLUS_EXPR of &D.2456 and _11 * 4, while the code in
vect_find_stmt_data_reference expected that _11 * 4 to be in DR_OFFSET
instead; furthermore there is the unsigned int -> sizetype promotion
that wasn't recognized either, but it is just fine too.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
committed to trunk.

2019-06-21  Jakub Jelinek  <jakub@redhat.com>

	* tree-vect-data-refs.c (vect_find_stmt_data_reference): Handle
	even zero DR_OFFSET, but DR_BASE_ADDRESS of POINTER_PLUS_EXPR
	containing the offset as possible simd lane access.  Look through
	widening conversion.  Move the
	TREE_CODE (DR_INIT (newdr)) == INTEGER_CST test earlier and reindent.

	* g++.dg/vect/simd-2.cc: Don't xfail, instead expect vectorization on
	x86.
	* g++.dg/vect/simd-5.cc: Likewise.

--- gcc/tree-vect-data-refs.c.jj	2019-06-21 08:47:04.171673314 +0200
+++ gcc/tree-vect-data-refs.c	2019-06-21 21:03:15.592941224 +0200
@@ -4072,10 +4072,18 @@ vect_find_stmt_data_reference (loop_p lo
 	  && DR_OFFSET (newdr)
 	  && DR_INIT (newdr)
 	  && DR_STEP (newdr)
+	  && TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
 	  && integer_zerop (DR_STEP (newdr)))
 	{
+	  tree base_address = DR_BASE_ADDRESS (newdr);
 	  tree off = DR_OFFSET (newdr);
 	  tree step = ssize_int (1);
+	  if (integer_zerop (off)
+	      && TREE_CODE (base_address) == POINTER_PLUS_EXPR)
+	    {
+	      off = TREE_OPERAND (base_address, 1);
+	      base_address = TREE_OPERAND (base_address, 0);
+	    }
 	  STRIP_NOPS (off);
 	  if (TREE_CODE (off) == MULT_EXPR
 	      && tree_fits_uhwi_p (TREE_OPERAND (off, 1)))
@@ -4084,39 +4092,47 @@ vect_find_stmt_data_reference (loop_p lo
 	      off = TREE_OPERAND (off, 0);
 	      STRIP_NOPS (off);
 	    }
-	  if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST)
+	  if (CONVERT_EXPR_P (off)
+	      && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off, 0)))
+		  < TYPE_PRECISION (TREE_TYPE (off))))
+	    off = TREE_OPERAND (off, 0);
+	  if (TREE_CODE (off) == SSA_NAME)
 	    {
-	      if (CONVERT_EXPR_P (off)
-		  && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off, 0)))
-		      < TYPE_PRECISION (TREE_TYPE (off))))
-		off = TREE_OPERAND (off, 0);
-	      if (TREE_CODE (off) == SSA_NAME)
+	      gimple *def = SSA_NAME_DEF_STMT (off);
+	      /* Look through widening conversion.  */
+	      if (is_gimple_assign (def)
+		  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
+		{
+		  tree rhs1 = gimple_assign_rhs1 (def);
+		  if (TREE_CODE (rhs1) == SSA_NAME
+		      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+		      && (TYPE_PRECISION (TREE_TYPE (off))
+			  > TYPE_PRECISION (TREE_TYPE (rhs1))))
+		    def = SSA_NAME_DEF_STMT (rhs1);
+		}
+	      if (is_gimple_call (def)
+		  && gimple_call_internal_p (def)
+		  && (gimple_call_internal_fn (def) == IFN_GOMP_SIMD_LANE))
 		{
-		  gimple *def = SSA_NAME_DEF_STMT (off);
+		  tree arg = gimple_call_arg (def, 0);
 		  tree reft = TREE_TYPE (DR_REF (newdr));
-		  if (is_gimple_call (def)
-		      && gimple_call_internal_p (def)
-		      && (gimple_call_internal_fn (def) == IFN_GOMP_SIMD_LANE))
+		  gcc_assert (TREE_CODE (arg) == SSA_NAME);
+		  arg = SSA_NAME_VAR (arg);
+		  if (arg == loop->simduid
+		      /* For now.  */
+		      && tree_int_cst_equal (TYPE_SIZE_UNIT (reft), step))
 		    {
-		      tree arg = gimple_call_arg (def, 0);
-		      gcc_assert (TREE_CODE (arg) == SSA_NAME);
-		      arg = SSA_NAME_VAR (arg);
-		      if (arg == loop->simduid
-			  /* For now.  */
-			  && tree_int_cst_equal (TYPE_SIZE_UNIT (reft), step))
-			{
-			  DR_OFFSET (newdr) = ssize_int (0);
-			  DR_STEP (newdr) = step;
-			  DR_OFFSET_ALIGNMENT (newdr) = BIGGEST_ALIGNMENT;
-			  DR_STEP_ALIGNMENT (newdr)
-			    = highest_pow2_factor (step);
-			  /* Mark as simd-lane access.  */
-			  tree arg2 = gimple_call_arg (def, 1);
-			  newdr->aux = (void *) (-1 - tree_to_uhwi (arg2));
-			  free_data_ref (dr);
-			  datarefs->safe_push (newdr);
-			  return opt_result::success ();
-			}
+		      DR_BASE_ADDRESS (newdr) = base_address;
+		      DR_OFFSET (newdr) = ssize_int (0);
+		      DR_STEP (newdr) = step;
+		      DR_OFFSET_ALIGNMENT (newdr) = BIGGEST_ALIGNMENT;
+		      DR_STEP_ALIGNMENT (newdr) = highest_pow2_factor (step);
+		      /* Mark as simd-lane access.  */
+		      tree arg2 = gimple_call_arg (def, 1);
+		      newdr->aux = (void *) (-1 - tree_to_uhwi (arg2));
+		      free_data_ref (dr);
+		      datarefs->safe_push (newdr);
+		      return opt_result::success ();
 		    }
 		}
 	    }
--- gcc/testsuite/g++.dg/vect/simd-2.cc.jj	2019-06-17 23:18:53.621850057 +0200
+++ gcc/testsuite/g++.dg/vect/simd-2.cc	2019-06-21 21:05:47.290572866 +0200
@@ -1,7 +1,7 @@
 // { dg-require-effective-target size32plus }
 // { dg-additional-options "-fopenmp-simd" }
 // { dg-additional-options "-mavx" { target avx_runtime } }
-// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
 
 #include "../../gcc.dg/vect/tree-vect.h"
 
--- gcc/testsuite/g++.dg/vect/simd-5.cc.jj	2019-06-19 10:25:08.423001090 +0200
+++ gcc/testsuite/g++.dg/vect/simd-5.cc	2019-06-21 21:06:00.755362646 +0200
@@ -1,7 +1,7 @@
 // { dg-require-effective-target size32plus }
 // { dg-additional-options "-fopenmp-simd" }
 // { dg-additional-options "-mavx" { target avx_runtime } }
-// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
 
 #include "../../gcc.dg/vect/tree-vect.h"
 

	Jakub



More information about the Gcc-patches mailing list