This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
No TBAA before ptr_derefs_may_alias_p?
- From: Bingfeng Mei <bmei at broadcom dot com>
- To: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, Richard Biener <rguenther at suse dot de>
- Date: Fri, 31 Jan 2014 15:02:44 +0000
- Subject: No TBAA before ptr_derefs_may_alias_p?
- Authentication-results: sourceware.org; auth=none
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