This is the mail archive of the gcc@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]

Semi-Latent Bug in tree vectorizer


There's a rather annoying bug in the vectorizer which can cause us to
have SSA_NAMEs which are used, but never defined.

Consider this testcase compiled with -msse2 -ftree-vectorize:

typedef char achar __attribute__ ((__aligned__(16)));
int main1 ()
{
  struct {
    achar *p;
    achar *q;
  } s;
  int i;
  achar x[16];
  achar cb[16];
  s.p = x;
  i = 0;
  do
    {
      s.p[i] = cb[i];
      i++;
    } while (i < 16);

  if (s.p[0])
    abort ();
}

In the interest of brevity, I'm just going to point out the
problematical store from the .ifcvt dump:


  #   x_16 = V_MAY_DEF <x_21>;
  #   SFT.3_20 = V_MAY_DEF <SFT.3_15>;
  *D.1470_8 = D.1472_11;

Which gets vectorized and appears like this in the .vect dump:



  #   x_16 = V_MAY_DEF <x_21>;
  #   SFT.3_20 = V_MAY_DEF <SFT.3_15>;
  *vect_px.17_36 = vect_var_.10_29;

Which looks perfectly fine.  Unfortunately, there is a huge problem. 
If the operands for that statement are rebuilt, then we are going to
lose the assignment to SFT.3_20.


When we vectorize the store we copy the virtual operands from the
original statement to the new vectorized statement via this code:

  /* Copy the V_MAY_DEFS representing the aliasing of the original array
     element's definition to the vector's definition then update the
     defining statement.  The original is being deleted so the same
     SSA_NAMEs can be used.  */
  copy_virtual_operands (*vec_stmt, stmt);
  v_may_defs = STMT_V_MAY_DEF_OPS (*vec_stmt);
  nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);

  for (i = 0; i < nv_may_defs; i++)
    {
      tree ssa_name = V_MAY_DEF_RESULT (v_may_defs, i);
      SSA_NAME_DEF_STMT (ssa_name) = *vec_stmt;
    }

This is safe if and only if the the operand scanning code will compute
the same V_MAY_DEFS for the original scalar statement and the new
vectorized statement.  ie, *D.1470 must have the same aliasing
properties as *vect_px.17.

This works in the mainline because nothing ever causes a rescan of
the statement's operands.  However, with some pending changes I've got
to the jump threader, IVopts will later want to change *vect_px.17_36
in the vectorized statement, which causes a rescan of the operands.

When we rescan the operands, we get a different set of V_MAY_DEFS,
specifically we lose the V_MAY_DEF for SFT.3_20.  Which results in
uses of SFT.3_20 later, but SFT.3_20 is never defined.

You can see this behavior in the mainline with the attached trivial
change which forces a rescan of the operands after we change the
store statement.  This will cause an IL checking failure after 
vectorizing as we'll have SSA_NAMEs which are used, but never defined.

It seems to me the vectorizer needs to ensure that the aliasing
properties are the same so that if the statement is later rescanned
for some reason we don't suddenly use definition sites for SSA_NAMES.
I'm not at all familiar with this code, so I don't know the best way
to try and fix it.

It would probably be wise to audit the other uses of 
copy_virtual_operands.  We might also consider forcing statement
rescans as part of our IL checking code to avoid these kinds of
problems in the future.

Jeff









Index: tree-vect-transform.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-vect-transform.c,v
retrieving revision 2.9
diff -c -p -r2.9 tree-vect-transform.c
*** tree-vect-transform.c	29 Mar 2005 17:45:39 -0000	2.9
--- tree-vect-transform.c	8 Apr 2005 16:44:49 -0000
*************** vectorizable_store (tree stmt, block_stm
*** 910,915 ****
--- 910,916 ----
       defining statement.  The original is being deleted so the same
       SSA_NAMEs can be used.  */
    copy_virtual_operands (*vec_stmt, stmt);
+   update_stmt (*vec_stmt);
    v_may_defs = STMT_V_MAY_DEF_OPS (*vec_stmt);
    nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
  	    

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