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