[PATCH] Fix PR58137

Richard Biener rguenther@suse.de
Thu Sep 5 12:41:00 GMT 2013


This makes the vectorizer no longer produce vector types with
pointer components as it doesn't properly use POINTER_PLUS_EXPR
which then confuses other passes dealing with vectors in a generic way.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Sitting back and waiting for the fireworks.

Richard.

2013-09-05  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/58137
	* tree-vect-stmts.c (get_vectype_for_scalar_type_and_size):
	Do not create vectors of pointers.
	* tree-vect-loop.c (get_initial_def_for_induction): Use proper
	types for the components of the vector initializer.
	* tree-cfg.c (verify_gimple_assign_binary): Remove special-casing
	allowing pointer vectors with PLUS_EXPR/MINUS_EXPR.

	* gcc.target/i386/pr58137.c: New testcase.

Index: gcc/tree-vect-loop.c
===================================================================
*** gcc/tree-vect-loop.c	(revision 202273)
--- gcc/tree-vect-loop.c	(working copy)
*************** get_initial_def_for_induction (gimple iv
*** 3133,3139 ****
    stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
    loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
    struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-   tree scalar_type;
    tree vectype;
    int nunits;
    edge pe = loop_preheader_edge (loop);
--- 3133,3138 ----
*************** get_initial_def_for_induction (gimple iv
*** 3185,3192 ****
    gcc_assert (ok);
    pe = loop_preheader_edge (iv_loop);
  
!   scalar_type = TREE_TYPE (init_expr);
!   vectype = get_vectype_for_scalar_type (scalar_type);
    resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi)));
    gcc_assert (vectype);
    nunits = TYPE_VECTOR_SUBPARTS (vectype);
--- 3184,3190 ----
    gcc_assert (ok);
    pe = loop_preheader_edge (iv_loop);
  
!   vectype = get_vectype_for_scalar_type (TREE_TYPE (init_expr));
    resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi)));
    gcc_assert (vectype);
    nunits = TYPE_VECTOR_SUBPARTS (vectype);
*************** get_initial_def_for_induction (gimple iv
*** 3229,3236 ****
  
        /* iv_loop is the loop to be vectorized. Create:
  	 vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr)  */
!       new_var = vect_get_new_vect_var (scalar_type, vect_scalar_var, "var_");
!       new_name = force_gimple_operand (init_expr, &stmts, false, new_var);
        if (stmts)
  	{
  	  new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
--- 3227,3237 ----
  
        /* iv_loop is the loop to be vectorized. Create:
  	 vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr)  */
!       new_var = vect_get_new_vect_var (TREE_TYPE (vectype),
! 				       vect_scalar_var, "var_");
!       new_name = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
! 						     init_expr),
! 				       &stmts, false, new_var);
        if (stmts)
  	{
  	  new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
*************** get_initial_def_for_induction (gimple iv
*** 3243,3251 ****
        for (i = 1; i < nunits; i++)
  	{
  	  /* Create: new_name_i = new_name + step_expr  */
! 	  enum tree_code code = POINTER_TYPE_P (scalar_type)
! 				? POINTER_PLUS_EXPR : PLUS_EXPR;
! 	  new_name = fold_build2 (code, scalar_type, new_name, step_expr);
  	  if (!is_gimple_min_invariant (new_name))
  	    {
  	      init_stmt = gimple_build_assign (new_var, new_name);
--- 3244,3251 ----
        for (i = 1; i < nunits; i++)
  	{
  	  /* Create: new_name_i = new_name + step_expr  */
! 	  new_name = fold_build2 (PLUS_EXPR, TREE_TYPE (new_name),
! 				  new_name, step_expr);
  	  if (!is_gimple_min_invariant (new_name))
  	    {
  	      init_stmt = gimple_build_assign (new_var, new_name);
Index: gcc/tree-vect-stmts.c
===================================================================
*** gcc/tree-vect-stmts.c	(revision 202272)
--- gcc/tree-vect-stmts.c	(working copy)
*************** get_vectype_for_scalar_type_and_size (tr
*** 6203,6210 ****
       corresponding to that mode.  The theory is that any use that
       would cause problems with this will disable vectorization anyway.  */
    else if (!SCALAR_FLOAT_TYPE_P (scalar_type)
! 	   && !INTEGRAL_TYPE_P (scalar_type)
! 	   && !POINTER_TYPE_P (scalar_type))
      scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
  
    /* We can't build a vector type of elements with alignment bigger than
--- 6203,6209 ----
       corresponding to that mode.  The theory is that any use that
       would cause problems with this will disable vectorization anyway.  */
    else if (!SCALAR_FLOAT_TYPE_P (scalar_type)
! 	   && !INTEGRAL_TYPE_P (scalar_type))
      scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
  
    /* We can't build a vector type of elements with alignment bigger than
Index: gcc/testsuite/gcc.target/i386/pr58137.c
===================================================================
*** gcc/testsuite/gcc.target/i386/pr58137.c	(revision 0)
--- gcc/testsuite/gcc.target/i386/pr58137.c	(revision 0)
***************
*** 0 ****
--- 1,33 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O3 -mavx2" } */
+ 
+ typedef unsigned int U32;
+ 
+ struct sv {
+   void* sv_any;
+   U32 sv_refcnt;
+   U32 sv_flags;
+ };
+ typedef struct sv SV;
+ 
+ struct xrv {
+   SV * xrv_rv;
+ };
+ typedef struct xrv XRV;
+ 
+ extern XRV * PL_xrv_root;
+ 
+ void
+ more_xrv (void)
+ {
+   register XRV* xrv;
+   register XRV* xrvend;
+   xrv = PL_xrv_root;
+   xrvend = &xrv[200 / sizeof (XRV) - 1];
+   while (xrv < xrvend)
+   {
+     xrv->xrv_rv = (SV*)(xrv + 1);
+     xrv++;
+   }
+   xrv->xrv_rv = 0;
+ }
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 202272)
--- gcc/tree-cfg.c	(working copy)
*************** verify_gimple_assign_binary (gimple stmt
*** 3571,3581 ****
      case PLUS_EXPR:
      case MINUS_EXPR:
        {
! 	/* We use regular PLUS_EXPR and MINUS_EXPR for vectors.
! 	   ???  This just makes the checker happy and may not be what is
! 	   intended.  */
! 	if (TREE_CODE (lhs_type) == VECTOR_TYPE
! 	    && POINTER_TYPE_P (TREE_TYPE (lhs_type)))
  	  {
  	    if (TREE_CODE (rhs1_type) != VECTOR_TYPE
  		|| TREE_CODE (rhs2_type) != VECTOR_TYPE)
--- 3571,3580 ----
      case PLUS_EXPR:
      case MINUS_EXPR:
        {
! 	tree lhs_etype = lhs_type;
! 	tree rhs1_etype = rhs1_type;
! 	tree rhs2_etype = rhs2_type;
! 	if (TREE_CODE (lhs_type) == VECTOR_TYPE)
  	  {
  	    if (TREE_CODE (rhs1_type) != VECTOR_TYPE
  		|| TREE_CODE (rhs2_type) != VECTOR_TYPE)
*************** verify_gimple_assign_binary (gimple stmt
*** 3583,3604 ****
  		error ("invalid non-vector operands to vector valued plus");
  		return true;
  	      }
! 	    lhs_type = TREE_TYPE (lhs_type);
! 	    rhs1_type = TREE_TYPE (rhs1_type);
! 	    rhs2_type = TREE_TYPE (rhs2_type);
! 	    /* PLUS_EXPR is commutative, so we might end up canonicalizing
! 	       the pointer to 2nd place.  */
! 	    if (POINTER_TYPE_P (rhs2_type))
! 	      {
! 		tree tem = rhs1_type;
! 		rhs1_type = rhs2_type;
! 		rhs2_type = tem;
! 	      }
! 	    goto do_pointer_plus_expr_check;
  	  }
! 	if (POINTER_TYPE_P (lhs_type)
! 	    || POINTER_TYPE_P (rhs1_type)
! 	    || POINTER_TYPE_P (rhs2_type))
  	  {
  	    error ("invalid (pointer) operands to plus/minus");
  	    return true;
--- 3582,3594 ----
  		error ("invalid non-vector operands to vector valued plus");
  		return true;
  	      }
! 	    lhs_etype = TREE_TYPE (lhs_type);
! 	    rhs1_etype = TREE_TYPE (rhs1_type);
! 	    rhs2_etype = TREE_TYPE (rhs2_type);
  	  }
! 	if (POINTER_TYPE_P (lhs_etype)
! 	    || POINTER_TYPE_P (rhs1_etype)
! 	    || POINTER_TYPE_P (rhs2_etype))
  	  {
  	    error ("invalid (pointer) operands to plus/minus");
  	    return true;
*************** verify_gimple_assign_binary (gimple stmt
*** 3610,3616 ****
  
      case POINTER_PLUS_EXPR:
        {
- do_pointer_plus_expr_check:
  	if (!POINTER_TYPE_P (rhs1_type)
  	    || !useless_type_conversion_p (lhs_type, rhs1_type)
  	    || !ptrofftype_p (rhs2_type))
--- 3600,3605 ----



More information about the Gcc-patches mailing list