Hi,
I got this simple example to vectorize. Somehow, GCC (4.8) generates loop 
version because
it cannot determine alias between acc[i] write and x[i].real read. It is pretty 
obvious to me that they are not aliased based on TBAA information.

typedef struct
{
   short real;
   short imag;
} complex16_t;

void
libvector_AccSquareNorm_ref (unsigned long long  *acc,
                             const complex16_t *x, unsigned len)
{
    for (unsigned i = 0; i < len; i++)
    {
        acc[i] +=
            ((unsigned long long)((int)x[i].real * x[i].real)) +
            ((unsigned long long)((int)x[i].imag * x[i].imag));
    }
}

Tracing into how the alias information is calculated, I found it hits the 
following code
by calling ptr_derefs_may_alias_p and return true. ptr_derefs_may_alias_p 
doesn't contain
TBAA disambiguation code. Should we add check before that? 

  /* If we had an evolution in a MEM_REF BASE_OBJECT we do not know
     the size of the base-object.  So we cannot do any offset/overlap
     based analysis but have to rely on points-to information only.  */
  if (TREE_CODE (addr_a) == MEM_REF
      && DR_UNCONSTRAINED_BASE (a))
    {
      if (TREE_CODE (addr_b) == MEM_REF
          && DR_UNCONSTRAINED_BASE (b))
        return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0),
                                       TREE_OPERAND (addr_b, 0));
      else
        return ptr_derefs_may_alias_p (TREE_OPERAND (addr_a, 0),
                                       build_fold_addr_expr (addr_b));
    }
  else if (TREE_CODE (addr_b) == MEM_REF
           && DR_UNCONSTRAINED_BASE (b))
    return ptr_derefs_may_alias_p (build_fold_addr_expr (addr_a),
                                   TREE_OPERAND (addr_b, 0));

  /* Otherwise DR_BASE_OBJECT is an access that covers the whole object
     that is being subsetted in the loop nest.  */
  if (DR_IS_WRITE (a) && DR_IS_WRITE (b))
    return refs_output_dependent_p (addr_a, addr_b);
  else if (DR_IS_READ (a) && DR_IS_WRITE (b))
    return refs_anti_dependent_p (addr_a, addr_b);
  return refs_may_alias_p (addr_a, addr_b);

This issue can be reproduced on trunk x86-64 gcc. 

Cheers,
Bingfeng Mei

Reply via email to