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]

[PATCH] Fix PR56157


This fixes PR56157 - when looking up operands for a vectorized
SLP stmt we have to match up SLP childs with operands.  We do
so by looking for the operand in the DEF position of the SLP
child.  But that get's complicated in face of either stmt being
a pattern stmt and its operands being DEFed by pattern stmts
(in case this is a multiple stmt pattern) or by the scalar
variant (of eventually another pattern the SLP child points to).

I ended up giving up trying to be clever and trying to handle all
situations with a single compare and just compare with pattern
and non-pattern def.  False matches are not possible, just we
must not miss a match.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok?

Thanks,
Richard.

2013-01-31  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/
	* tree-vect-slp.c (vect_get_slp_defs): More thoroughly try to
	match up operand with SLP child.

	* gcc.dg/torture/pr56157.c: New testcase.

Index: gcc/tree-vect-slp.c
===================================================================
*** gcc/tree-vect-slp.c	(revision 195610)
--- gcc/tree-vect-slp.c	(working copy)
*************** void
*** 2616,2628 ****
  vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
                     vec<slp_void_p> *vec_oprnds, int reduc_index)
  {
!   gimple first_stmt, first_def;
    int number_of_vects = 0, i;
    unsigned int child_index = 0;
    HOST_WIDE_INT lhs_size_unit, rhs_size_unit;
    slp_tree child = NULL;
    vec<tree> *vec_defs;
!   tree oprnd, def_lhs;
    bool vectorized_defs;
  
    first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
--- 2616,2628 ----
  vect_get_slp_defs (vec<tree> ops, slp_tree slp_node,
                     vec<slp_void_p> *vec_oprnds, int reduc_index)
  {
!   gimple first_stmt;
    int number_of_vects = 0, i;
    unsigned int child_index = 0;
    HOST_WIDE_INT lhs_size_unit, rhs_size_unit;
    slp_tree child = NULL;
    vec<tree> *vec_defs;
!   tree oprnd;
    bool vectorized_defs;
  
    first_stmt = SLP_TREE_SCALAR_STMTS (slp_node)[0];
*************** vect_get_slp_defs (vec<tree> ops, slp_tr
*** 2638,2666 ****
        if (SLP_TREE_CHILDREN (slp_node).length () > child_index)
          {
            child = (slp_tree) SLP_TREE_CHILDREN (slp_node)[child_index];
-           first_def = SLP_TREE_SCALAR_STMTS (child)[0];
  
! 	  /* In the end of a pattern sequence we have a use of the original stmt,
! 	     so we need to compare OPRND with the original def.  */
!           if (is_pattern_stmt_p (vinfo_for_stmt (first_def))
! 	      && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (first_stmt))
!               && !is_pattern_stmt_p (vinfo_for_stmt (first_stmt)))
!             first_def = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def));
  
!           if (is_gimple_call (first_def))
!             def_lhs = gimple_call_lhs (first_def);
!           else
!             def_lhs = gimple_assign_lhs (first_def);
! 
!           if (operand_equal_p (oprnd, def_lhs, 0))
!             {
!               /* The number of vector defs is determined by the number of
!                  vector statements in the node from which we get those
  		 statements.  */
!                  number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child);
!                  vectorized_defs = true;
  	      child_index++;
!             }
          }
  
        if (!vectorized_defs)
--- 2638,2659 ----
        if (SLP_TREE_CHILDREN (slp_node).length () > child_index)
          {
            child = (slp_tree) SLP_TREE_CHILDREN (slp_node)[child_index];
  
! 	  /* We have to check both pattern and original def, if available.  */
! 	  gimple first_def = SLP_TREE_SCALAR_STMTS (child)[0];
! 	  gimple related = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (first_def));
  
! 	  if (operand_equal_p (oprnd, gimple_get_lhs (first_def), 0)
! 	      || (related
! 		  && operand_equal_p (oprnd, gimple_get_lhs (related), 0)))
! 	    {
! 	      /* The number of vector defs is determined by the number of
! 		 vector statements in the node from which we get those
  		 statements.  */
! 	      number_of_vects = SLP_TREE_NUMBER_OF_VEC_STMTS (child);
! 	      vectorized_defs = true;
  	      child_index++;
! 	    }
          }
  
        if (!vectorized_defs)
Index: gcc/testsuite/gcc.dg/torture/pr56157.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr56157.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr56157.c	(working copy)
***************
*** 0 ****
--- 1,25 ----
+ /* { dg-do compile } */
+ /* { dg-options "-ftree-vectorize" } */
+ 
+ struct Pixel {
+     unsigned short r;
+     unsigned short g;
+     unsigned short b;
+     unsigned short a;
+ };
+ 
+ void fn(unsigned char * __restrict dst, const unsigned char * __restrict src)
+ {
+   unsigned x;
+   for(x = 0; x < 1024; x += 1)
+     {
+       struct Pixel pixel;
+       pixel.r = (unsigned short)(((unsigned)src[0]) * 0xffff / 0xff);
+       pixel.g = (unsigned short)(((unsigned)src[1]) * 0xffff / 0xff);
+       pixel.b = (unsigned short)(((unsigned)src[2]) * 0xffff / 0xff);
+       pixel.a = (unsigned short)(((unsigned)src[3]) * 0xffff / 0xff);
+       __builtin_memcpy(dst, &pixel, sizeof pixel);
+       src += 4;
+       dst += 8;
+     }
+ }


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