This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RE: No TBAA before ptr_derefs_may_alias_p?
- From: Bingfeng Mei <bmei at broadcom dot com>
- To: Richard Biener <rguenther at suse dot de>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>
- Date: Fri, 31 Jan 2014 15:26:56 +0000
- Subject: RE: No TBAA before ptr_derefs_may_alias_p?
- Authentication-results: sourceware.org; auth=none
- References: <B71DF1153024A14EABB94E39368E44A604269C31 at SJEXCHMB13 dot corp dot ad dot broadcom dot com> <52EBC010 dot 5030409 at suse dot de>
Thanks, Richard,
I will prepare a patch with test as well as filing a bug.
Bingfeng
-----Original Message-----
From: Richard Biener [mailto:rguenther@suse.de]
Sent: 31 January 2014 15:24
To: Bingfeng Mei; gcc@gcc.gnu.org
Subject: Re: No TBAA before ptr_derefs_may_alias_p?
On 1/31/14 4:02 PM, Bingfeng Mei wrote:
> 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.
True, you can add a
if (flag_strict_aliasing
&& DR_IS_WRITE (a) && DR_IS_READ (b)
&& !alias_sets_conflict_p (get_alias_set (DR_REF (a)), get_alias_set
(DR_REF (b)))
return false;
before the ptr_derefs_may_alias_p calls. TBAA is only valid for
true dependences.
Richard.
> Cheers,
> Bingfeng Mei
>